/*
 * Copyright 2026 Rive
 */

#include "gm.hpp"
#include "gmutils.hpp"
#include "rive/math/math_types.hpp"
#include "rive/renderer.hpp"
#include "common/rand.hpp"

using namespace rivegm;
using namespace rive;

namespace
{

static void drawStripedBackground(rive::Renderer* renderer, int32_t dim)
{
  {
    Paint p;
    p->color(0xff000000);
    renderer->drawPath(
        PathBuilder::Rect({0.0f, 0.0f, float(dim), float(dim)}),
        p);
  }
  {
    Paint p;
    p->color(0xff2c1642);
    p->feather(10.0f);
    auto yStep = 40.0f;
    for (auto y = 20.0f; y < float(dim); y++)
    {
      auto path = PathBuilder::Rect({
          -100.0f,
          y,
          float(dim) + 100.0f,
          y + yStep * 0.3f,
      });
      path->fillRule(FillRule::clockwise);
      renderer->drawPath(path, p);
      y += yStep;
      yStep *= 1.12f;
    }
  }
}

class ClipStrokeGM : public GM
{
public:
  static constexpr int32_t SectionSize = 400;
  static constexpr int32_t Spacing = 50;
  static constexpr int32_t RoundRadius = 50;
  static constexpr int32_t SectionCount = 3;
  static constexpr int32_t ImageDim = SectionCount * SectionSize;

  ClipStrokeGM() : GM(ImageDim, ImageDim) {}

  void onDraw(rive::Renderer* renderer) override
  {
    drawStripedBackground(renderer, ImageDim);

    constexpr uint32_t Colors[SectionCount][SectionCount] = {
        {
            0xff881177,
            0xffeedd00,
            0xff00bbcc,
        },
        {
            0xffaa3355,
            0xff99dd55,
            0xffee9944,
        },
        {
            0xffcc6666,
            0xff3366bb,
            0xff22ccbb,
        },
    };
    for (auto yIndex = 0; yIndex < 3; yIndex++)
    {
      for (auto xIndex = 0; xIndex < 3; xIndex++)
      {
        renderer->save();
        {
          const auto box = AABB{
              float(SectionSize * xIndex + Spacing / 2),
              float(SectionSize * yIndex + Spacing / 2),
              float(SectionSize * (xIndex + 1) - Spacing / 2),
              float(SectionSize * (yIndex + 1) - Spacing / 2),
          };
          auto clipper = PathBuilder::RRect(
              box,
              float(RoundRadius),
              float(RoundRadius));
          renderer->clipStroke(
              clipper,
              {.thickness = float(yIndex * 3 + xIndex + 1) * 3.0f});

          Paint p;
          p->color(Colors[xIndex][yIndex]);

          const auto dim = float(SectionCount * SectionSize) * 0.5f;
          auto path = PathBuilder::Circle(dim, dim, dim * 0.8f);
          path->fillRule(FillRule::clockwise);
          renderer->drawPath(path, p);
        }
        renderer->restore();
      }
    }
  }
};

enum class NestType
{
  pathInStroke,
  strokeInPath,
  strokeInStroke,
};

template <NestType N> class ClipStrokeNestedGM : public GM
{
public:
  static constexpr int32_t SectionSize = 400;
  static constexpr int32_t Spacing = 50;
  static constexpr int32_t RoundRadius = 50;
  static constexpr int32_t SectionCount = 3;
  static constexpr int32_t ImageDim = SectionCount * SectionSize;

  ClipStrokeNestedGM() : GM(ImageDim, ImageDim) {}

  void onDraw(rive::Renderer* renderer) override
  {
    {
      Paint p;
      p->color(0xff000000);
      renderer->drawPath(
          PathBuilder::Rect({0.0f, 0.0f, float(ImageDim), float(ImageDim)}),
          p);
    }
    {
      Paint p;
      p->color(0xff2c1642);
      p->feather(10.0f);
      auto yStep = 40.0f;
      for (auto y = 20.0f; y < float(SectionCount * SectionSize); y++)
      {
        auto path = PathBuilder::Rect({
            -100.0f,
            y,
            float(ImageDim) + 100.0f,
            y + yStep * 0.3f,
        });
        path->fillRule(FillRule::clockwise);
        renderer->drawPath(path, p);
        y += yStep;
        yStep *= 1.12f;
      }
    }
    constexpr uint32_t Colors[] = {
        0xffeedd00,
        0xffee9944,
        0xffcc6666,
        0xffaa3355,
        0xff881177,
        0xff3366bb,
        0xff00bbcc,
        0xff22ccbb,
        0xff99dd55,
    };

    const auto dim = float(SectionCount * SectionSize) * 0.5f;
    auto outerPath = PathBuilder::Circle(dim, dim, dim * 0.8f);

    constexpr auto CircleDiameter = 100;
    constexpr auto CircleSpacing = 20;
    constexpr auto CircleRadius = float(CircleDiameter) * 0.5f;
    auto innerCircle = PathBuilder::Circle(
        CircleRadius,
        CircleRadius,
        CircleRadius);

    renderer->save();
    {
      if constexpr (N == NestType::strokeInPath)
      {
        renderer->clipPath(outerPath);
      }
      else
      {
        renderer->clipStroke(outerPath, {.thickness = 200.0f});
      }

      for (auto yIndex = 0; yIndex < 3; yIndex++)
      {
        for (auto xIndex = 0; xIndex < 3; xIndex++)
        {
          renderer->save();
          {
            const auto box = AABB{
                float(SectionSize * xIndex + Spacing / 2),
                float(SectionSize * yIndex + Spacing / 2),
                float(SectionSize * (xIndex + 1) - Spacing / 2),
                float(SectionSize * (yIndex + 1) - Spacing / 2),
            };
            auto clipper = PathBuilder::RRect(
                box,
                float(RoundRadius),
                float(RoundRadius));

            if constexpr (N == NestType::pathInStroke)
            {
              renderer->clipPath(clipper);
            }
            else
            {
              renderer->clipStroke(clipper, {.thickness = 20.0f});
            }

            auto colorIndex = 0u;
            for (auto y = 5; y < ImageDim; y += CircleDiameter + CircleSpacing)
            {
              for (auto x = 5; x < ImageDim;
                   x += CircleDiameter + CircleSpacing)
              {
                Paint p;
                p->color(Colors[colorIndex % std::size(Colors)]);
                colorIndex++;
                renderer->save();
                {
                  renderer->translate(x, y);
                  renderer->drawPath(innerCircle, p);
                }
                renderer->restore();
              }
            }
          }

          renderer->restore();
        }
      }
    }
    renderer->restore();
  }
};

class ClipStrokeOpenGM : public GM
{
public:
  static constexpr int32_t SectionSize = 400;
  static constexpr int32_t SectionCount = 3;
  static constexpr int32_t ImageDim = SectionCount * SectionSize;
  static constexpr int32_t StrokeWidth = 50.0f;

  ClipStrokeOpenGM() : GM(ImageDim, ImageDim) {}

  void onDraw(rive::Renderer* renderer) override
  {
    Path clipper = PathBuilder()
                       .addPolygon(
                           std::vector{
                               Vec2D{StrokeWidth, StrokeWidth},
                               Vec2D{SectionSize - StrokeWidth, StrokeWidth},
                               Vec2D{
                                   SectionSize - StrokeWidth,
                                   SectionSize - StrokeWidth},
                               Vec2D{StrokeWidth, SectionSize - StrokeWidth}},
                           false)
                       .detach();

    drawStripedBackground(renderer, ImageDim);

    constexpr uint32_t Colors[SectionCount][SectionCount] = {
        {
            0xff881177,
            0xffeedd00,
            0xff00bbcc,
        },
        {
            0xffaa3355,
            0xff99dd55,
            0xffee9944,
        },
        {
            0xffcc6666,
            0xff3366bb,
            0xff22ccbb,
        },
    };
    for (auto yIndex = 0; yIndex < SectionCount; yIndex++)
    {
      for (auto xIndex = 0; xIndex < SectionCount; xIndex++)
      {
        renderer->save();
        {
          const auto tX = float(SectionSize * xIndex);
          const auto tY = float(SectionSize * yIndex);
          renderer->translate(tX, tY);
          renderer->clipStroke(
              clipper,
              {
                  .thickness = StrokeWidth,
                  .join = StrokeJoin(xIndex),
                  .cap = StrokeCap(yIndex),
              });

          Paint p;
          p->color(Colors[xIndex][yIndex]);

          renderer->translate(-tX, -tY);

          const auto dim = float(SectionCount * SectionSize) * 0.5f;
          auto path = PathBuilder::Circle(dim, dim, dim * 5.0f);
          path->fillRule(FillRule::clockwise);
          renderer->drawPath(path, p);
        }
        renderer->restore();
      }
    }
  }
};
} // namespace

GMREGISTER(clip_stroke_basic, return (new ClipStrokeGM()))
GMREGISTER(
    clip_stroke_nested_a,
    return (new ClipStrokeNestedGM<NestType::pathInStroke>()))
GMREGISTER(
    clip_stroke_nested_b,
    return (new ClipStrokeNestedGM<NestType::strokeInPath>()))
GMREGISTER(
    clip_stroke_nested_c,
    return (new ClipStrokeNestedGM<NestType::strokeInStroke>()))
GMREGISTER(clip_stroke_open, return (new ClipStrokeOpenGM()))

DEF_SIMPLE_GM(clip_stroke_position, 768, 768, renderer)
{
  drawStripedBackground(renderer, 768);

  Path path = PathBuilder::Circle(128.0f, 128.0f, 100.0f);
  path->fillRule(FillRule::clockwise);

  Path otherClip = PathBuilder::Polygon(
      {Vec2D{-30.0f, 226.0f},
       Vec2D{226.0f, -30.0f},
       Vec2D{286.0f, 30.0f},
       Vec2D{30.0f, 286.0f}},
      true,
      FillRule::clockwise);

  Path fillA = PathBuilder::RRect({30.0f, 30.0f, 226.0f, 226.0f}, 50.0f, 50.0f);
  Path fillB = PathBuilder::RRect({40.0f, 40.0f, 216.0f, 216.0f}, 50.0f, 50.0f);

  for (auto nestIndex = 0; nestIndex < 3; nestIndex++)
  {
    renderer->save();

    renderer->translate(0.0f, nestIndex * 256.0f);

    for (auto i = 0; i < 3; i++)
    {
      renderer->save();
      {
        if (nestIndex == 1)
        {
          // nest 1 is "positioned clip stroke inside of fill"
          renderer->clipPath(otherClip);
        }

        renderer->clipStroke(
            path,
            {.thickness = 20.0f, .position = StrokePosition(i)});

        if (nestIndex == 2)
        {
          // nest 1 is "fill inside of positioned clip stroke"
          renderer->clipPath(otherClip);
        }

        Paint p;
        p->color(0xffaa3355);
        p->style(RenderPaintStyle::fill);
        renderer->drawPath(fillA, p);
        p->color(0xff00bbcc);
        renderer->drawPath(fillB, p);
      }
      renderer->restore();

      renderer->translate(256.0f, 0.0f);
    }

    renderer->restore();
  }
}
