/*
 * Copyright 2022 Rive
 */

#include "bicubic.hpp"
#include <vector>

template <typename T> T lerp(const T& a, const T& b, float t)
{
  return a * (1 - t) + b * t;
}

using namespace rivegm;

rive::Vec2D BicubicPatch::eval(float u, float v) const
{
  float weights[16];
  this->evalWeights(u, v, weights);

  rive::Vec2D result{0, 0};
  for (int i = 0; i < 16; ++i)
  {
    result += m_Pts[i] * weights[i];
  }
  return result;
}

void BicubicPatch::evalWeights(float u, float v, float weights[16]) const
{
  auto compute_bezier_coeff = [](float c[4], float t) {
    float s = 1 - t;
    c[0] = s * s * s;
    c[1] = 3 * t * s * s;
    c[2] = 3 * t * t * s;
    c[3] = t * t * t;
  };

  float cu[4], cv[4];
  compute_bezier_coeff(cu, u);
  compute_bezier_coeff(cv, v);

  int i = 0;
  for (int y = 0; y < 4; ++y)
  {
    for (int x = 0; x < 4; ++x)
    {
      weights[i++] = cu[x] * cv[y];
    }
  }
}

BicubicPatch::Rec BicubicPatch::buffers(const rive::AABB* uvBounds) const
{
  constexpr int N = 16;

  constexpr int QUADS = N * N;
  constexpr int VERTS = (N + 1) * (N + 1);
  constexpr int TRIS = QUADS * 2;
  constexpr int INDXS = TRIS * 3;

  const rive::AABB unit = {0, 0, 1, 1};
  if (!uvBounds)
  {
    uvBounds = &unit;
  }

  Rec rec;
  rec.pts.resize(VERTS);
  rec.uvs.resize(VERTS);

  auto pos = rec.pts.data();
  auto tex = rec.uvs.data();

  const float normalize = 1.0f / N;

  for (int y = 0; y <= N; ++y)
  {
    const float v = y * normalize;
    const float tex_v = lerp(uvBounds->top(), uvBounds->bottom(), v);
    for (int x = 0; x <= N; ++x)
    {
      const float u = x * normalize;
      *pos++ = this->eval(u, v);
      *tex++ = {
          lerp(uvBounds->left(), uvBounds->right(), u),
          tex_v,
      };
    }
  }
  assert(pos - rec.pts.data() == VERTS);
  assert(tex - rec.uvs.data() == VERTS);

  rec.indices.resize(INDXS);
  uint16_t* ndx = rec.indices.data();

  constexpr int W = N + 1;

  int index = 0;
  for (int y = 0; y < N; ++y)
  {
    for (int x = 0; x < N; ++x)
    {
      ndx[0] = index;
      ndx[1] = index + 1;
      ndx[2] = index + 1 + W;
      ndx[3] = index;
      ndx[4] = index + 1 + W;
      ndx[5] = index + W;
      ndx += 6;
      index += 1;
    }
    index += 1; // skip the last column
  }
  assert(ndx - rec.indices.data() == INDXS);
  for (int i = 0; i < INDXS; ++i)
  {
    assert(rec.indices[i] < VERTS);
  }

  return rec;
}

BicubicPatch::Mesh BicubicPatch::mesh(
    rive::Factory* factory,
    const rive::AABB* uvBounds) const
{
  auto rec = BicubicPatch::buffers(uvBounds);

  auto ptsBuffer = factory->makeRenderBuffer(
      rive::RenderBufferType::vertex,
      rive::RenderBufferFlags::none,
      rec.pts.size() * sizeof(rive::Vec2D));
  if (ptsBuffer)
  {
    void* ptsData = ptsBuffer->map();
    memcpy(ptsData, rec.pts.data(), ptsBuffer->sizeInBytes());
    ptsBuffer->unmap();
  }

  auto uvsBuffer = factory->makeRenderBuffer(
      rive::RenderBufferType::vertex,
      rive::RenderBufferFlags::mappedOnceAtInitialization,
      rec.uvs.size() * sizeof(rive::Vec2D));
  if (uvsBuffer)
  {
    void* uvsData = uvsBuffer->map();
    memcpy(uvsData, rec.uvs.data(), uvsBuffer->sizeInBytes());
    uvsBuffer->unmap();
  }

  auto idxBuffer = factory->makeRenderBuffer(
      rive::RenderBufferType::index,
      rive::RenderBufferFlags::mappedOnceAtInitialization,
      rec.indices.size() * sizeof(uint16_t));
  if (idxBuffer)
  {
    void* idxData = idxBuffer->map();
    memcpy(idxData, rec.indices.data(), idxBuffer->sizeInBytes());
    idxBuffer->unmap();
  }

  return {std::move(ptsBuffer), std::move(uvsBuffer), std::move(idxBuffer)};
}
