/*
 * Copyright 2018 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm/gm.h"
#include "include/codec/SkEncodedOrigin.h"
#include "include/core/SkBlurTypes.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkImage.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "src/codec/SkCodecImageGenerator.h"
#include "tools/DecodeUtils.h"
#include "tools/EncodeUtils.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"

static constexpr int kImgW = 100;
static constexpr int kImgH =  80;

/**
  This function was used to create the images used by these test. It saves them as PNGs (so they
  are lossless). Then the following bash script was used to create the oriented JPGs with
  imagemagick and exiftool:
#!/bin/bash

for s in 444 422 420 440 411 410; do
  for i in {1..8}; do
    magick convert $i.png -sampling-factor ${s:0:1}:${s:1:1}:${s:2:1} $i\_$s.jpg;
    exiftool -orientation=$i -n -m -overwrite_original $i\_$s.jpg;
  done
done

 */
static void make_images() {
    for (int i = 1; i <= 8; ++i) {
        SkISize size{kImgW, kImgH};
        SkEncodedOrigin origin = static_cast<SkEncodedOrigin>(i);
        // We apply the inverse transformation to the PNG we generate, convert the PNG to a
        // a JPEG using magick, then modify the JPEG's tag using exiftool (without modifying the
        // stored JPEG data).
        if (origin >= kLeftTop_SkEncodedOrigin) {
            // The last four SkEncodedOrigin values involve 90 degree rotations
            using std::swap;
            swap(size.fWidth, size.fHeight);
        }
        using std::swap;
        auto surf = SkSurfaces::Raster(
                SkImageInfo::Make(size, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
        auto* canvas = surf->getCanvas();
        SkMatrix m = SkEncodedOriginToMatrixInverse(origin, kImgW, kImgH);
        canvas->concat(m);
        canvas->clear(SK_ColorBLACK);
        SkPaint paint;
        paint.setColor(SK_ColorRED);
        SkScalar midX = kImgW / 2.f;
        SkScalar midY = kImgH / 2.f;
        SkScalar w = midX - 1;
        SkScalar h = midY - 1;
        canvas->drawRect(SkRect::MakeXYWH(1, 1, w, h), paint);
        paint.setColor(SK_ColorBLUE);
        canvas->drawRect(SkRect::MakeXYWH(midX, 1, w, h), paint);
        paint.setColor(SK_ColorGREEN);
        canvas->drawRect(SkRect::MakeXYWH(1, midY, w, h), paint);
        paint.setColor(SK_ColorYELLOW);
        canvas->drawRect(SkRect::MakeXYWH(midX, midY, w, h), paint);
        SkFont font(ToolUtils::DefaultPortableTypeface(), kImgH / 4.f);

        SkPaint blurPaint;
        blurPaint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, .75f));
        blurPaint.setColor(SK_ColorBLACK);
        paint.setColor(SK_ColorWHITE);

        auto drawLabel = [&](const char* string, SkScalar x, SkScalar y) {
            canvas->save();
            canvas->translate(1, 1);
            canvas->drawString(string, x, y, font, blurPaint);
            canvas->restore();
            canvas->drawString(string, x, y, font, paint);
        };

        auto measure = [&font](const char* text) {
            SkRect bounds;
            font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
            return bounds;
        };

        static constexpr SkScalar kPad = 3.f;
        SkRect bounds;

        bounds = measure("top");
        drawLabel("top", midX - bounds.centerX(), -bounds.top() + kPad);

        bounds = measure("bottom");
        drawLabel("bottom", midX - bounds.centerX(), kImgH - kPad - bounds.bottom());

        // It looks weird if "left" and "right" and the number at the center aren't vertically
        // aligned.
        SkScalar baseY = midY - measure("leftright").centerY();
        bounds = measure("left");
        drawLabel("left", kPad - bounds.left(), baseY);

        bounds = measure("right");
        drawLabel("right", kImgW - kPad - bounds.right(), baseY);

        SkString num = SkStringPrintf("%d", i);
        bounds = measure(num.c_str());
        drawLabel(num.c_str(), midX - bounds.centerX(), baseY);
        num.append(".png");
        SkPixmap pm;
        surf->makeImageSnapshot()->peekPixels(&pm);
        ToolUtils::EncodeImageToPngFile(num.c_str(), pm);
    }
}

// This gm draws 8 images that are mostly the same when respecting the
// EXIF orientation tag. Each one has four quadrants (red, blue, green,
// yellow), and labels on the left, top, right and bottom. The only
// visual difference is a number in the middle corresponding to the
// EXIF tag for that image's jpg file.
static void draw(SkCanvas* canvas, const char* suffix) {
    // Avoid unused function warning.
    if ((false)) {
        make_images();
    }
    canvas->save();
    for (char i = '1'; i <= '8'; i++) {
        SkString path = SkStringPrintf("images/orientation/%c%s.jpg", i, suffix);
        auto image = ToolUtils::GetResourceAsImage(path.c_str());
        if (!image) {
            continue;
        }
        canvas->drawImage(image, 0, 0);
        if ('4' == i) {
            canvas->restore();
            canvas->translate(0, image->height());
        } else {
            canvas->translate(image->width(), 0);
        }
    }
}

#define MAKE_GM(subsample) DEF_SIMPLE_GM(orientation_##subsample, canvas, 4*kImgW, 2*kImgH) { \
        draw(canvas, "_" #subsample);                                                         \
}

MAKE_GM(410)
MAKE_GM(411)
MAKE_GM(420)
MAKE_GM(422)
MAKE_GM(440)
MAKE_GM(444)

// This GM demonstrates that the default SkImageGenerator respects the orientation flag.
DEF_SIMPLE_GM(respect_orientation_jpeg, canvas, 4*kImgW, 2*kImgH) {
   canvas->save();
    for (char i = '1'; i <= '8'; i++) {
        SkString path = SkStringPrintf("images/orientation/%c_444.jpg", i);
        // Get the image as data
        sk_sp<SkData> data(GetResourceAsData(path.c_str()));
        sk_sp<SkImage> image = SkImages::DeferredFromGenerator(
            SkCodecImageGenerator::MakeFromEncodedCodec(data));
        if (!image) {
            continue;
        }
        canvas->drawImage(image, 0, 0);
        if ('4' == i || '8' == i) {
            canvas->restore();
            canvas->translate(0, image->height());
        } else {
            canvas->translate(image->width(), 0);
        }
    }
}
