/*
 * Copyright 2024 Rive
 */

#include "gm.hpp"
#include "gmutils.hpp"
#include "rive/math/bezier_utils.hpp"
#include "rive/math/math_types.hpp"
#include "rive/math/wangs_formula.hpp"

using namespace rivegm;

namespace rive::gpu
{
class FeatherGM : public GM
{
public:
  FeatherGM() : GM(1756, 2048)
  {
    m_paint = TestingWindow::Get()->factory()->makeRenderPaint();
    m_paint->color(0xffffffff);
  }

  ColorInt clearColor() const override { return 0xff000000; }

  void onDraw(Renderer* renderer) override
  {
    renderer->scale(1.463f, 1.463f);
    for (int y = 0; y < 7; ++y)
    {
      renderer->save();
      for (int x = 0; x < 6; ++x)
      {
        renderer->save();
        renderer->translate(50, 50);
        // For the y=0 case, this checks that epsilon size feathers
        // generate smooth AA.
        m_paint->feather(expf(y));
        drawCell(renderer, x, y, m_paint.get());
        renderer->restore();
        renderer->translate(200, 0);
      }
      renderer->restore();
      renderer->translate(0, 200);
    }
  }

private:
  virtual void drawCell(Renderer*, int x, int y, RenderPaint*) = 0;

  rcp<RenderPaint> m_paint;
};

// Check that basic shapes feather correctly (enough).
class FeatherShapesGM : public FeatherGM
{
public:
  void onOnceBeforeDraw() override
  {
    m_shapes.reserve(6);

    auto& square = m_shapes.emplace_back(makeShape());
    square->addRect(0, 0, 100, 100);

    auto& circle = m_shapes.emplace_back(makeShape());
    path_addOval(
        circle.get(),
        AABB{0, 0, 100, 100},
        rivegm::PathDirection::clockwise);

    auto shark = makeShape();
    shark->moveTo(376, 1422);
    shark->cubicTo(774, 526, 60, 660, 398, 329);
    shark->cubicTo(
        639.333374f,
        149.666656f,
        905.333313f,
        258.666656f,
        1196,
        656);
    shark->cubicTo(686, 460, 686, 660, 1370, 1006);
    // "cuspy" flat line with control points outside T=0..1.
    shark->cubicTo(
        1701.333374f,
        867.333374f,
        44.666626f,
        1560.666626f,
        376,
        1422);
    m_shapes.emplace_back(makeShape())
        ->addRenderPath(
            shark.get(),
            Mat2D().scale({.11f, .11f}).translate({-40, -38}));

    auto& cusp = m_shapes.emplace_back(makeShape());
    cusp->lineTo(100, 0);
    cusp->cubicTo(0, 100, 0, 0, 100, 100);
    cusp->lineTo(0, 100);
    cusp->cubicTo(50, 67, -50, 33, 0, 0);

    float r = 40;
    auto& rrect = m_shapes.emplace_back(makeShape());
    rrect->moveTo(r, 0);
    rrect->lineTo(100 - r, 0);
    rrect->cubicTo(100 - r / 2, 0, 100, r / 2, 100, r);
    rrect->lineTo(100, 100 - r);
    rrect->cubicTo(100, 100 - r / 5, 100 - r / 5, 100, 100 - r, 100);
    rrect->lineTo(r, 100);
    rrect->cubicTo(0 + r / 3, 100, 0, 100 - r / 3, 0, 100 - r);
    rrect->lineTo(0, r);
    rrect->cubicTo(0, 0, 0, 0, r, 0);

    auto& irrect = m_shapes.emplace_back(makeShape());
    irrect->addRenderPath(square.get(), Mat2D());
    irrect->addRenderPath(
        rrect.get(),
        Mat2D(-60.f / 100, 0, 0, 60.f / 100, 80, 20));
  }

protected:
  class Shape : public RenderPath
  {
  public:
    Shape() : m_path(FillRule::clockwise) {}

    RenderPath* renderPath() const override { return m_path.get(); }
    void rewind() override { m_path = Path(); }
    void fillRule(FillRule value) override { m_path->fillRule(value); }
    void moveTo(float x, float y) override
    {
      m_path->moveTo(x, y);
      m_begin = m_pen = {x, y};
    }
    void lineTo(float x, float y) override
    {
      m_path->lineTo(x, y);
      m_pen = {x, y};
    }
    void cubicTo(float ox, float oy, float ix, float iy, float x, float y)
        override
    {
      m_path->cubicTo(ox, oy, ix, iy, x, y);
      m_pen = {x, y};
    }
    void close() override
    {
      m_path->close();
      m_pen = m_begin;
    }
    void addRenderPath(const RenderPath* path, const Mat2D& transform) override
    {
      auto shape = static_cast<const Shape*>(path);
      m_path->addRenderPath(shape->renderPath(), transform);
      m_pen = shape->m_pen;
      m_begin = shape->m_begin;
    }

    void addRawPath(const RawPath& path) override { m_path->addRawPath(path); }

  protected:
    Path m_path;
    Vec2D m_pen = {0, 0};
    Vec2D m_begin = {0, 0};
  };

  virtual std::unique_ptr<Shape> makeShape()
  {
    return std::make_unique<Shape>();
  }

  void drawCell(Renderer* renderer, int x, int y, RenderPaint* paint) override
  {
    renderer->drawPath(m_shapes[x]->renderPath(), paint);
  }

  std::vector<std::unique_ptr<Shape>> m_shapes;
};
GMREGISTER(feather_shapes, return new FeatherShapesGM)

// Validate corners by tessellating shapes into polygons and then feathering
// them.
class FeatherPolyShapesGM : public FeatherShapesGM
{
private:
  class PolyShape : public Shape
  {
  public:
    void cubicTo(float ox, float oy, float ix, float iy, float x, float y)
        override
    {
      Vec2D p[4] = {m_pen, {ox, oy}, {ix, iy}, {x, y}};
      int n = wangs_formula::cubic(p, 8);
      n = std::max(n, 3);
      n = (n & ~1) + 1;
      math::EvalCubic ec(p);
      float dt = 2.f / n;
      float4 t = dt * float4{.5f, .5f, 1, 1};
      for (int i = 1; i < n; i += 2, t += dt)
      {
        float4 result = ec(t);
        Shape::lineTo(result.x, result.y);
        Shape::lineTo(result.z, result.w);
      }
      Shape::lineTo(x, y);
    }
  };

  virtual std::unique_ptr<Shape> makeShape()
  {
    return std::make_unique<PolyShape>();
  }
};
GMREGISTER(feather_polyshapes, return new FeatherPolyShapesGM)

// Check that corners don't have artifacts.
class FeatherCornerGM : public FeatherGM
{
private:
  virtual void drawCell(Renderer* renderer, int x, int y, RenderPaint* paint)
      override
  {
    float theta;
    if (x == 0)
    {
      theta = math::PI;
    }
    else if (x == 1)
    {
      theta = math::PI / 2;
    }
    else
    {
      theta = math::PI * powf((5 - x) / 5.f, 2.71828f);
    }
    renderer->clipPath(PathBuilder::Rect({-20, -20, 120, 120}));
    float left = 3 * math::PI;
    Vec2D v0 = Vec2D(cosf(left), sinf(left));
    Vec2D v1 = Vec2D(cosf(left - theta), sinf(left - theta));
    Path path(FillRule::clockwise);
    path->move(200 * v0 + Vec2D{0, 200});
    path->line(200 * v0);
    path->lineTo(0, 0);
    path->line(200 * v1);
    path->line(200 * v1 + Vec2D{0, 200});
    renderer->translate(50, 50);
    renderer->drawPath(path, paint);
  }
};
GMREGISTER(feather_corner, return new FeatherCornerGM)

// Check that tightly rounded corners don't have artifacts.
class FeatherRoundCornerGM : public FeatherGM
{
private:
  virtual void drawCell(Renderer* renderer, int x, int y, RenderPaint* paint)
      override
  {
    float theta = math::PI * powf((5 - x) / 5.f, 1.5f);
    renderer->clipPath(PathBuilder::Rect({-20, -20, 120, 120}));
    float down = math::PI / 2;
    Vec2D v0 = Vec2D(cosf(down + theta / 2), sinf(down + theta / 2));
    Vec2D v1 = Vec2D(cosf(down - theta / 2), sinf(down - theta / 2));
    Path path(FillRule::clockwise);
    path->move(200 * v0 + Vec2D{0, 200});
    path->line(200 * v0);
    path->line(75 * v0);
    path->cubic({0, 0}, {0, 0}, 75 * v1);
    path->line(200 * v1);
    path->line(200 * v1 + Vec2D{0, 200});
    renderer->translate(50, 50);
    renderer->drawPath(path, paint);
  }
};
GMREGISTER(feather_roundcorner, return new FeatherRoundCornerGM)

// Check that the cusp points on a squashed ellipse don't have artifacts.
class FeatherEllipseGM : public FeatherGM
{

private:
  virtual void drawCell(Renderer* renderer, int x, int y, RenderPaint* paint)
      override
  {
    auto unitCircle = PathBuilder::Circle(0, 0, 1);
    float squash = powf((5 - x) / 5.f, 2.71828f);
    Path ellipse(FillRule::clockwise);
    ellipse->addRenderPath(unitCircle, Mat2D::fromScale(50 * squash, 50));
    renderer->translate(50, 50);
    renderer->drawPath(ellipse, paint);
  }
};
GMREGISTER(feather_ellipse, return new FeatherEllipseGM)

// Check that a non-degenerate cubic cusps and near-cusps don't have artifacts.
class FeatherCuspGM : public FeatherGM
{
private:
  virtual void drawCell(Renderer* renderer, int x, int y, RenderPaint* paint)
      override
  {
    float dx = 10 * copysignf(powf(fabsf(x - 3.f), 1.75f), x - 3);
    Path cusp(FillRule::clockwise);
    cusp->moveTo(0, 100);
    cusp->moveTo(0, 100);
    cusp->cubicTo(100 + dx, 0, 0 - dx, 0, 100, 100);
    renderer->drawPath(cusp, paint);
  }
};
GMREGISTER(feather_cusp, return new FeatherCuspGM)

// Check that basic strokes feather correctly (enough).
class FeatherStrokesGM : public FeatherGM
{
public:
  FeatherStrokesGM() : FeatherGM()
  {
    m_strokes.reserve(6);

    auto& square = m_strokes.emplace_back();
    square->addRect(0, 0, 100, 100);

    m_strokes.emplace_back(PathBuilder::Circle(50, 50, 50));

    auto& serp = m_strokes.emplace_back();
    serp->moveTo(0, 100);
    serp->cubicTo(60, 0, 30, 0, 100, 100);

    auto& cusp = m_strokes.emplace_back();
    cusp->lineTo(100, 0);
    cusp->cubicTo(0, 100, 0, 0, 100, 100);
    cusp->lineTo(0, 100);
    cusp->cubicTo(50, 67, -50, 33, 0, 0);

    auto& loop = m_strokes.emplace_back();
    loop->moveTo(25, 100);
    loop->cubicTo(250, -20, -150, -20, 75, 100);

    auto& irrect = m_strokes.emplace_back();
    float r = 40;
    Path rrect;
    rrect->moveTo(r, 0);
    rrect->lineTo(100 - r, 0);
    rrect->cubicTo(100 - r / 2, 0, 100, r / 2, 100, r);
    rrect->lineTo(100, 100 - r);
    rrect->cubicTo(100, 100 - r / 5, 100 - r / 5, 100, 100 - r, 100);
    rrect->lineTo(r, 100);
    rrect->cubicTo(0 + r / 3, 100, 0, 100 - r / 3, 0, 100 - r);
    rrect->lineTo(0, r);
    rrect->cubicTo(0, 0, 0, 0, r, 0);
    irrect->addRenderPath(square, Mat2D());
    irrect->addRenderPath(rrect, Mat2D(-80.f / 100, 0, 0, 80.f / 100, 90, 10));
  }

private:
  virtual void drawCell(Renderer* renderer, int x, int y, RenderPaint* paint)
      override
  {
    paint->style(RenderPaintStyle::stroke);
    paint->thickness(15);
    // Feathers ignore the join.
    paint->join((y & 1) ? StrokeJoin::bevel : StrokeJoin::miter);
    // Feathers ignore the cap.
    paint->cap((y & 1) ? StrokeCap::square : StrokeCap::butt);
    renderer->drawPath(m_strokes[x].get(), paint);
  }

  std::vector<Path> m_strokes;
};
GMREGISTER(feather_strokes, return new FeatherStrokesGM)
} // namespace rive::gpu
