/*
 * Copyright 2022 Rive
 * Copyright 2022 Rive
 */

#include "gm.hpp"
#include "gmutils.hpp"
#include "bicubic.hpp"

#include "rive/math/math_types.hpp"
#include "rive/math/hit_test.hpp"

#include "assets/nomoon.png.hpp"

class Random
{
    //  See "Numerical Recipes in C", 1992 page 284 for these constants
    //  For the LCG that sets the initial state from a seed
    enum
    {
        kMul = 1664525,
        kAdd = 1013904223
    };
    uint32_t m_Seed;

public:
    Random(uint32_t seed = 0) : m_Seed(seed) {}

    uint32_t nextU()
    {
        m_Seed = m_Seed * kMul + kAdd;
        return m_Seed;
    }

    float nextF()
    {
        double x = this->nextU() * (1.0 / (1 << 30));
        return (float)(x - std::floor(x));
    }

    float nextF(float min, float max)
    {
        return this->nextF() * (max - min) + min;
    }
};

using namespace rivegm;

static void make_patch(rive::Vec2D pts[16], const rive::AABB& r)
{
    const float sx = r.width() / 3;
    const float sy = r.height() / 3;

    for (int y = 0; y < 4; ++y)
    {
        for (int x = 0; x < 4; ++x)
        {
            const int index = y * 4 + x;
            pts[index] = {
                r.left() + x * sx,
                r.top() + y * sy,
            };
        }
    }
}

static void perterb_patch(rive::Vec2D pts[16], float scale)
{
    Random rand;
    auto rf = [&]() { return rand.nextF(-scale, scale); };

    for (int i = 0; i < 16; ++i)
    {
        auto dx = rf();
        auto dy = rf();
        pts[i] += {dx, dy};
    }
}

class MeshGM : public GM
{
public:
    MeshGM() : GM(800, 600, "mesh") {}

    void onDraw(rive::Renderer* ren) override
    {
        auto img = LoadImage(assets::nomoon_png());

        constexpr float kGridCellSize = 20;
        Path grid;
        grid->fillRule(rive::FillRule::evenOdd);
        for (size_t v = 0; v < 400 / (kGridCellSize * 2); ++v)
        {
            grid->addRect(0, v * kGridCellSize * 2, 1600, kGridCellSize);
        }
        for (size_t u = 0; u < 1600 / (kGridCellSize * 2); ++u)
        {
            grid->addRect(u * kGridCellSize * 2, 0, kGridCellSize, 400);
        }
        Paint gray;
        gray->color(0xa0a0a0a0);

        BicubicPatch patch;

        rive::AABB r = {50, 50, 350, 350};
        make_patch(patch.m_Pts, r);
        perterb_patch(patch.m_Pts, 50);
        auto mesh = patch.mesh(TestingWindow::Get()->factory());
        uint32_t vertexCount =
            mesh.pts ? rive::math::lossless_numeric_cast<uint32_t>(
                           mesh.pts->sizeInBytes() / sizeof(rive::Vec2D))
                     : 0;
        uint32_t indexCount =
            mesh.indices ? rive::math::lossless_numeric_cast<uint32_t>(
                               mesh.indices->sizeInBytes() / sizeof(uint16_t))
                         : 0;

        ren->scale(.5f, .5f);

        constexpr rive::BlendMode blendModes[] = {rive::BlendMode::srcOver,
                                                  rive::BlendMode::darken,
                                                  rive::BlendMode::luminosity,
                                                  rive::BlendMode::exclusion};

        // Draw meshes that exercise all variations in the mesh shader:
        // viewMatrix, opacity, blendMode, clipRect, clip.
        for (size_t j = 0; j < 3; ++j)
        {
            if (j == 1)
            {
                ren->clipPath(
                    PathBuilder::Rect({50, 120, 1600 - 50, 800 - 120}));
            }
            ren->drawPath(grid, gray);
            ren->save();
            for (size_t i = 0; i < 4; ++i)
            {
                ren->save();
                ren->translate(200, 200);
                ren->rotate(i);
                ren->translate(-200, -200);
                if (j == 2)
                {
                    ren->clipPath(PathBuilder::Circle(200, 200, 150));
                }
                if (img != nullptr)
                {
                    ren->drawImageMesh(img.get(),
                                       mesh.pts,
                                       mesh.uvs,
                                       mesh.indices,
                                       vertexCount,
                                       indexCount,
                                       blendModes[i],
                                       1.f - .1f * (i + 1));
                }
                ren->restore();
                ren->translate(400, 0);
            }
            ren->restore();
            ren->translate(0, 400);
        }

        if (false)
        {
            Paint paint;
            for (int i = 0; i < 16; ++i)
            {
                auto p = patch.m_Pts[i];
                draw_rect(ren, {p.x - 2, p.y - 2, p.x + 3, p.y + 3}, paint);
            }
        }
    }
};
GMREGISTER(return new MeshGM)

class MeshHitTestGM : public GM
{
    BicubicPatch::Rec rec;
    rive::AABB r = {15, 15, 45, 45};
    int fN;

public:
    MeshHitTestGM(int N, const char name[]) : GM(60, 60, name) { fN = N; }

    void onOnceBeforeDraw() override
    {
        BicubicPatch patch;

        make_patch(patch.m_Pts, r);
        perterb_patch(patch.m_Pts, 6);

        rec = patch.buffers();
    }

    void onDraw(rive::Renderer* ren) override
    {
        Paint paint;

        for (float y = 0; y < 60; y += 1)
        {
            for (float x = 0; x < 60; x += 1)
            {
                auto area = rive::AABB(x, y, x + fN, y + fN);
                rive::ColorInt color = 0xFF000000;
                auto ia = area.round();
                if (rive::HitTester::testMesh(ia, rec.pts, rec.indices))
                {
                    color = 0xFFFFFFFF;
                }

                paint->color(color);
                draw_rect(ren, area, paint.get());
            }
        }
    }
};

GMREGISTER(return new MeshHitTestGM(7, "mesh-ht-7"))
GMREGISTER(return new MeshHitTestGM(1, "mesh-ht-1"))
