/*
 * 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/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradient.h"
#include "tools/DecodeUtils.h"
#include "tools/GpuToolUtils.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
#include "tools/timer/TimeUtils.h"

static sk_sp<SkImage> make_image(SkCanvas* rootCanvas) {
    static constexpr SkScalar kSize = 50;
    SkImageInfo info = SkImageInfo::MakeN32Premul(kSize, kSize);
    auto surface(SkSurfaces::Raster(info));

    SkPaint p;
    p.setAntiAlias(true);
    p.setColor(SK_ColorGREEN);

    surface->getCanvas()->drawCircle(kSize / 2, kSize / 2, kSize / 2, p);

    p.setStyle(SkPaint::kStroke_Style);
    p.setColor(SK_ColorRED);
    surface->getCanvas()->drawLine(kSize * .25f, kSize * .50f, kSize * .75f, kSize * .50f, p);
    surface->getCanvas()->drawLine(kSize * .50f, kSize * .25f, kSize * .50f, kSize * .75f, p);

    sk_sp<SkImage> img = surface->makeImageSnapshot();
    return ToolUtils::MakeTextureImage(rootCanvas, std::move(img));
}

DEF_SIMPLE_GM(localmatrixshader_nested, canvas, 450, 1200) {
    auto image = make_image(canvas);
    if (!image) {
        return;
    }

    using FactoryT = sk_sp<SkShader> (*)(const sk_sp<SkImage>&,
                                         const SkMatrix& inner,
                                         const SkMatrix& outer);
    static const FactoryT gFactories[] = {
        // SkLocalMatrixShader(SkImageShader(inner), outer)
        [](const sk_sp<SkImage>& img, const SkMatrix& inner, const SkMatrix& outer) {
            return img->makeShader(SkSamplingOptions(), inner)->makeWithLocalMatrix(outer);
        },

        // SkLocalMatrixShader(SkLocalMatrixShader(SkImageShader(I), inner), outer)
        [](const sk_sp<SkImage>& img, const SkMatrix& inner, const SkMatrix& outer) {
            return img->makeShader(SkSamplingOptions())->makeWithLocalMatrix(inner)->makeWithLocalMatrix(outer);
        },

        // SkLocalMatrixShader(SkComposeShader(SkImageShader(inner)), outer)
        [](const sk_sp<SkImage>& img, const SkMatrix& inner, const SkMatrix& outer) {
            return SkShaders::Blend(SkBlendMode::kSrcOver,
                                    SkShaders::Color(SK_ColorTRANSPARENT),
                                    img->makeShader(SkSamplingOptions(), inner))
                   ->makeWithLocalMatrix(outer);
        },

        // SkLocalMatrixShader(SkComposeShader(SkLocalMatrixShader(SkImageShader(I), inner)), outer)
        [](const sk_sp<SkImage>& img, const SkMatrix& inner, const SkMatrix& outer) {
            return SkShaders::Blend(SkBlendMode::kSrcOver,
                                    SkShaders::Color(SK_ColorTRANSPARENT),
                                    img->makeShader(SkSamplingOptions())->makeWithLocalMatrix(inner))
                   ->makeWithLocalMatrix(outer);
        },
    };

    static const auto outer = SkMatrix::Scale(2, 2),
                      inner = SkMatrix::Translate(20, 20);

    SkPaint border;
    border.setAntiAlias(true);
    border.setStyle(SkPaint::kStroke_Style);

    auto rect = SkRect::Make(image->bounds());
    SkAssertResult(SkMatrix::Concat(outer, inner).mapRect(&rect));

    const auto drawColumn = [&]() {
        SkAutoCanvasRestore acr(canvas, true);
        for (const auto& f : gFactories) {
            SkPaint p;
            p.setShader(f(image, inner, outer));

            canvas->drawRect(rect, p);
            canvas->drawRect(rect, border);

            canvas->translate(0, rect.height() * 1.5f);
        }
    };

    drawColumn();

    {
        SkAutoCanvasRestore acr(canvas, true);
        canvas->translate(0, rect.height() * std::size(gFactories) * 1.5f);
        drawColumn();
    }

    canvas->translate(rect.width() * 1.5f, 0);
    canvas->scale(2, 2);
    drawColumn();
}

DEF_SIMPLE_GM(localmatrixshader_persp, canvas, 542, 266) {
    auto image = ToolUtils::GetResourceAsImage("images/yellow_rose.png");

    SkBitmap downsized;
    downsized.allocPixels(image->imageInfo().makeWH(128, 128));
    image->scalePixels(downsized.pixmap(), SkSamplingOptions(SkFilterMode::kLinear));
    image = downsized.asImage();
    SkRect imgRect = SkRect::MakeIWH(image->width(), image->height());

    // scale matrix
    SkMatrix scale = SkMatrix::Scale(1.f / 5.f, 1.f / 5.f);

    // perspective matrix
    const std::array<SkPoint, 4> src = imgRect.toQuad();
    SkPoint dst[4] = {{0, 10.f},
                      {image->width() + 28.f, -100.f},
                      {image->width() - 28.f, image->height() + 100.f},
                      {0.f, image->height() - 10.f}};
    SkMatrix persp;
    SkAssertResult(persp.setPolyToPoly(src, dst));

    // combined persp * scale
    SkMatrix perspScale = SkMatrix::Concat(persp, scale);

    auto draw = [&](sk_sp<SkShader> shader, bool applyPerspToCTM) {
        canvas->save();
        canvas->clipRect(imgRect);
        if (applyPerspToCTM) {
            canvas->concat(persp);
        }
        SkPaint imgShaderPaint;
        imgShaderPaint.setShader(std::move(shader));
        canvas->drawPaint(imgShaderPaint);
        canvas->restore();

        canvas->translate(10.f + image->width(), 0.f); // advance
    };

    // SkImageShader
    canvas->save();
    // 4 variants that all attempt to apply sample at persp * scale w/ an image shader
    // 1. scale provided to SkImage::makeShader(...) but drawn with persp
    auto s1 = image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                SkSamplingOptions(), &scale);
    draw(s1, true);

    // 2. scale provided to SkImage::makeShader, then wrapped in persp makeWithLocalMatrix
    // These post-concat, so it ends up as persp * scale.
    auto s2 = image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                SkSamplingOptions(), &scale)
                   ->makeWithLocalMatrix(persp);
    draw(s2, false);

    // 3. Providing pre-computed persp*scale to SkImage::makeShader()
    auto s3 = image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                SkSamplingOptions(), &perspScale);
    draw(s3, false);

    // 4. Providing pre-computed persp*scale to makeWithLocalMatrix
    auto s4 = image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, SkSamplingOptions())
                   ->makeWithLocalMatrix(perspScale);
    draw(s4, false);
    canvas->restore();

    canvas->translate(0.f, 10.f + image->height()); // advance to next row

    // SkGradientShader
    const SkColor4f kGradColors[] = { SkColors::kBlack, SkColors::kTransparent };
    const SkGradient grad = {{kGradColors, {}, SkTileMode::kRepeat}, {}};
    const SkPoint center = imgRect.center();
    const float radius = imgRect.width() / 2.f;
    canvas->save();
    // 1. scale provided to Make, drawn with persp
    auto g1 = SkShaders::RadialGradient(center, radius, grad, &scale);
    draw(g1, true);

    // 2. scale provided to Make, then wrapped with makeWithLocalMatrix (post-concat as before).
    auto g2 = g1->makeWithLocalMatrix(persp);
    draw(g2, false);

    // 3. Provide per-computed persp*scale to Make
    auto g3 = SkShaders::RadialGradient(center, radius, grad, &perspScale);
    draw(g3, false);

    // 4.  Providing pre-computed persp*scale to makeWithLocalMatrix
    auto g4 = SkShaders::RadialGradient(center, radius, grad)->makeWithLocalMatrix(perspScale);
    draw(g4, false);
    canvas->restore();
}

namespace skiagm {
class LocalMatrixOrder : public GM {
public:
    LocalMatrixOrder() {}

protected:
    SkString getName() const override { return SkString("localmatrix_order"); }

    SkISize getISize() override { return SkISize::Make(500, 500); }

    void onOnceBeforeDraw() override {
        auto mandrill = ToolUtils::GetResourceAsImage("images/mandrill_256.png");  // 256x256
        auto example5 = ToolUtils::GetResourceAsImage("images/example_5.png");     // 128x128

        auto mshader = mandrill->makeShader(
                SkTileMode::kRepeat,
                SkTileMode::kRepeat,
                SkFilterMode::kNearest,
                SkMatrix::RotateDeg(45, {128, 128})); // rotate about center
        auto eshader = example5->makeShader(
                SkTileMode::kRepeat,
                SkTileMode::kRepeat,
                SkFilterMode::kNearest,
                SkMatrix::Scale(2, 2)); // make same size as mandrill and...
        // ... rotate about center
        eshader = eshader->makeWithLocalMatrix(SkMatrix::RotateDeg(45, {128, 128}));

        // blend the two rotated and aligned images.
        fShader = SkShaders::Blend(SkBlendMode::kModulate, mshader, eshader);
    }

    void onDraw(SkCanvas* canvas) override {
        // Rotate fShader about the canvas center
        auto center = SkRect::Make(canvas->imageInfo().bounds()).center();

        // viewer can insert a dpi scaling matrix. Make the animation always rotate about the device
        // center.
        if (auto ictm = canvas->getTotalMatrix(); ictm.invert(&ictm)) {
            center = ictm.mapPoint(center);
        }

        auto shader = fShader->makeWithLocalMatrix(SkMatrix::RotateDeg(fAngle, center));

        SkPaint paint;
        paint.setShader(shader);
        canvas->drawPaint(paint);
    }

    bool onAnimate(double nanos) override {
        fAngle = TimeUtils::NanosToSeconds(nanos) * 5.f;
        return true;
    }

    sk_sp<SkShader> fShader;
    float fAngle = 0.f;
};

DEF_GM(return new LocalMatrixOrder;)
}  // namespace skiagm
