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

#include "gm.h"

#include "SkColorSpace.h"
#include "SkColorSpaceXformSteps.h"
#include "SkDashPathEffect.h"
#include "SkFont.h"
#include "SkGradientShader.h"
#include "SkString.h"

static bool nearly_equal(SkColor4f x, SkColor4f y) {
    const float K = 0.01f;
    return fabsf(x.fR - y.fR) < K
        && fabsf(x.fG - y.fG) < K
        && fabsf(x.fB - y.fB) < K
        && fabsf(x.fA - y.fA) < K;
}

static SkString fmt(SkColor4f c) {
    return SkStringPrintf("%.2g %.2g %.2g %.2g", c.fR, c.fG, c.fB, c.fA);
}

static SkColor4f transform(SkColor4f c, SkColorSpace* src, SkColorSpace* dst) {
    SkColorSpaceXformSteps(src, kUnpremul_SkAlphaType,
                           dst, kUnpremul_SkAlphaType).apply(c.vec());
    return c;
}

static void compare_pixel(const char* label,
                          SkCanvas* canvas, int x, int y,
                          SkColor4f color, SkColorSpace* cs) {
    SkPaint paint;
    SkFont font;
    auto canvas_cs = canvas->imageInfo().refColorSpace();

    // I'm not really sure if this makes things easier or harder to follow,
    // but we sniff the canvas to grab its current y-translate, so that (x,y)
    // can be written in sort of chunk-relative terms.
    const SkMatrix& m = canvas->getTotalMatrix();
    SkASSERT(m.isTranslate());
    SkScalar dy = m.getTranslateY();
    SkASSERT(dy == (int)dy);
    y += (int)dy;

    SkBitmap bm;
    bm.allocPixels(SkImageInfo::Make(1,1, kRGBA_F32_SkColorType, kUnpremul_SkAlphaType, canvas_cs));
    if (!canvas->readPixels(bm, x,y)) {
        MarkGMGood(canvas, 140,40);
        canvas->drawString("can't readPixels() on this canvas :(", 100,20, font, paint);
        return;
    }

    SkColor4f pixel;
    memcpy(&pixel, bm.getAddr(0,0), sizeof(pixel));

    SkColor4f expected = transform(color,cs, canvas_cs.get());
    if (canvas->imageInfo().colorType() < kRGBA_F16_SkColorType) {
        // We can't expect normalized formats to hold values outside [0,1].
        for (int i = 0; i < 4; ++i) {
            expected[i] = SkTPin(expected[i], 0.0f, 1.0f);
        }
    }
    if (canvas->imageInfo().colorType() == kGray_8_SkColorType) {
        // Drawing into Gray8 is known to be maybe-totally broken.
        // TODO: update expectation here to be {lum,lum,lum,1} if we fix Gray8.
        expected = SkColor4f{NAN, NAN, NAN, 1};
    }

    if (nearly_equal(pixel, expected)) {
        MarkGMGood(canvas, 140,40);
    } else {
        MarkGMBad(canvas, 140,40);
    }

    struct {
        const char* label;
        SkColor4f   color;
    } lines[] = {
        {"Pixel:"   , pixel   },
        {"Expected:", expected},
    };

    SkAutoCanvasRestore saveRestore(canvas, true);
    canvas->drawString(label, 80,20, font, paint);
    for (auto l : lines) {
        canvas->translate(0,20);
        canvas->drawString(l.label,               80,20, font, paint);
        canvas->drawString(fmt(l.color).c_str(), 140,20, font, paint);
    }
}

DEF_SIMPLE_GM(p3, canvas, 450, 1300) {
    auto p3 = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);
    auto srgb = SkColorSpace::MakeSRGB();

    auto p3_to_srgb = [&](SkColor4f c) {
        SkPaint p;
        p.setColor4f(c, p3.get());
        return p.getColor4f();
    };

    // Draw a P3 red rectangle and check the corner.
    {
        SkPaint paint;
        paint.setColor4f({1,0,0,1}, p3.get());

        canvas->drawRect({10,10,70,70}, paint);
        compare_pixel("drawRect P3 red ",
                      canvas, 10,10,
                      {1,0,0,1}, p3.get());
    }

    canvas->translate(0,80);

    // Draw a P3 red bitmap, using a draw.
    {
        SkBitmap bm;
        bm.allocPixels(SkImageInfo::Make(60,60, kRGBA_F16_SkColorType, kPremul_SkAlphaType, p3));

        SkPaint paint;
        paint.setColor4f({1,0,0,1}, p3.get());
        SkCanvas{bm}.drawPaint(paint);

        canvas->drawBitmap(bm, 10,10);
        compare_pixel("drawBitmap P3 red, from drawPaint",
                      canvas, 10,10,
                      {1,0,0,1}, p3.get());
    }

    canvas->translate(0,80);

    // Draw a P3 red bitmap, using SkBitmap::eraseColor().
    {
        SkBitmap bm;
        bm.allocPixels(SkImageInfo::Make(60,60, kRGBA_F16_SkColorType, kPremul_SkAlphaType, p3));

        bm.eraseColor(0xffff0000/*in P3*/);

        canvas->drawBitmap(bm, 10,10);
        compare_pixel("drawBitmap P3 red, from SkBitmap::eraseColor()",
                      canvas, 10,10,
                      {1,0,0,1}, p3.get());
    }

    canvas->translate(0,80);

    // Draw a P3 red bitmap, using SkPixmap::erase().
    {
        SkBitmap bm;
        bm.allocPixels(SkImageInfo::Make(60,60, kRGBA_F16_SkColorType, kPremul_SkAlphaType, p3));

        // At the moment only SkPixmap has an erase() that takes an SkColor4f.
        SkPixmap pm;
        SkAssertResult(bm.peekPixels(&pm));
        SkAssertResult(pm.erase({1,0,0,1} /*in p3*/));

        canvas->drawBitmap(bm, 10,10);
        compare_pixel("drawBitmap P3 red, from SkPixmap::erase",
                      canvas, 10,10,
                      {1,0,0,1}, p3.get());
    }

    canvas->translate(0,80);

    // Draw a P3 red bitmap wrapped in a shader, using SkPixmap::erase().
    {
        SkBitmap bm;
        bm.allocPixels(SkImageInfo::Make(60,60, kRGBA_F16_SkColorType, kPremul_SkAlphaType, p3));

        // At the moment only SkPixmap has an erase() that takes an SkColor4f.
        SkPixmap pm;
        SkAssertResult(bm.peekPixels(&pm));
        SkAssertResult(pm.erase({1,0,0,1} /*in p3*/));

        SkPaint paint;
        paint.setShader(SkShader::MakeBitmapShader(bm, SkShader::kRepeat_TileMode,
                                                   SkShader::kRepeat_TileMode));

        canvas->drawRect({10,10,70,70}, paint);
        compare_pixel("drawBitmapAsShader P3 red, from SkPixmap::erase",
                      canvas, 10,10,
                      {1,0,0,1}, p3.get());
    }

    canvas->translate(0,80);

    // Draw a gradient from P3 red to P3 green interpolating in unpremul P3, checking the corners.
    {

        SkPoint points[] = {{10.5,10.5}, {69.5,69.5}};
        SkColor4f colors[] = {{1,0,0,1}, {0,1,0,1}};

        SkPaint paint;
        paint.setShader(SkGradientShader::MakeLinear(points, colors, p3,
                                                     nullptr, SK_ARRAY_COUNT(colors),
                                                     SkShader::kClamp_TileMode));
        canvas->drawRect({10,10,70,70}, paint);
        canvas->save();
            compare_pixel("UPM P3 gradient, P3 red",
                          canvas, 10,10,
                          {1,0,0,1}, p3.get());

            canvas->translate(180, 0);

            compare_pixel("UPM P3 gradient, P3 green",
                          canvas, 69,69,
                          {0,1,0,1}, p3.get());
        canvas->restore();
    }

    canvas->translate(0,80);

    // Draw a gradient from P3 red to P3 green interpolating in premul P3, checking the corners.
    {

        SkPoint points[] = {{10.5,10.5}, {69.5,69.5}};
        SkColor4f colors[] = {{1,0,0,1}, {0,1,0,1}};

        SkPaint paint;
        paint.setShader(
                SkGradientShader::MakeLinear(points, colors, p3,
                                             nullptr, SK_ARRAY_COUNT(colors),
                                             SkShader::kClamp_TileMode,
                                             SkGradientShader::kInterpolateColorsInPremul_Flag,
                                             nullptr/*local matrix*/));
        canvas->drawRect({10,10,70,70}, paint);
        canvas->save();
            compare_pixel("PM P3 gradient, P3 red",
                          canvas, 10,10,
                          {1,0,0,1}, p3.get());

            canvas->translate(180, 0);

            compare_pixel("PM P3 gradient, P3 green",
                          canvas, 69,69,
                          {0,1,0,1}, p3.get());
        canvas->restore();
    }

    canvas->translate(0,80);

    // Draw a gradient from P3 red to P3 green interpolating in unpremul sRGB, checking the corners.
    {

        SkPoint points[] = {{10.5,10.5}, {69.5,69.5}};
        SkColor4f colors[] = {p3_to_srgb({1,0,0,1}), p3_to_srgb({0,1,0,1})};

        SkPaint paint;
        paint.setShader(SkGradientShader::MakeLinear(points, colors, srgb,
                                                     nullptr, SK_ARRAY_COUNT(colors),
                                                     SkShader::kClamp_TileMode));
        canvas->drawRect({10,10,70,70}, paint);
        canvas->save();
            compare_pixel("UPM sRGB gradient, P3 red",
                          canvas, 10,10,
                          {1,0,0,1}, p3.get());

            canvas->translate(180, 0);

            compare_pixel("UPM sRGB gradient, P3 green",
                          canvas, 69,69,
                          {0,1,0,1}, p3.get());
        canvas->restore();
    }

    canvas->translate(0,80);

    // Draw a gradient from P3 red to P3 green interpolating in premul sRGB, checking the corners.
    {

        SkPoint points[] = {{10.5,10.5}, {69.5,69.5}};
        SkColor4f colors[] = {p3_to_srgb({1,0,0,1}), p3_to_srgb({0,1,0,1})};

        SkPaint paint;
        paint.setShader(
                SkGradientShader::MakeLinear(points, colors, srgb,
                                             nullptr, SK_ARRAY_COUNT(colors),
                                             SkShader::kClamp_TileMode,
                                             SkGradientShader::kInterpolateColorsInPremul_Flag,
                                             nullptr/*local matrix*/));
        canvas->drawRect({10,10,70,70}, paint);
        canvas->save();
            compare_pixel("PM P3 gradient, P3 red",
                          canvas, 10,10,
                          {1,0,0,1}, p3.get());

            canvas->translate(180, 0);

            compare_pixel("PM P3 gradient, P3 green",
                          canvas, 69,69,
                          {0,1,0,1}, p3.get());
        canvas->restore();
    }

    canvas->translate(0,80);

    // Leon's blue -> green -> red gradient, interpolating in premul.
    {
        SkPoint points[] = {{10.5,10.5}, {10.5,69.5}};
        SkColor4f colors[] = { {0,0,1,1}, {0,1,0,1}, {1,0,0,1} };

        SkPaint paint;
        paint.setShader(
                SkGradientShader::MakeLinear(points, colors, p3,
                                             nullptr, SK_ARRAY_COUNT(colors),
                                             SkShader::kClamp_TileMode,
                                             SkGradientShader::kInterpolateColorsInPremul_Flag,
                                             nullptr/*local matrix*/));
        canvas->drawRect({10,10,70,70}, paint);
        canvas->save();
            compare_pixel("Leon's gradient, P3 blue",
                          canvas, 10,10,
                          {0,0,1,1}, p3.get());

            canvas->translate(180, 0);

            compare_pixel("Leon's gradient, P3 red",
                          canvas, 10,69,
                          {1,0,0,1}, p3.get());
        canvas->restore();
    }

    canvas->translate(0,80);

    // Draw an A8 image with a P3 red, scaled and not, as a shader or bitmap.
    {
        uint8_t mask[256];
        for (int i = 0; i < 256; i++) {
            mask[i] = 255-i;
        }
        SkBitmap bm;
        bm.installPixels(SkImageInfo::MakeA8(16,16), mask, 16);

        SkPaint as_bitmap;
        as_bitmap.setColor4f({1,0,0,1}, p3.get());
        as_bitmap.setFilterQuality(kLow_SkFilterQuality);

        SkPaint as_shader;
        as_shader.setColor4f({1,0,0,1}, p3.get());
        as_shader.setFilterQuality(kLow_SkFilterQuality);
        as_shader.setShader(SkShader::MakeBitmapShader(bm, SkShader::kClamp_TileMode
                                                         , SkShader::kClamp_TileMode));

        canvas->drawBitmap(bm, 10,10, &as_bitmap);
        compare_pixel("A8 sprite bitmap P3 red",
                      canvas, 10,10,
                      {1,0,0,1}, p3.get());

        canvas->translate(0, 80);

        canvas->save();
            canvas->translate(10,10);
            canvas->drawRect({0,0,16,16}, as_shader);
        canvas->restore();
        compare_pixel("A8 sprite shader P3 red",
                      canvas, 10,10,
                      {1,0,0,1}, p3.get());

        canvas->translate(0,80);

        canvas->drawBitmapRect(bm, {10,10,70,70}, &as_bitmap);
        compare_pixel("A8 scaled bitmap P3 red",
                      canvas, 10,10,
                      {1,0,0,1}, p3.get());

        canvas->translate(0,80);

        canvas->save();
            canvas->translate(10,10);
            canvas->scale(3.75,3.75);
            canvas->drawRect({0,0,16,16}, as_shader);
        canvas->restore();
        compare_pixel("A8 scaled shader P3 red",
                      canvas, 10,10,
                      {1,0,0,1}, p3.get());
    }

    // TODO: draw P3 colors more ways
}

DEF_SIMPLE_GM(p3_ovals, canvas, 450, 320) {
    auto p3 = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);

    // Test cases that exercise each Op in GrOvalOpFactory.cpp

    // Draw a circle and check the center (CircleOp)
    {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setColor4f({ 1,0,0,1 }, p3.get());

        canvas->drawCircle(40, 40, 30, paint);
        compare_pixel("drawCircle P3 red ",
                      canvas, 40, 40,
                      { 1,0,0,1 }, p3.get());
    }

    canvas->translate(0, 80);

    // Draw an oval and check the center (EllipseOp)
    {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setColor4f({ 1,0,0,1 }, p3.get());

        canvas->drawOval({ 20,10,60,70 }, paint);
        compare_pixel("drawOval P3 red ",
                      canvas, 40, 40,
                      { 1,0,0,1 }, p3.get());
    }

    canvas->translate(0, 80);

    // Draw a butt-capped dashed circle and check the top of the stroke (ButtCappedDashedCircleOp)
    {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setColor4f({ 1,0,0,1 }, p3.get());
        paint.setStyle(SkPaint::kStroke_Style);
        float intervals[] = { 70, 10 };
        paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
        paint.setStrokeWidth(10);

        canvas->drawCircle(40, 40, 30, paint);
        compare_pixel("drawDashedCircle P3 red ",
                      canvas, 40, 10,
                      { 1,0,0,1 }, p3.get());
    }

    canvas->translate(0, 80);

    // Draw an oval with rotation and check the center (DIEllipseOp)
    {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setColor4f({ 1,0,0,1 }, p3.get());

        canvas->save();
            canvas->translate(40, 40);
            canvas->rotate(45);
            canvas->drawOval({ -20,-30,20,30 }, paint);
        canvas->restore();
        compare_pixel("drawRotatedOval P3 red ",
                      canvas, 40, 40,
                      { 1,0,0,1 }, p3.get());
    }

    canvas->translate(0, 80);
}
