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

#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkCubicMap.h"
#include "include/core/SkImage.h"
#include "include/core/SkPoint.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkVertices.h"
#include "include/effects/SkGradient.h"
#include "include/private/base/SkFloatingPoint.h"
#include "tools/DecodeUtils.h"
#include "tools/Resources.h"
#include "tools/timer/TimeUtils.h"
#include "tools/viewer/Slide.h"

#include <cmath>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <vector>

#include "imgui.h"

namespace {

float lerp(float a, float b, float t) {
    return a + (b - a)*t;
}

sk_sp<SkShader> make_image_shader(const char* resource) {
    sk_sp<SkImage> img = ToolUtils::GetResourceAsImage(resource);

    // Normalize to 1x1 for UV sampling.
    const auto lm = SkMatrix::Scale(1.0f/img->width(), 1.0f/img->height());

    return img->makeShader(SkTileMode::kDecal,
                           SkTileMode::kDecal,
                           SkSamplingOptions(SkFilterMode::kLinear),
                           &lm);
}

static constexpr struct ShaderFactory {
    const char*     fName;
    sk_sp<SkShader> (*fBuild)();
} gShaderFactories[] = {
    {
        "Img (Mandrill)",
        []() ->sk_sp<SkShader> { return make_image_shader("images/mandrill_512.png"); }
    },
    {
        "Img (Baby Tux)",
        []() ->sk_sp<SkShader> { return make_image_shader("images/baby_tux.png"); }
    },
    {
        "Img (Brickwork)",
        []() ->sk_sp<SkShader> { return make_image_shader("images/brickwork-texture.jpg"); }
    },
    {
        "Radial Gradient",
        []() ->sk_sp<SkShader> {
            static constexpr SkColor4f gColors[] = {
                SkColors::kGreen, SkColors::kRed, SkColors::kBlue, SkColors::kGreen
            };
            return SkShaders::RadialGradient({0.5f, 0.5f}, 0.5f,
                                             {{gColors, {}, SkTileMode::kRepeat}, {}});
        }
    },
    {
        "Colors",
        []() ->sk_sp<SkShader> { return nullptr; }
    },
};

static constexpr struct VertexAnimator {
    const char* fName;
    void (*fAanimate)(const std::vector<SkPoint>& uv, float t, std::vector<SkPoint>& out);
} gVertexAnimators[] = {
    {
        "Cylinderator",
        // Simulate a cylinder rolling sideways across the 1x1 uv space.
        [](const std::vector<SkPoint>& uvs, float t, std::vector<SkPoint>& out) {
            static constexpr float kCylRadius = .2f;

            const auto cyl_pos = t;

            for (size_t i = 0; i < uvs.size(); ++i) {
                const auto& uv = uvs[i];

                if (uv.fX <= cyl_pos) {
                    out[i] = uv;
                    continue;
                }

                const auto arc_len = uv.fX - cyl_pos,
                           arc_ang = arc_len/kCylRadius;

                out[i] = SkPoint{
                    cyl_pos + std::sin(arc_ang)*kCylRadius,
                    uv.fY,
                };
            }
        },
    },
    {
        "Squircillator",
        // Pull all vertices towards center, proportionally, such that the outer square edge
        // is mapped to a circle for t == 1.
        [](const std::vector<SkPoint>& uvs, float t, std::vector<SkPoint>& out) {
            for (size_t i = 0; i < uvs.size(); ++i) {
                // remap to [-.5,.5]
                const auto uv = (uvs[i] - SkPoint{0.5,0.5});

                // Distance from center to outer edge for the line pasing through uv.
                const auto d = uv.length()*0.5f/std::max(std::abs(uv.fX), std::abs(uv.fY));
                // Scale needed to pull the outer edge to the r=0.5 circle at t == 1.
                const auto s = lerp(1, (0.5f / d), t);

                out[i] = uv*s + SkPoint{0.5, 0.5};
            }
        },
    },
    {
        "Twirlinator",
        // Rotate vertices proportional to their distance to center.
        [](const std::vector<SkPoint>& uvs, float t, std::vector<SkPoint>& out) {
            static constexpr float kMaxRotate = SK_FloatPI*4;

            for (size_t i = 0; i < uvs.size(); ++i) {
                // remap to [-.5,.5]
                const auto uv = (uvs[i] - SkPoint{0.5,0.5});
                const auto angle = kMaxRotate * t * uv.length();

                out[i] = SkMatrix::RotateRad(angle).mapPoint(uv) + SkPoint{0.5, 0.5};
            }
        },
    },
    {
        "Wigglynator",
        [](const std::vector<SkPoint>& uvs, float t, std::vector<SkPoint>& out) {
            const float radius = t*0.2f/(std::sqrt(uvs.size()) - 1);
            for (size_t i = 0; i < uvs.size(); ++i) {
                const float phase = i*SK_FloatPI*0.31f,
                            angle = phase + t*SK_FloatPI*2;
                out[i] = uvs[i] + SkVector{
                    radius*std::cos(angle),
                    radius*std::sin(angle),
                };
            }
        },
    },
    {
        "None",
        [](const std::vector<SkPoint>& uvs, float, std::vector<SkPoint>& out) { out = uvs; },
    },
};

class MeshSlide final : public Slide {
public:
    MeshSlide() : fTimeMapper({0.5f, 0}, {0.5f, 1}) { fName = "Mesh"; }

    void load(SkScalar w, SkScalar h) override {
        fSize = {w, h};

        this->initMesh(256);
        this->initShader(gShaderFactories[0]);
    }

    void resize(SkScalar w, SkScalar h) override { fSize = {w, h}; }

    void draw(SkCanvas* canvas) override {
        SkAutoCanvasRestore acr(canvas, true);

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

        static constexpr float kMeshFraction = 0.85f;
        const float mesh_size = std::min(fSize.fWidth, fSize.fHeight)*kMeshFraction;

        canvas->translate((fSize.fWidth  - mesh_size) * 0.5f,
                          (fSize.fHeight - mesh_size) * 0.5f);
        canvas->scale(mesh_size, mesh_size);

        auto verts = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode,
                                          fVertices.size(),
                                          fVertices.data(),
                                          fShader ? fUVs.data() : nullptr,
                                          fShader ? nullptr : fColors.data(),
                                          fIndices.size(),
                                          fIndices.data());
        p.setShader(fShader);
        canvas->drawVertices(verts, SkBlendMode::kModulate, p);

        if (fShowMesh) {
            p.setShader(nullptr);
            p.setColor(SK_ColorBLUE);
            p.setStroke(true);
            p.setStrokeWidth(0.5f/mesh_size);

            SkASSERT(fIndices.size() % 6 == 0);
            for (auto i = fIndices.cbegin(); i < fIndices.cend(); i += 6) {
                canvas->drawLine(fVertices[i[0]], fVertices[i[1]], p);
                canvas->drawLine(fVertices[i[1]], fVertices[i[2]], p);
                canvas->drawLine(fVertices[i[2]], fVertices[i[0]], p);
                canvas->drawLine(fVertices[i[3]], fVertices[i[4]], p);
                canvas->drawLine(fVertices[i[4]], fVertices[i[5]], p);
                canvas->drawLine(fVertices[i[5]], fVertices[i[3]], p);
            }

            p.setStrokeCap(SkPaint::kRound_Cap);
            p.setStrokeWidth(5/mesh_size);
            canvas->drawPoints(SkCanvas::kPoints_PointMode, fVertices, p);
        }

        this->drawControls();
    }

    bool animate(double nanos) override {
        if (!fTimeBase) {
            fTimeBase = nanos;
        }

        // Oscillating between 0..1
        const float t =
                std::abs((std::fmod((nanos - fTimeBase)*0.000000001*fAnimationSpeed, 2) - 1));

        // Add some easing
        fCurrentAnimator->fAanimate(fUVs, fTimeMapper.computeYFromX(t), fVertices);

        return true;
    }

private:
    void initMesh(size_t vertex_count) {
        // Generate an NxN mesh.  For simplicity, we keep the vertices in normalized space
        // (1x1 same as UVs), and scale the mesh up when rendering.
        const auto n = static_cast<size_t>(std::sqrt(vertex_count));
        SkASSERT(n > 0);
        SkASSERT(n == std::sqrt(vertex_count));

        fVertices.resize(vertex_count);
        fUVs.resize(vertex_count);
        fColors.resize(vertex_count);
        for (size_t i = 0; i < vertex_count; ++i) {
            fVertices[i] = fUVs[i] = {
                static_cast<float>(i % n) / (n - 1),
                static_cast<float>(i / n) / (n - 1),
            };
            fColors[i] = SkColorSetRGB(!!(i%2)*255,
                                       !!(i%3)*255,
                                       !!((i+1)%3)*255);
        }

        // Trivial triangle tessellation pattern:
        //
        // *---*---*
        // |  /|\  |
        // | / | \ |
        // |/  |  \|
        // *---*---*
        // |\  |  /|
        // | \ | / |
        // |  \|/  |
        // *---*---*
        const size_t triangle_count = 2*(n - 1)*(n - 1),
                        index_count = 3*triangle_count;

        fIndices.clear();
        fIndices.reserve(index_count);
        for (size_t i = 0; i < n - 1; ++i) {
            for (size_t j = 0; j < n - 1; ++j) {
                const auto row_0_idx = j*n + i,
                           row_1_idx = row_0_idx + n,
                           off_0 = (i + j) % 2,
                           off_1 = 1 - off_0;

                fIndices.push_back(row_0_idx +     0);
                fIndices.push_back(row_0_idx +     1);
                fIndices.push_back(row_1_idx + off_0);

                fIndices.push_back(row_0_idx + off_1);
                fIndices.push_back(row_1_idx +     1);
                fIndices.push_back(row_1_idx +     0);
            }
        }

        SkASSERT(fIndices.size() == index_count);
    }

    void initShader(const ShaderFactory& fact) {
        fShader = fact.fBuild();
        fCurrentShaderFactory = &fact;
    }

    void drawControls() {
        ImGui::Begin("Mesh Options");

        if (ImGui::BeginCombo("Texture", fCurrentShaderFactory->fName)) {
            for (const auto& fact : gShaderFactories) {
                const auto is_selected = (fCurrentShaderFactory->fName == fact.fName);
                if (ImGui::Selectable(fact.fName) && !is_selected) {
                    this->initShader(fact);
                }
                if (is_selected) {
                    ImGui::SetItemDefaultFocus();
                }
            }
            ImGui::EndCombo();
        }

        if (ImGui::BeginCombo("Animator", fCurrentAnimator->fName)) {
            for (const auto& anim : gVertexAnimators) {
                const auto is_selected = (fCurrentAnimator->fName == anim.fName);
                if (ImGui::Selectable(anim.fName) && !is_selected) {
                    fCurrentAnimator = &anim;
                    fTimeBase = 0;
                }
                if (is_selected) {
                    ImGui::SetItemDefaultFocus();
                }
            }
            ImGui::EndCombo();
        }

        static constexpr struct {
            const char* fLabel;
            size_t      fCount;
        } gSizeInfo[] = {
            {     "4x4",    16 },
            {     "8x8",    64 },
            {   "16x16",   256 },
            {   "32x32",  1024 },
            {   "64x64",  4096 },
            { "128x128", 16384 },
        };
        ImGui::SliderInt("Mesh Size",
                         &fMeshSizeSelector,
                         0, std::size(gSizeInfo) - 1,
                         gSizeInfo[fMeshSizeSelector].fLabel);
        if (fVertices.size() != gSizeInfo[fMeshSizeSelector].fCount) {
            this->initMesh(gSizeInfo[fMeshSizeSelector].fCount);
        }

        ImGui::SliderFloat("Speed", &fAnimationSpeed, 0.25, 4, "%.2f");

        ImGui::Checkbox("Show mesh", &fShowMesh);

        ImGui::End();
    }

    SkSize                  fSize;
    sk_sp<SkShader>         fShader;
    std::vector<SkPoint>    fVertices,
                            fUVs;
    std::vector<SkColor>    fColors;
    std::vector<uint16_t>   fIndices;

    double                  fTimeBase = 0;
    const SkCubicMap        fTimeMapper;

    // UI stuff
    const ShaderFactory*    fCurrentShaderFactory = &gShaderFactories[0];
    const VertexAnimator*   fCurrentAnimator      = &gVertexAnimators[0];
    int                     fMeshSizeSelector     = 2;
    float                   fAnimationSpeed       = 1.f;
    bool                    fShowMesh             = false;
};

}  // anonymous namespace

DEF_SLIDE(return new MeshSlide{};)
