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

#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkCubicMap.h"
#include "include/core/SkFont.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkShader.h"
#include "include/core/SkString.h"
#include "include/core/SkVertices.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/private/SkDebug.h"
#include "src/core/SkRandom.h"
#include "tools/fonts/FontToolUtils.h"
#include "tools/viewer/Slide.h"

#include "delaunator.hpp"
#include "imgui.h"

#include <array>
#include <cmath>
#include <cstddef>
#include <limits>
#include <vector>

namespace {

sk_sp<SkVertices> triangulate_pts(const std::vector<SkPoint>& pts, const std::vector<SkColor>& colors) {
    // put points in the format delaunator wants
    std::vector<double> coords;
    for (size_t i = 0; i < pts.size(); ++i) {
        coords.push_back(pts[i].x());
        coords.push_back(pts[i].y());
    }

    // triangulation happens here
    delaunator::Delaunator d(coords);

    // SkVertices parameters
    std::vector<SkPoint> vertices;
    std::vector<uint16_t> indices;

    // populate vertices & colors
    for(std::size_t i = 0; i < d.coords.size(); i+=2) {
        vertices.push_back(SkPoint::Make(d.coords[i], d.coords[i+1]));
    }

    // populate triangle indices
    for(std::size_t i = 0; i < d.triangles.size(); i+=3) {
        indices.push_back(d.triangles[i]);
        indices.push_back(d.triangles[i+1]);
        indices.push_back(d.triangles[i+2]);
    }

    return SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, vertices.size(), vertices.data(), nullptr, colors.data(), indices.size(), indices.data());
}

sk_sp<SkShader> makeGradientShader(int w, int h, std::vector<SkPoint>& vertices, std::vector<SkColor>& colors) {
    vertices.push_back(SkPoint::Make(0.f, 0.f));
    vertices.push_back(SkPoint::Make(w, 0.f));
    vertices.push_back(SkPoint::Make(0.f, h));
    vertices.push_back(SkPoint::Make(w, h));

    colors.push_back(SK_ColorTRANSPARENT);
    colors.push_back(SK_ColorTRANSPARENT);
    colors.push_back(SK_ColorTRANSPARENT);
    colors.push_back(SK_ColorTRANSPARENT);

    sk_sp<SkVertices> sk_vertices = triangulate_pts(vertices, colors);

    // record with a picture
    SkRect tile = SkRect::MakeWH(w, h);
    SkPictureRecorder recorder;
    SkCanvas* c = recorder.beginRecording(tile);

    SkPaint p;
    p.setColor(SK_ColorWHITE);
    c->drawVertices(sk_vertices, SkBlendMode::kModulate, p);
    sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());

    return picture->makeShader(SkTileMode::kDecal, SkTileMode::kDecal, SkFilterMode::kNearest);
}

class GradientRenderer : public SkRefCnt {
public:
    virtual void draw(SkCanvas*) const = 0;

    virtual sk_sp<SkShader> asShader() const = 0;

    virtual void updateVertices(SkSpan<const SkPoint> vert_pos,
                                SkSpan<const SkColor4f> vert_colors) = 0;
};

class SkSlRenderer : public GradientRenderer {
public:
    void draw(SkCanvas* canvas) const override {
        SkPaint paint;
        paint.setShader(fShader);
        canvas->drawRect(SkRect::MakeWH(1, 1), paint);
    }

    sk_sp<SkShader> asShader() const override { return fShader; }

    void updateVertices(SkSpan<const SkPoint> vert_pos,
                        SkSpan<const SkColor4f> vert_colors) override {
        SkASSERT(vert_pos.size() == vert_colors.size());
        const auto vert_count = vert_pos.size();

        if (!vert_count) {
            return;
        }

        // Effect compilation is expensive, so we cache and only recompile when the count changes.
        if (vert_count != fCachedCount) {
            this->buildEffect(vert_count);
            fCachedCount = vert_count;
        }

        SkRuntimeEffectBuilder builder(fEffect);
        builder.uniform("u_vertcolors").set(vert_colors.data(), vert_colors.size());
        builder.uniform("u_vertpos")   .set(vert_pos.data()   , vert_pos.size());

        fShader = builder.makeShader();
    }
    virtual void buildEffect(size_t vert_count) = 0;

protected:
    sk_sp<SkRuntimeEffect> fEffect;
    sk_sp<SkShader>        fShader;

    size_t                 fCachedCount = 0;
};

class AEGradientRenderer final : public SkSlRenderer {
public:
    void buildEffect(size_t vert_count) override {
        static constexpr char gAEGradientSkSL[] =
            "uniform half4  u_vertcolors[%zu];"
            "uniform float2 u_vertpos[%zu];"

            "half4 main(float2 xy) {"
                "half4 c = half4(0);"
                "float w_acc = 0;"

                "for (int i = 0; i < %zu; ++i) {"
                    "float d = distance(xy, u_vertpos[i]);"
                    "float w = 1 / (d * d);"

                    "c += u_vertcolors[i] * w;"
                    "w_acc += w;"
                "}"

                "return c / w_acc;"
            "}";

        const auto res = SkRuntimeEffect::MakeForShader(
                            SkStringPrintf(gAEGradientSkSL, vert_count, vert_count, vert_count));
        if (!res.effect) {
            SkDEBUGF("%s\n", res.errorText.c_str());
        }

        fEffect = res.effect;

        SkASSERT(fEffect);
    }
};

class LinearGradientRenderer final : public SkSlRenderer {
public:
    void buildEffect(size_t vert_count) override {
        static constexpr char sksl[] =
            "uniform half4  u_vertcolors[%zu];"
            "uniform float2 u_vertpos[%zu];"

            "half4 main(float2 xy) {"
                "float v[%zu];"
                "for (int i = 0; i < %zu; i++) {"
                    "v[i] = 1.;"
                "}"

                "for (int i = 0; i < %zu; ++i) {"
                    "for (int j = 0; j < %zu; ++j) {"
                        "vec2 delta;"
                        "delta.x = u_vertpos[j].x - u_vertpos[i].x;"
                        "delta.y = u_vertpos[j].y - u_vertpos[i].y;"

                        "mat3 m = mat3 ("
                            "delta.x, delta.y, 0.,"                 // 1st column
                            "-delta.y, delta.x, 0.,"                // 2nd column
                            "u_vertpos[i].x, u_vertpos[i].y, 1."    // 3rd column
                        ");"
                        "mat3 m_inv = inverse(m);"

                        "vec3 p_h = vec3(xy.x, xy.y, 1.);"
                        "vec3 u = m_inv*p_h;"
                        "float t = u.x;"

                        "if (t < 0) {"
                            "v[j] = 0;"
                        "} else if (t > 1) {"
                            "v[i] = 0;"
                        "} else {"
                            "v[i] *= 1-t;"
                            "v[j] *= t;"
                        "}"
                    "}"
                "}"

                "half4 c = half4(0);"
                "float w_acc = 0;"
                "for (int i = 0; i < %zu; i++) {"
                    "c += u_vertcolors[i] * v[i];"
                    "w_acc += v[i];"
                "}"

                "return c / w_acc;"
            "}";

        const auto res = SkRuntimeEffect::MakeForShader(
                            SkStringPrintf(sksl, vert_count, vert_count, vert_count, vert_count, vert_count, vert_count, vert_count));
        if (!res.effect) {
            SkDEBUGF("%s\n", res.errorText.c_str());
        }

        fEffect = res.effect;

        SkASSERT(fEffect);
    }
};

class IllGradientRenderer final : public SkSlRenderer {
public:
    void buildEffect(size_t vert_count) override {
        static constexpr char sksl[] =
            "uniform half4  u_vertcolors[%zu];"
            "uniform float2 u_vertpos[%zu];"

            "half4 main(float2 xy) {"
                "float d[%zu];"
                "for (int i = 0; i < %zu; i++) {"
                    "d[i] = 0.;"
                "}"

                "for (int i = 0; i < %zu; ++i) {"
                    "for (int j = 0; j < %zu; ++j) {"
                        "vec2 delta;"
                        "delta.x = u_vertpos[j].x - u_vertpos[i].x;"
                        "delta.y = u_vertpos[j].y - u_vertpos[i].y;"

                        "mat3 m = mat3 ("
                            "delta.x, delta.y, 0.,"                 // 1st column
                            "-delta.y, delta.x, 0.,"                // 2nd column
                            "u_vertpos[i].x, u_vertpos[i].y, 1."    // 3rd column
                        ");"
                        "mat3 m_inv = inverse(m);"

                        "vec3 p_h = vec3(xy.x, xy.y, 1.);"
                        "vec3 u = m_inv*p_h;"
                        "float t = u.x;"

                        "float s = length(delta);"
                        "if (t < 0) {"
                            "d[i] += s*abs(u.y);"
                            "d[j] += s*distance(vec2(u.x, u.y), vec2(1., 0.));"
                        "} else if (t > 1) {"
                            "d[j] += s*abs(u.y);"
                            "d[i] += s*distance(vec2(u.x, u.y), vec2(0., 0.));"
                        "} else {"
                            "d[i] += s*distance(vec2(u.x, u.y), vec2(0., 0.));"
                            "d[j] += s*distance(vec2(u.x, u.y), vec2(1., 0.));"
                        "}"
                    "}"
                "}"

                "half4 c = half4(0);"
                "float w_acc = 0;"
                "for (int i = 0; i < %zu; i++) {"
                    "float w = 1 / (d[i] * d[i]);"
                    "c += u_vertcolors[i] * w;"
                    "w_acc += w;"
                "}"

                "return c / w_acc;"
            "}";

        const auto res = SkRuntimeEffect::MakeForShader(
                            SkStringPrintf(sksl, vert_count, vert_count, vert_count, vert_count, vert_count, vert_count, vert_count));
        if (!res.effect) {
            SkDEBUGF("%s\n", res.errorText.c_str());
        }

        fEffect = res.effect;

        SkASSERT(fEffect);
    }
};

class TriangulatedGradientRenderer final : public GradientRenderer {
public:
    void draw(SkCanvas* canvas) const override {
        SkPaint paint;
        paint.setShader(fShader);
        canvas->drawRect(SkRect::MakeWH(1, 1), paint);
    }

    sk_sp<SkShader> asShader() const override { return fShader; }

    void updateVertices(SkSpan<const SkPoint> vert_pos,
                        SkSpan<const SkColor4f> vert_colors) override {
        SkASSERT(vert_pos.size() == vert_colors.size());
        const auto vert_count = vert_pos.size();

        if (!vert_count) {
            return;
        }

        std::vector<SkPoint> pos;
        for (auto& p : vert_pos) {
            pos.push_back(p);
        }
        std::vector<SkColor> colors;
        for (auto& c : vert_colors) {
            colors.push_back(c.toSkColor());
        }

        fShader = makeGradientShader(1, 1, pos, colors);
    }

private:
    sk_sp<SkShader> fShader;
};

static constexpr struct RendererChoice {
    const char* fName;
    sk_sp<GradientRenderer>(*fFactory)();
} gGradientRenderers[] = {
    {
        "AfterEffects Gradient",
        []() -> sk_sp<GradientRenderer> { return sk_make_sp<AEGradientRenderer>(); }
    },
    {
        "n-Linear gradient",
        []() -> sk_sp<GradientRenderer> { return sk_make_sp<LinearGradientRenderer>(); }
    },
    {
        "Illustrator (attempt) gradient",
        []() -> sk_sp<GradientRenderer> { return sk_make_sp<IllGradientRenderer>(); }
    },
    {
        "Triangulated gradient",
        []() -> sk_sp<GradientRenderer> { return sk_make_sp<TriangulatedGradientRenderer>(); }
    }
};

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

static constexpr struct VertexAnimator {
    const char* fName;
    void (*fAanimate)(SkSpan<const SkPoint> uvs, SkSpan<SkPoint> pos, float t);
} gVertexAnimators[] = {
    {
        "Wigglynator",
        [](SkSpan<const SkPoint> uvs, SkSpan<SkPoint> pos, float t) {
            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;
                pos[i] = uvs[i] + SkVector{
                    radius*std::cos(angle),
                    radius*std::sin(angle),
                };
            }
        },
    },
    {
        "Squircillator",
        // Pull all vertices towards center, proportionally, such that the outer square edge
        // is mapped to a circle for t == 1.
        [](SkSpan<const SkPoint> uvs, SkSpan<SkPoint> pos, float t) {
            for (size_t i = 0; i < uvs.size(); ++i) {
                // remap to [-.5,.5]
                const auto uv = (uvs[i] - SkPoint{0.5,0.5});
                // can't allow len to collapse to zero, lest bad things happen at {0.5, 0.5}
                const auto len = std::max(uv.length(), std::numeric_limits<float>::min());

                // Distance from center to outer edge for the line pasing through uv.
                const auto d = len*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);

                pos[i] = uv*s + SkPoint{0.5, 0.5};
            }
        },
    },
    {
        "Twirlinator",
        // Rotate vertices proportional to their distance to center.
        [](SkSpan<const SkPoint> uvs, SkSpan<SkPoint> pos, float t) {
            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();

                pos[i] = SkMatrix::RotateRad(angle).mapPoint(uv) + SkPoint{0.5, 0.5};
            }
        },
    },
    {
        "Cylinderator",
        // Simulate a cylinder rolling sideways across the 1x1 uv space.
        [](SkSpan<const SkPoint> uvs, SkSpan<SkPoint> pos, float t) {
            static constexpr float kCylRadius = .2f;

            const auto cyl_pos = t;

            for (size_t i = 0; i < uvs.size(); ++i) {
                if (uvs[i].fX <= cyl_pos) {
                    pos[i] = uvs[i];
                    continue;
                }

                const auto arc_len = uvs[i].fX - cyl_pos,
                           arc_ang = arc_len/kCylRadius;

                pos[i] = SkPoint{
                    cyl_pos + std::sin(arc_ang)*kCylRadius,
                    uvs[i].fY,
                };
            }
        },
    },
    {
        "None",
        [](SkSpan<const SkPoint> uvs, SkSpan<SkPoint> pos, float t) {
            memcpy(pos.data(), uvs.data(), uvs.size() * sizeof(SkPoint));
        },
    },
};

class MeshGradientSlide final : public Slide {
public:
    MeshGradientSlide()
        : fCurrentRenderer(gGradientRenderers[0].fFactory())
        , fFont(ToolUtils::DefaultPortableTypeface(), .75f)
        , fTimeMapper({0.5f, 0}, {0.5f, 1})
        , fVertedCountTimeMapper({0, 0.5f}, {0.5f, 1})
    {
            fName = "MeshGradient";
    }

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

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

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

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

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

        if (fShaderFill) {
            SkPaint paint;
            paint.setAntiAlias(true);
            paint.setShader(fCurrentRenderer->asShader());
            canvas->drawString("SK", 0, 0.75f, fFont, paint);
        } else {
            fCurrentRenderer->draw(canvas);
        }

        this->drawControls();
    }

    bool animate(double nanos) override {
        // Mesh count animation
        {
            if (!fVertexCountTimeBase) {
                fVertexCountTimeBase = nanos;
            }

            static constexpr float kSizeAdjustSeconds = 2;
            const float t = (nanos - fVertexCountTimeBase) * 0.000000001 / kSizeAdjustSeconds;

            this->updateMesh(lerp(fVertexCountFrom,
                                  fVertexCountTo,
                                  fVertedCountTimeMapper.computeYFromX(t)));
        }

        // Vertex animation
        {
            if (!fTimeBase) {
                fTimeBase = nanos;
            }

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

            fCurrentAnimator->fAanimate(fVertUVs, fVertPos, fTimeMapper.computeYFromX(t));

            fCurrentRenderer->updateVertices(fVertPos, fVertColors);
        }

        return true;
    }

private:
    void updateMesh(size_t new_count) {
        // These look better than rng when the count is low.
        struct GFixedVertices {
            SkPoint   fUv;
            SkColor4f fColor;
        };
        static constexpr auto gFixedVertices = std::to_array<GFixedVertices>({
                GFixedVertices{{.25f, .25f}, {1, 0, 0, 1}},
                GFixedVertices{{.75f, .75f}, {0, 1, 0, 1}},
                GFixedVertices{{.75f, .25f}, {0, 0, 1, 1}},
                GFixedVertices{{.25f, .75f}, {1, 1, 0, 1}},
                GFixedVertices{{.50f, .50f}, {0, 1, 1, 1}},
        });

        SkASSERT(fVertUVs.size() == fVertPos.size());
        SkASSERT(fVertUVs.size() == fVertColors.size());
        const size_t current_count = fVertUVs.size();

        fVertUVs.resize(new_count);
        fVertPos.resize(new_count);
        fVertColors.resize(new_count);

        for (size_t i = current_count; i < new_count; ++i) {
            const SkPoint uv = i < std::size(gFixedVertices)
                ? gFixedVertices[i].fUv
                : SkPoint{ fRNG.nextF(), fRNG.nextF() };
            const SkColor4f color = i < std::size(gFixedVertices)
                ? gFixedVertices[i].fColor
                : SkColor4f{ fRNG.nextF(), fRNG.nextF(), fRNG.nextF(), 1.f };

            fVertUVs[i] = fVertPos[i] = uv;
            fVertColors[i] = color;
        }

        if (new_count < current_count) {
            // Reset the RNG state
            fRNG.setSeed(0);
            static constexpr size_t kRandsPerVertex = 5;
            const size_t rand_vertex_count =
                std::max(new_count, std::size(gFixedVertices)) - std::size(gFixedVertices);
            for (size_t i = 0; i < rand_vertex_count * kRandsPerVertex; ++i) { fRNG.nextF(); }
        }
    }

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

        if (ImGui::BeginCombo("Gradient Type", fCurrentRendererChoice->fName)) {
            for (const auto& renderer : gGradientRenderers) {
                const auto is_selected = (fCurrentRendererChoice->fName == renderer.fName);
                if (ImGui::Selectable(renderer.fName) && !is_selected) {
                    fCurrentRendererChoice = &renderer;
                    fCurrentRenderer = renderer.fFactory();
                    fCurrentRenderer->updateVertices(fVertPos, fVertColors);
                }
                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();
        }

        if (ImGui::SliderInt("Vertex Count", &fVertexCountTo, 3, 64)) {
            fVertexCountTimeBase = 0;
            fVertexCountFrom = fVertUVs.size();
        }

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

        ImGui::Checkbox("Shader Fill", &fShaderFill);

        ImGui::End();
    }

    SkSize                  fSize;
    std::vector<SkPoint>    fVertUVs;
    std::vector<SkPoint>    fVertPos;    // fVertUVs after animation
    std::vector<SkColor4f>  fVertColors;

    SkRandom                fRNG;

    sk_sp<GradientRenderer> fCurrentRenderer;

    const SkFont            fFont;

    // Animation state
    const SkCubicMap        fTimeMapper,
                            fVertedCountTimeMapper;
    double                  fTimeBase               = 0,
                            fVertexCountTimeBase    = 0;
    int                     fVertexCountFrom        = 0,
                            fVertexCountTo          = 5;

    // UI stuff
    const RendererChoice*   fCurrentRendererChoice  = &gGradientRenderers[0];
    const VertexAnimator*   fCurrentAnimator        = &gVertexAnimators[0];
    float                   fAnimationSpeed         = 1.f;
    bool                    fShaderFill             = false;
};

}  // anonymous namespace

DEF_SLIDE(return new MeshGradientSlide{};)
