/*
 * Copyright 2021 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/SkCanvas.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/effects/SkGradientShader.h"
#include "include/effects/SkRuntimeEffect.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"

class RuntimeEffectImage : public skiagm::GM {
public:
    RuntimeEffectImage() = default;

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

    SkISize onISize() override { return {800, 200}; }

protected:
    void onOnceBeforeDraw() override {
        SkString sksl(R"(
            uniform shader child;
            uniform half gAlphaType; // 0 is premul, non-zero unpremul.

            half4 main(float2 p) {
                half r = fract(p.x/20);
                half g = fract(p.y/20);
                half b = fract((p.x + 5)/10);
                half a = min(distance(p, vec2(50, 50))/50 + 0.3, 1);
                half4 result = half4(r, g, b, a);
                result *= sample(child, p);
                if (gAlphaType == 0) {
                   result.rgb *= a;
                }
                return result;
            }
        )");
        auto [effect, error] = SkRuntimeEffect::MakeForShader(sksl);
        if (!effect) {
            SkDebugf("RuntimeShader error: %s\n", error.c_str());
        }
        fEffect = std::move(effect);
    }

    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        GrRecordingContext* rc = canvas->recordingContext();
        SkRuntimeShaderBuilder builder(fEffect);
        SkImageInfo info = SkImageInfo::Make(100, 100, kRGBA_8888_SkColorType, kPremul_SkAlphaType);

        SkSamplingOptions nn{SkFilterMode::kNearest};
        SkSamplingOptions mm{SkFilterMode::kLinear, SkMipmapMode::kNearest};
        auto whiteShader = SkShaders::Color(SK_ColorWHITE);
        auto imageForShader = GetResourceAsImage("images/ducky.jpg");
        if (!imageForShader) {
            *errorMsg = "Could not load image";
            return DrawResult::kFail;
        }
        auto imageShader = imageForShader->makeShader(SkTileMode::kRepeat,
                                                      SkTileMode::kRepeat,
                                                      SkSamplingOptions(SkFilterMode::kLinear),
                                                      SkMatrix::Scale(0.2f, 0.2f));

        builder.uniform("gAlphaType") = 0.f;
        builder.child("child") = whiteShader;
        ToolUtils::draw_checkerboard(canvas, SK_ColorWHITE, SK_ColorLTGRAY, 50);
        canvas->translate(5, 5);
        SkPaint aaPaint;
        aaPaint.setAntiAlias(true);
        for (const auto& vm : {SkMatrix::Scale(1.5f, 1.5f), SkMatrix::Scale(0.3f, 0.3f)}) {
            canvas->save();
            canvas->concat(vm);

            sk_sp<SkImage> image;

            // basic
            image = builder.makeImage(rc, nullptr, info, false);
            canvas->drawImage(image, 0, 0, nn, &aaPaint);
            canvas->translate(105, 0);

            // local matrix
            SkMatrix lm = SkMatrix::RotateDeg(45, {50, 50});
            lm.preTranslate(10, 10);
            image = builder.makeImage(rc, &lm, info, false);
            canvas->drawImage(image, 0, 0, nn, &aaPaint);
            canvas->translate(105, 0);

            // unpremul
            if (rc) {
                // use a uniform to make the effect output be unpremul so it looks the same as the
                // premul case when drawn to the canvas.
                builder.uniform("gAlphaType") = 1.f;
                image = builder.makeImage(rc,
                                          nullptr,
                                          info.makeAlphaType(kUnpremul_SkAlphaType),
                                          false);
                builder.uniform("gAlphaType") = 0.f;
                canvas->drawImage(image, 0, 0, nn, &aaPaint);
                canvas->translate(105, 0);
            } else {
                // CPU doesn't yet support making kUnpremul images. Just draw the basic one again.
                image = builder.makeImage(nullptr, nullptr, info, false);
                canvas->drawImage(image, 0, 0, nn, &aaPaint);
                canvas->translate(105, 0);
            }

            // color space
            sk_sp<SkColorSpace> cs = SkColorSpace::MakeSRGB()->makeColorSpin();
            image = builder.makeImage(rc, nullptr, info.makeColorSpace(std::move(cs)), false);
            canvas->drawImage(image, 0, 0, nn, &aaPaint);
            canvas->translate(105, 0);

            // mipmapped and different child
            builder.child("child") = imageShader;
            image = builder.makeImage(rc, nullptr, info, true);
            builder.child("child") = whiteShader;
            canvas->drawImage(image, 0, 0, mm, &aaPaint);
            canvas->translate(105, 0);

            canvas->restore();
            canvas->translate(0, 105*vm.getScaleY());
        }
        return DrawResult::kOk;
    }

private:
    sk_sp<SkRuntimeEffect> fEffect;
};
DEF_GM(return new RuntimeEffectImage;)
