/*
 * Copyright 2011 Google Inc.
 *
 * 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/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"
#include "include/effects/SkImageFilters.h"
#include "tools/ToolUtils.h"

#include <utility>

static sk_sp<SkImage> make_src(int w, int h) {
    sk_sp<SkSurface> surface(SkSurfaces::Raster(SkImageInfo::MakeN32Premul(w, h)));
    SkCanvas* canvas = surface->getCanvas();

    SkPaint paint;
    SkPoint pts[] = { {0, 0}, {SkIntToScalar(w), SkIntToScalar(h)} };
    SkColor colors[] = {
        SK_ColorTRANSPARENT, SK_ColorGREEN, SK_ColorCYAN,
        SK_ColorRED, SK_ColorMAGENTA, SK_ColorWHITE,
    };
    paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, std::size(colors),
                                                 SkTileMode::kClamp));
    canvas->drawPaint(paint);
    return surface->makeImageSnapshot();
}

static sk_sp<SkImage> make_dst(int w, int h) {
    sk_sp<SkSurface> surface(SkSurfaces::Raster(SkImageInfo::MakeN32Premul(w, h)));
    SkCanvas* canvas = surface->getCanvas();

    SkPaint paint;
    SkPoint pts[] = { {0, SkIntToScalar(h)}, {SkIntToScalar(w), 0} };
    SkColor colors[] = {
        SK_ColorBLUE, SK_ColorYELLOW, SK_ColorBLACK, SK_ColorGREEN,
        SK_ColorGRAY,
    };
    paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, std::size(colors),
                                                 SkTileMode::kClamp));
    canvas->drawPaint(paint);
    return surface->makeImageSnapshot();
}

static void show_k_text(SkCanvas* canvas, SkScalar x, SkScalar y, const SkScalar k[]) {
    SkFont font(ToolUtils::create_portable_typeface(), 24);
    font.setEdging(SkFont::Edging::kAntiAlias);
    SkPaint paint;
    paint.setAntiAlias(true);
    for (int i = 0; i < 4; ++i) {
        SkString str;
        str.appendScalar(k[i]);
        SkScalar width = font.measureText(str.c_str(), str.size(), SkTextEncoding::kUTF8);
        canvas->drawString(str, x, y + font.getSize(), font, paint);
        x += width + SkIntToScalar(10);
    }
}

class ArithmodeGM : public skiagm::GM {
    SkString onShortName() override { return SkString("arithmode"); }

    SkISize onISize() override { return {640, 572}; }

    void onDraw(SkCanvas* canvas) override {
        constexpr int WW = 100,
                      HH = 32;

        sk_sp<SkImage> src = make_src(WW, HH);
        sk_sp<SkImage> dst = make_dst(WW, HH);
        sk_sp<SkImageFilter> srcFilter = SkImageFilters::Image(src, {SkFilterMode::kLinear});
        sk_sp<SkImageFilter> dstFilter = SkImageFilters::Image(dst, {SkFilterMode::kLinear});

        constexpr SkScalar one = SK_Scalar1;
        constexpr SkScalar K[] = {
            0, 0, 0, 0,
            0, 0, 0, one,
            0, one, 0, 0,
            0, 0, one, 0,
            0, one, one, 0,
            0, one, -one, 0,
            0, one/2, one/2, 0,
            0, one/2, one/2, one/4,
            0, one/2, one/2, -one/4,
            one/4, one/2, one/2, 0,
            -one/4, one/2, one/2, 0,
        };

        const SkScalar* k = K;
        const SkScalar* stop = k + std::size(K);
        // Many of the Arithmetic filters have a 4th coefficient that's not zero, which means they
        // affect transparent black. 'rect' is used as a crop filter to make sure they don't
        // overwrite each other.
        const SkRect rect = SkRect::MakeWH(WW, HH);
        SkScalar gap = SkIntToScalar(WW + 20);
        while (k < stop) {
            {
                SkAutoCanvasRestore acr(canvas, true);
                canvas->drawImage(src, 0, 0);
                canvas->translate(gap, 0);
                canvas->drawImage(dst, 0, 0);
                canvas->translate(gap, 0);
                SkPaint paint;
                paint.setImageFilter(SkImageFilters::Arithmetic(k[0], k[1], k[2], k[3], true,
                                                                dstFilter, srcFilter, rect));
                canvas->saveLayer(nullptr, &paint);
                canvas->restore();

                canvas->translate(gap, 0);
                show_k_text(canvas, 0, 0, k);
            }

            k += 4;
            canvas->translate(0, HH + 12);
        }

        // Draw two special cases to test enforcePMColor. In these cases, we
        // draw the dst bitmap twice, the first time it is halved and inverted,
        // leading to invalid premultiplied colors. If we enforcePMColor, these
        // invalid values should be clamped, and will not contribute to the
        // second draw.
        for (int i = 0; i < 2; i++) {
            const bool enforcePMColor = (i == 0);

            {
                SkAutoCanvasRestore acr(canvas, true);
                canvas->translate(gap, 0);
                canvas->drawImage(dst, 0, 0);
                canvas->translate(gap, 0);

                sk_sp<SkImageFilter> bg =
                        SkImageFilters::Arithmetic(0, 0, -one / 2, 1, enforcePMColor, dstFilter,
                                                   nullptr, nullptr);
                SkPaint p;
                p.setImageFilter(SkImageFilters::Arithmetic(0, one / 2, -one, 1, true,
                                                            std::move(bg), dstFilter, rect));
                canvas->saveLayer(nullptr, &p);
                canvas->restore();
                canvas->translate(gap, 0);

                // Label
                SkFont   font(ToolUtils::create_portable_typeface(), 24);
                SkString str(enforcePMColor ? "enforcePM" : "no enforcePM");
                canvas->drawString(str, 0, font.getSize(), font, SkPaint());
            }
            canvas->translate(0, HH + 12);
        }
    }

private:
    using INHERITED = GM;
};
DEF_GM( return new ArithmodeGM; )

///////////////////////////////////////////////////////////////////////////////

#include "include/effects/SkBlenders.h"

class ArithmodeBlenderGM : public skiagm::GM {
    float                  fK1, fK2, fK3, fK4;
    sk_sp<SkImage>         fSrc, fDst, fChecker;
    sk_sp<SkShader>        fSrcShader, fDstShader;
    sk_sp<SkRuntimeEffect> fRuntimeEffect;

    SkString onShortName() override { return SkString("arithmode_blender"); }

    static constexpr int W = 200;
    static constexpr int H = 200;

    SkISize onISize() override { return {(W + 30) * 2, (H + 30) * 4}; }

    void onOnceBeforeDraw() override {
        // Prepare a runtime effect for this blend.
        static constexpr char kShader[] = R"(
            uniform shader srcImage;
            uniform shader dstImage;
            uniform blender arithBlend;
            half4 main(float2 xy) {
                return arithBlend.eval(srcImage.eval(xy), dstImage.eval(xy));
            }
        )";
        auto [effect, error] = SkRuntimeEffect::MakeForShader(SkString(kShader));
        SkASSERT(effect);
        fRuntimeEffect = effect;

        // Start with interesting K-values, in case we're drawn without calling onAnimate().
        fK1 = -0.25f;
        fK2 =  0.25f;
        fK3 =  0.25f;
        fK4 =  0;

        fSrc = make_src(W, H);
        fDst = make_dst(W, H);
        fSrcShader = fSrc->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, SkSamplingOptions());
        fDstShader = fDst->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, SkSamplingOptions());

        fChecker = ToolUtils::create_checkerboard_image(W, H, 0xFFBBBBBB, 0xFFEEEEEE, 8);
    }

    bool onAnimate(double nanos) override {
        double theta = nanos * 1e-6 * 0.001;
        fK1 = sin(theta + 0) * 0.25;
        fK2 = cos(theta + 1) * 0.25;
        fK3 = sin(theta + 2) * 0.25;
        fK4 = 0.5;
        return true;
    }

    void onDraw(SkCanvas* canvas) override {
        const SkRect rect = SkRect::MakeWH(W, H);

        canvas->drawImage(fSrc, 10, 10);
        canvas->drawImage(fDst, 10, 10 + H + 10);

        SkSamplingOptions sampling;
        sk_sp<SkBlender> blender = SkBlenders::Arithmetic(fK1, fK2, fK3, fK4,
                                                          /*enforcePremul=*/true);
        canvas->translate(10 + W + 10, 10);

        // All three images drawn below should appear identical.
        // Draw via blend step
        SkPaint blenderPaint;
        canvas->drawImage(fChecker, 0, 0);
        canvas->saveLayer(&rect, nullptr);
        canvas->drawImage(fDst, 0, 0);
        blenderPaint.setBlender(blender);
        canvas->drawImage(fSrc, 0, 0, sampling, &blenderPaint);
        canvas->restore();

        canvas->translate(0, 10 + H);

        // Draw via SkImageFilters::Blend (should appear the same as above)
        SkPaint imageFilterPaint;
        canvas->drawImage(fChecker, 0, 0);
        imageFilterPaint.setImageFilter(
                SkImageFilters::Blend(blender,
                                      /*background=*/nullptr,
                                      /*foreground=*/SkImageFilters::Image(fSrc, sampling)));
        canvas->drawImage(fDst, 0, 0, sampling, &imageFilterPaint);

        canvas->translate(0, 10 + H);

        // Draw via SkShaders::Blend (should still appear the same as above)
        SkPaint shaderBlendPaint;
        canvas->drawImage(fChecker, 0, 0);
        shaderBlendPaint.setShader(SkShaders::Blend(blender, fDstShader, fSrcShader));
        canvas->drawRect(rect, shaderBlendPaint);

        canvas->translate(0, 10 + H);

        // Draw via runtime effect (should still appear the same as above)
        SkPaint runtimePaint;
        canvas->drawImage(fChecker, 0, 0);
        SkRuntimeEffect::ChildPtr children[] = {fSrcShader, fDstShader, blender};
        runtimePaint.setShader(fRuntimeEffect->makeShader(/*uniforms=*/{}, children));
        canvas->drawRect(rect, runtimePaint);
    }

private:
    using INHERITED = GM;
};
DEF_GM( return new ArithmodeBlenderGM; )
