/*
 * Copyright 2011 Google Inc.
 * Copyright 2022 Rive
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

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

using namespace rivegm;
using namespace rive;

#define W 400
#define H 400
#define N 50

constexpr float SW = static_cast<float>(W);
constexpr float SH = static_cast<float>(H);

static void rnd_rect(AABB* r, RenderPaint* paint, Rand& rand)
{
  float x = (static_cast<int32_t>(rand.u32() >> 16)) * 1.52587890625e-5f * W;
  float y = (static_cast<int32_t>(rand.u32() >> 16)) * 1.52587890625e-5f * H;
  float w = (static_cast<int32_t>(rand.u32() >> 16)) * 1.52587890625e-5f *
            (W >> 2);
  float h = (static_cast<int32_t>(rand.u32() >> 16)) * 1.52587890625e-5f *
            (H >> 2);
  float hoffset =
      (static_cast<int32_t>(static_cast<int32_t>(rand.u32()) >> 15) *
       1.52587890625e-5f);
  float woffset =
      (static_cast<int32_t>(static_cast<int32_t>(rand.u32()) >> 15) *
       1.52587890625e-5f);

  r->minX = x;
  r->minY = y;
  r->maxX = x + w;
  r->maxY = y + h;
  *r = r->offset(-w / 2 + woffset, -h / 2 + hoffset);

  paint->color(rand.u32());
  // paint->setAlphaf(1.0f);
}

class StrokesGM : public GM
{
public:
  StrokesGM() : GM(W, H) {}

protected:
  void onDraw(Renderer* renderer) override
  {
    Paint paint;
    paint->style(RenderPaintStyle::stroke);
    paint->thickness(static_cast<float>(9) / 2);

    renderer->save();
    renderer->clipPath(PathBuilder::Rect(
        {static_cast<float>(2),
         static_cast<float>(2),
         SW - static_cast<float>(2),
         SH - static_cast<float>(2)}));

    Rand rand;
    for (int i = 0; i < N; i++)
    {
      AABB r;
      rnd_rect(&r, paint, rand);
      renderer->drawPath(PathBuilder::Oval(r), paint);
      rnd_rect(&r, paint, rand);
      renderer->drawPath(
          PathBuilder::RRect(r, r.width() / 4, r.height() / 4),
          paint);
      rnd_rect(&r, paint, rand);
    }
    renderer->restore();
  }
};

/* See
   https://code.google.com/p/chromium/issues/detail?id=422974          and
   http://jsfiddle.net/1xnku3sg/2/
 */
class ZeroLenStrokesGM : public GM
{
public:
  ZeroLenStrokesGM() : GM(W * 3 / 7, H * 3 / 4) {}

private:
  Path fMoveHfPath, fMoveZfPath, /* fDashedfPath, */ fRefPath[4];
  Path fCubicPath, fQuadPath, fLinePath;

protected:
  void onOnceBeforeDraw() override
  {
    // SkAssertResult(SkParsePath::FromSVGString("M0,0h0M10,0h0M20,0h0",
    // &fMoveHfPath));
    // SkAssertResult(SkParsePath::FromSVGString("M0,0zM10,0zM20,0z",
    // &fMoveZfPath)); SkAssertResult(SkParsePath::FromSVGString("M0,0h25",
    // &fDashedfPath)); SkAssertResult(SkParsePath::FromSVGString("M 0 0 C 0
    // 0 0 0 0 0", &fCubicPath));
    // SkAssertResult(SkParsePath::FromSVGString("M 0 0 Q 0 0 0 0",
    // &fQuadPath)); SkAssertResult(SkParsePath::FromSVGString("M 0 0 L 0
    // 0", &fLinePath));
    fMoveHfPath = PathBuilder()
                      .moveTo(0, 0)
                      .lineTo(0, 0)
                      .moveTo(10, 0)
                      .lineTo(10, 0)
                      .moveTo(20, 0)
                      .lineTo(20, 0)
                      .detach();
    fMoveZfPath = PathBuilder()
                      .moveTo(0, 0)
                      .close()
                      .moveTo(10, 0)
                      .close()
                      .moveTo(20, 0)
                      .close()
                      .detach();
    fCubicPath = PathBuilder().moveTo(0, 0).cubicTo(0, 0, 0, 0, 0, 0).detach();
    fQuadPath = PathBuilder().moveTo(0, 0).quadTo(0, 0, 0, 0).detach();
    fLinePath = PathBuilder().moveTo(0, 0).lineTo(0, 0).detach();

    PathBuilder b[4];
    for (int i = 0; i < 3; ++i)
    {
      b[0].addOval({i * 10.f - 5, 0 - 5, i * 10.f + 5, 0 + 5});
      b[1].addOval({i * 10.f - 10, 0 - 10, i * 10.f + 10, 0 + 10});
      b[2].addRect({i * 10.f - 4, -2, i * 10.f + 4, 6});
      b[3].addRect({i * 10.f - 10, -10, i * 10.f + 10, 10});
    }
    for (int i = 0; i < 4; ++i)
    {
      fRefPath[i] = b[i].detach();
    }
  }

  void onDraw(Renderer* renderer) override
  {
    Paint fillPaint, strokePaint; // , dashPaint;
    strokePaint->style(RenderPaintStyle::stroke);
    StrokeCap caps[3] = {StrokeCap::round, StrokeCap::square, StrokeCap::butt};
    for (int i = 0; i < 3; ++i)
    {
      fillPaint->color(0xff000000);
      strokePaint->color(0xff000000);
      strokePaint->thickness(i ? 8.f : 10.f);
      strokePaint->cap(caps[i]);
      renderer->save();
      renderer->translate(10 + i * 100.f, 10);
      renderer->drawPath(fMoveHfPath, strokePaint);
      renderer->translate(0, 20);
      renderer->drawPath(fMoveZfPath, strokePaint);
#if 0
            dashPaint = strokePaint;
            const float intervals[] = {0, 10};
            dashPaint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
            SkPath fillPath;
            dashPaint.getFillPath(fDashedfPath, &fillPath);
            canvas->translate(0, 20);
            canvas->drawPath(fDashedfPath, dashPaint);
#endif
      renderer->translate(0, 20);
      renderer->drawPath(fRefPath[i * 2], fillPaint);
      strokePaint->thickness(20);
      strokePaint->color(0x80000000);
      renderer->translate(0, 50);
      renderer->drawPath(fMoveHfPath, strokePaint);
      renderer->translate(0, 30);
      renderer->drawPath(fMoveZfPath, strokePaint);
      renderer->translate(0, 30);
      fillPaint->color(0x80000000);
      renderer->drawPath(fRefPath[1 + i * 2], fillPaint);
      renderer->translate(0, 30);
      renderer->drawPath(fCubicPath, strokePaint);
      renderer->translate(0, 30);
      renderer->drawPath(fQuadPath, strokePaint);
      renderer->translate(0, 30);
      renderer->drawPath(fLinePath, strokePaint);
      renderer->restore();
    }
  }
};

class TeenyStrokesGM : public GM
{
public:
  TeenyStrokesGM() : GM(W, H * .5) {}

private:
  static void line(float scale, Renderer* canvas, ColorInt color)
  {
    Paint p;
    p->style(RenderPaintStyle::stroke);
    p->color(color);
    canvas->translate(50, 0);
    canvas->save();
    p->thickness(scale * 5);
    canvas->scale(1 / scale, 1 / scale);
    // canvas->drawLine(20 * scale, 20 * scale, 20 * scale, 100 * scale, p);
    // canvas->drawLine(20 * scale, 20 * scale, 100 * scale, 100 * scale,
    // p);
    canvas->drawPath(
        PathBuilder()
            .moveTo(20 * scale, 20 * scale)
            .lineTo(20 * scale, 100 * scale)
            .detach(),
        p);
    canvas->drawPath(
        PathBuilder()
            .moveTo(20 * scale, 20 * scale)
            .lineTo(100 * scale, 100 * scale)
            .detach(),
        p);
    canvas->restore();
  }

  void onDraw(Renderer* canvas) override
  {
    line(0.00005f, canvas, 0xff000000);
    line(0.000045f, canvas, 0xffff0000);
    line(0.0000035f, canvas, 0xff00ff00);
    line(0.000003f, canvas, 0xff0000ff);
    line(0.000002f, canvas, 0xff000000);
  }
};

DEF_SIMPLE_GM(CubicStroke, 384, 384, canvas)
{
  Paint p;
  p->style(RenderPaintStyle::stroke);
  p->thickness(1.0720f);
  Path path;
  path->moveTo(-6000, -6000);
  path->cubicTo(-3500, 5500, -500, 5500, 2500, -6500);
  canvas->drawPath(path, p);
  p->thickness(1.0721f);
  canvas->translate(10, 10);
  canvas->drawPath(path, p);
  p->thickness(1.0722f);
  canvas->translate(10, 10);
  canvas->drawPath(path, p);
}

DEF_SIMPLE_GM(zerolinestroke, 90, 120, canvas)
{
  Paint paint;
  paint->style(RenderPaintStyle::stroke);
  paint->thickness(20);
  paint->cap(StrokeCap::round);

  Path path;
  path->moveTo(30, 90);
  path->lineTo(30, 90);
  path->lineTo(60, 90);
  path->lineTo(60, 90);
  canvas->drawPath(path, paint);

  path = Path();
  path->moveTo(30, 30);
  path->lineTo(60, 30);
  canvas->drawPath(path, paint);

  path = Path();
  path->moveTo(30, 60);
  path->lineTo(30, 60);
  path->lineTo(60, 60);
  canvas->drawPath(path, paint);
}

DEF_SIMPLE_GM(quadcap, 70, 30, canvas)
{
  canvas->translate(-100, 5);

  Paint p;
  p->style(RenderPaintStyle::stroke);
  p->thickness(1);
  PathBuilder b;
  Vec2D pts[] = {
      {105.738571f, 13.126318f},
      {105.738571f, 13.126318f},
      {123.753784f, 1.f}};
  Vec2D tangent = pts[1] - pts[2];
  tangent = tangent.normalized();
  Vec2D pts2[3];
  memcpy(pts2, pts, sizeof(pts));
  const float capOutset = rive::math::PI / 8;
  pts2[0].x += tangent.x * capOutset;
  pts2[0].y += tangent.y * capOutset;
  pts2[1].x += tangent.x * capOutset;
  pts2[1].y += tangent.y * capOutset;
  pts2[2].x += -tangent.x * capOutset;
  pts2[2].y += -tangent.y * capOutset;
  b.moveTo(pts2[0].x, pts2[0].y);
  b.quadTo(pts2[1].x, pts2[1].y, pts2[2].x, pts2[2].y);
  canvas->drawPath(b.detach(), p);

  b.moveTo(pts[0].x, pts[0].y);
  b.quadTo(pts[1].x, pts[1].y, pts[2].x, pts[2].y);
  p->cap(StrokeCap::round);
  canvas->translate(30, 0);
  canvas->drawPath(b.detach(), p);
}

class Strokes2GM : public GM
{
public:
  Strokes2GM() : GM(W, H) {}

private:
  Path fPath;

protected:
  void onOnceBeforeDraw() override
  {
    Rand rand;
    fPath->moveTo(0, 0);
    for (int i = 0; i < 13; i++)
    {
      float x = (static_cast<int32_t>(rand.u32() >> 16) * 1.52587890625e-5f) *
                (W >> 1);
      float y = (static_cast<int32_t>(rand.u32() >> 16) * 1.52587890625e-5f) *
                (H >> 1);
      fPath->lineTo(x, y);
    }
  }

  void onDraw(Renderer* canvas) override
  {
    Paint paint;
    paint->style(RenderPaintStyle::stroke);
    paint->thickness(static_cast<float>(9) / 2);

    canvas->save();
    canvas->clipPath(PathBuilder::Rect(
        {static_cast<float>(2),
         static_cast<float>(2),
         SW - static_cast<float>(2),
         SH - static_cast<float>(2)}));

    Rand rand;
    for (int i = 0; i < N / 2; i++)
    {
      AABB r;
      rnd_rect(&r, paint, rand);
      canvas->translate(SW / 2, SH / 2);
      canvas->transform(Mat2D::fromRotation(15 * math::PI / 180));
      canvas->translate(-SW / 2, -SH / 2);
      canvas->drawPath(fPath, paint);
    }
    canvas->restore();
  }
};

//////////////////////////////////////////////////////////////////////////////

static AABB inset(AABB r) { return r.inset(r.width() / 10, r.height() / 10); }

class Strokes3GM : public GM
{
  static void make0(PathBuilder* path, const AABB& bounds)
  {
    path->addRect(bounds, rivegm::PathDirection::cw);
    path->addRect(inset(bounds), rivegm::PathDirection::cw);
  }

  static void make1(PathBuilder* path, const AABB& bounds)
  {
    path->addRect(bounds, rivegm::PathDirection::cw);
    path->addRect(inset(bounds), rivegm::PathDirection::ccw);
  }

  static void make2(PathBuilder* path, const AABB& bounds)
  {
    path->addOval(bounds, rivegm::PathDirection::cw);
    path->addOval(inset(bounds), rivegm::PathDirection::cw);
  }

  static void make3(PathBuilder* path, const AABB& bounds)
  {
    path->addOval(bounds, rivegm::PathDirection::cw);
    path->addOval(inset(bounds), rivegm::PathDirection::ccw);
  }

  static void make4(PathBuilder* path, const AABB& bounds)
  {
    path->addRect(bounds, rivegm::PathDirection::cw);
    AABB r = bounds.inset(bounds.width() / 10, -bounds.height() / 10);
    path->addOval(r, rivegm::PathDirection::cw);
  }

  static void make5(PathBuilder* path, const AABB& bounds)
  {
    path->addRect(bounds, rivegm::PathDirection::cw);
    AABB r = bounds.inset(bounds.width() / 10, -bounds.height() / 10);
    path->addOval(r, rivegm::PathDirection::ccw);
  }

public:
  Strokes3GM() : GM(1500, 1500) {}

protected:
  void onDraw(Renderer* canvas) override
  {
    Paint origPaint;
    origPaint->style(RenderPaintStyle::stroke);
    // Paint fillPaint;
    // fillPaint->color(0xffff0000);
    Paint strokePaint;
    strokePaint->style(RenderPaintStyle::stroke);
    strokePaint->color(0xFF4444FF);

    void (*procs[])(
        PathBuilder*,
        const AABB&) = {make0, make1, make2, make3, make4, make5};

    canvas->translate(static_cast<float>(20), static_cast<float>(80));

    AABB bounds = {0, 0, static_cast<float>(50), static_cast<float>(50)};
    float dx = bounds.width() * 4 / 3;
    float dy = bounds.height() * 5;

    for (size_t i = 0; i < std::size(procs); ++i)
    {
      PathBuilder orig;
      procs[i](&orig, bounds);
      Path orig2 = orig.detach();

      canvas->save();
      for (int j = 0; j < 13; ++j)
      {
        float thickness = 1.0f * j * j;
        strokePaint->thickness(thickness);
        canvas->drawPath(orig2, strokePaint);
        canvas->drawPath(orig2, origPaint);
        // Path fill;
        // strokePaint.getFillPath(orig, &fill);
        // canvas->drawPath(fill, fillPaint);
        canvas->translate(dx + thickness, 0);
      }
      canvas->restore();
      canvas->translate(0, dy);
    }
  }
};

class Strokes4GM : public GM
{
public:
  Strokes4GM() : GM(W, H / 4) {}

protected:
  void onDraw(Renderer* canvas) override
  {
    Paint paint;
    paint->style(RenderPaintStyle::stroke);
    paint->thickness(0.055f);

    canvas->scale(1000, 1000);
    canvas->drawPath(
        PathBuilder::Oval({-1.97f, 2 - 1.97f, 1.97f, 2 + 1.97f}),
        paint);
  }
};

// Test stroking for curves that produce degenerate tangents when t is 0 or 1
// (see bug 4191)
class Strokes5GM : public GM
{
public:
  Strokes5GM() : GM(W, H) {}

protected:
  void onDraw(Renderer* canvas) override
  {
    Paint p;
    p->color(0xffff0000);
    p->style(RenderPaintStyle::stroke);
    p->thickness(40);
    p->cap(StrokeCap::butt);

    PathBuilder path;
    path.moveTo(157.474f, 111.753f);
    path.cubicTo(128.5f, 111.5f, 35.5f, 29.5f, 35.5f, 29.5f);
    canvas->drawPath(path.detach(), p);
    path.moveTo(250, 50);
    path.quadTo(280, 80, 280, 80);
    canvas->drawPath(path.detach(), p);
    path.moveTo(150, 50);
    path.quadTo(180, 80, 180, 80);
    canvas->drawPath(path.detach(), p);

    path.moveTo(157.474f, 311.753f);
    path.cubicTo(157.474f, 311.753f, 85.5f, 229.5f, 35.5f, 229.5f);
    canvas->drawPath(path.detach(), p);
    path.moveTo(280, 250);
    path.quadTo(280, 250, 310, 280);
    canvas->drawPath(path.detach(), p);
    path.moveTo(180, 250);
    path.quadTo(180, 250, 210, 280);
    canvas->drawPath(path.detach(), p);
  }
};

//////////////////////////////////////////////////////////////////////////////

GMREGISTER(strokes_round, return new StrokesGM;)
GMREGISTER(strokes_poly, return new Strokes2GM;)
GMREGISTER(strokes3, return new Strokes3GM;)
GMREGISTER(strokes_zoomed, return new Strokes4GM;)
GMREGISTER(zero_control_stroke, return new Strokes5GM;)

GMREGISTER(zeroPath, return new ZeroLenStrokesGM;)
GMREGISTER(teenyStrokes, return new TeenyStrokesGM;)

DEF_SIMPLE_GM(inner_join_geometry, 1000, 700, canvas)
{
  // These paths trigger cases where we must add inner join geometry.
  // skbug.com/11964
  const Vec2D pathPoints[] = {
      /*moveTo*/ /*lineTo*/ /*lineTo*/
      {119, 71},
      {129, 151},
      {230, 24},
      {200, 144},
      {129, 151},
      {230, 24},
      {192, 176},
      {224, 175},
      {281, 103},
      {233, 205},
      {224, 175},
      {281, 103},
      {121, 216},
      {234, 189},
      {195, 147},
      {141, 216},
      {254, 189},
      {238, 250},
      {159, 202},
      {269, 197},
      {289, 165},
      {159, 202},
      {269, 197},
      {287, 227},
  };

  Paint pathPaint;
  pathPaint->style(RenderPaintStyle::stroke);
  pathPaint->thickness(100);

#if 0
    Paint skeletonPaint;
    skeletonPaint->style(RenderPaintStyle::stroke);
    skeletonPaint->thickness(1);
    skeletonPaint->color(0xffff0000);
#endif

  canvas->translate(0, 50);
  for (size_t i = 0; i < std::size(pathPoints) / 3; i++)
  {
    // auto path = SkPath::Polygon(pathPoints + i * 3, 3, false);
    PathBuilder path;
    size_t j = i * 3;
    path.moveTo(pathPoints[j].x, pathPoints[j].y);
    path.lineTo(pathPoints[j + 1].x, pathPoints[j + 1].y);
    path.lineTo(pathPoints[j + 2].x, pathPoints[j + 2].y);
    canvas->drawPath(path.detach(), pathPaint);

#if 0
        SkPath fillPath;
        pathPaint.getFillPath(path, &fillPath);
        canvas->drawPath(fillPath, skeletonPaint);
#endif

    canvas->translate(200, 0);
    if ((i + 1) % 4 == 0)
    {
      canvas->translate(-800, 200);
    }
  }
}

DEF_SIMPLE_GM(skbug12244, 150, 150, canvas)
{
  // Should look like a stroked triangle; these vertices are the results of
  // the SkStroker but we draw as a filled path in order to highlight that
  // it's the GPU triangulating path renderer that's the source of the
  // problem, and not the stroking operation. The original path was a simple:
  // m(0,0), l(100, 40), l(0, 80), l(0,0) with a stroke width of 15px
  Path path;
  path->moveTo(2.7854299545288085938, -6.9635753631591796875);
  path->lineTo(120.194366455078125, 40);
  path->lineTo(-7.5000004768371582031, 91.07775115966796875);
  path->lineTo(-7.5000004768371582031, -11.077748298645019531);
  path->lineTo(2.7854299545288085938, -6.9635753631591796875);
  path->moveTo(-2.7854299545288085938, 6.9635753631591796875);
  path->lineTo(0, 0);
  path->lineTo(7.5, 0);
  path->lineTo(7.5000004768371582031, 68.92224884033203125);
  path->lineTo(79.805633544921875, 40);
  path->lineTo(-2.7854299545288085938, 6.9635753631591796875);

  Paint p;
  p->color(0xff00ff00);

  canvas->translate(20.f, 20.f);
  canvas->drawPath(path, p);
}

DEF_SIMPLE_GM(stroke_position, 768, 768, renderer)
{
  // Draw a black background
  {
    Paint p;
    p->color(0xff000000);
    renderer->drawPath(
        PathBuilder::Rect({0.0f, 0.0f, float(width()), float(height())}),
        p);
  }

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

  float featherSizes[] = {0.0f, 20.0f, 150.0f};
  for (auto feather = 0; feather < 3; feather++)
  {
    renderer->save();

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

    for (auto i = 0; i < 3; i++)
    {
      Paint p;
      p->color(0xFFEFEFEF);
      p->stroke({
          .thickness = 20.0f,
          .position = StrokePosition(i),
      });
      p->feather(featherSizes[feather]);
      renderer->drawPath(path, p);

      p->color(0x5f881177);
      p->style(RenderPaintStyle::fill);
      p->feather(0.0f);
      renderer->drawPath(path, p);
      renderer->translate(256.0f, 0.0f);
    }

    renderer->restore();
  }
}

DEF_SIMPLE_GM(stroke_position_clipped, 768, 768, renderer)
{
  // Draw a black background
  {
    Paint p;
    p->color(0xff000000);
    renderer->drawPath(
        PathBuilder::Rect({0.0f, 0.0f, float(width()), float(height())}),
        p);
  }

  Path clip = PathBuilder::RRect({0.0f, 64.0f, 256.0f, 192.0f}, 20.0f, 20.0f);

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

  float featherSizes[] = {0.0f, 20.0f, 150.0f};
  for (auto feather = 0; feather < 3; feather++)
  {
    renderer->save();

    renderer->translate(0.0f, feather * 256.0f);
    for (auto i = 0; i < 3; i++)
    {
      renderer->save();
      renderer->clipPath(clip);
      Paint p;
      p->color(0xFFEFEFEF);
      p->stroke({
          .thickness = 20.0f,
          .position = StrokePosition(i),
      });
      p->feather(featherSizes[feather]);
      renderer->drawPath(path, p);

      p->color(0x5f881177);
      p->style(RenderPaintStyle::fill);
      p->feather(0.0f);
      renderer->drawPath(path, p);
      renderer->restore();
      renderer->translate(256.0f, 0.0f);
    }

    renderer->restore();
  }
}
