/*
 * Copyright 2020 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/SkColor.h"
#include "include/core/SkImage.h"
#include "include/core/SkM44.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkSurface.h"
#include "include/effects/SkGradientShader.h"
#include "tools/timer/TimeUtils.h"

// Adapted from https://codepen.io/adamdupuis/pen/qLYzqB
class CrBug224618GM : public skiagm::GM {
public:
    CrBug224618GM() : fTime(0.f) {}

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

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

    // This animates the FOV in viewer, to ensure the panorama covering rects are stable across
    // a variety of perspective matrices
    bool onAnimate(double nanos) override {
        fTime = TimeUtils::Scaled(1e-9f * nanos, 0.5f);
        return true;
    }

    void onOnceBeforeDraw() override {
        static const SkColor kColors[2] = {SK_ColorTRANSPARENT, SkColorSetARGB(128, 255, 255, 255)};
        sk_sp<SkShader> gradient = SkGradientShader::MakeRadial(
                {200.f, 200.f}, 25.f, kColors, nullptr, 2, SkTileMode::kMirror,
                SkGradientShader::kInterpolateColorsInPremul_Flag, nullptr);

        sk_sp<SkSurface> surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(400, 400));

        SkPaint bgPaint;
        bgPaint.setShader(gradient);
        surface->getCanvas()->drawPaint(bgPaint);

        fCubeImage = surface->makeImageSnapshot();
    }

    void onDraw(SkCanvas* canvas) override {
        SkScalar viewportWidth = SkScalarMod(fTime, 10.f) / 10.f * (kMaxVW - kMinVW) + kMinVW;
        SkScalar radius = viewportWidth / 2.f; // round?
        // See https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/perspective
        SkM44 proj{1.f, 0.f, 0.f, 0.f,
                   0.f, 1.f, 0.f, 0.f,
                   0.f, 0.f, 1.f, 0.f,
                   0.f, 0.f, -1.f / radius, 1.f};
        SkM44 zoom             = SkM44::Translate(0.f, 0.f, radius);
        SkM44 postZoom         = SkM44::Translate(0.f, 0.f, -radius - 1.f);
        SkM44 rotateHorizontal = SkM44::Rotate({0, 1, 0}, 2.356194490192345f);

        // w in degrees will need to be converted to radians
        SkV4 axisAngles[6] = {
            {0.f, 1.f, 0.f, -90.f}, // rotateY(-90deg)
            {1.f, 0.f, 0.f, 0.f},   // <none>
            {0.f, 1.f, 0.f, 90.f},  // rotateY(90deg)
            {0.f, 1.f, 0.f, 180.f}, // rotateY(180deg)
            {1.f, 0.f, 0.f, -90.f}, // rotateX(-90deg)
            {1.f, 0.f, 0.f, 90.f},  // rotateX(90deg)
        };
        SkColor faceColors[6] = {
            SK_ColorRED,
            SK_ColorGREEN,
            SK_ColorBLUE,
            SK_ColorYELLOW,
            SkColorSetARGB(0xFF, 0xFF, 0xA5, 0x00), // orange css
            SkColorSetARGB(0xFF, 0x80, 0x00, 0x80)  // purple css
        };

        for (int i = 0; i < 6; ++i) {
            SkM44 model = SkM44::Rotate({axisAngles[i].x, axisAngles[i].y, axisAngles[i].z},
                                            SkDegreesToRadians(axisAngles[i].w));
            model = SkM44::Translate(radius, radius) * proj *    // project and place content
                    zoom * rotateHorizontal * model * postZoom * // main model matrix
                    SkM44::Translate(-radius, -radius);          // center content

            canvas->save();
            canvas->concat(model);

            SkPaint fillPaint;
            fillPaint.setAntiAlias(true);
            fillPaint.setColor(faceColors[i]);

            // Leverages FillRectOp on GPU backend
            canvas->drawRect(SkRect::MakeWH(viewportWidth, viewportWidth), fillPaint);

            // Leverages TextureOp on GPU backend, to ensure sure both quad paths handle clipping
            canvas->drawImageRect(fCubeImage.get(),
                                  SkRect::MakeWH(fCubeImage->width(), fCubeImage->height()),
                                  SkRect::MakeWH(viewportWidth, viewportWidth),
                                  SkSamplingOptions(SkFilterMode::kLinear), &fillPaint,
                                  SkCanvas::kFast_SrcRectConstraint);

            canvas->restore();
        }
    }
private:
    static const int kMaxVW = 800;
    static const int kMinVW = 300;

    SkScalar fTime;
    sk_sp<SkImage> fCubeImage;
};

DEF_GM(return new CrBug224618GM();)
