/*
 * 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) {}

  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(),
              rive::ImageSampler::LinearClamp(),
              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(mesh, return new MeshGM)

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

public:
  MeshHitTestGM(int N) : GM(60, 60) { 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(mesh_ht_7, return new MeshHitTestGM(7))
GMREGISTER(mesh_ht_1, return new MeshHitTestGM(1))
