/*
 * 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(const char* tag) :
        GM(1800, 2100, (std::string("feather_") + tag).c_str())
    {
        m_paint = TestingWindow::Get()->factory()->makeRenderPaint();
        m_paint->color(0xffffffff);
    }

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

    void onDraw(Renderer* renderer) override
    {
        renderer->scale(1.5f, 1.5f);
        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:
    FeatherShapesGM(const char* tag = "shapes") : FeatherGM(tag) {}

    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() 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(RenderPath* path, const Mat2D& transform) override
        {
            auto shape = static_cast<Shape*>(path);
            m_path->addRenderPath(shape->renderPath(), transform);
            m_pen = shape->m_pen;
            m_begin = shape->m_begin;
        }

    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(return new FeatherShapesGM)

// Validate corners by tessellating shapes into polygons and then feathering
// them.
class FeatherPolyShapesGM : public FeatherShapesGM
{
public:
    FeatherPolyShapesGM() : FeatherShapesGM("polyshapes") {}

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(return new FeatherPolyShapesGM)

// Check that corners don't have artifacts.
class FeatherCornerGM : public FeatherGM
{
public:
    FeatherCornerGM() : FeatherGM("corner") {}

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(return new FeatherCornerGM)

// Check that tightly rounded corners don't have artifacts.
class FeatherRoundCornerGM : public FeatherGM
{
public:
    FeatherRoundCornerGM() : FeatherGM("roundcorner") {}

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(return new FeatherRoundCornerGM)

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

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(return new FeatherEllipseGM)

// Check that a non-degenerate cubic cusps and near-cusps don't have artifacts.
class FeatherCuspGM : public FeatherGM
{
public:
    FeatherCuspGM() : FeatherGM("cusp") {}

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(return new FeatherCuspGM)

// Check that basic strokes feather correctly (enough).
class FeatherStrokesGM : public FeatherGM
{
public:
    FeatherStrokesGM() : FeatherGM("strokes")
    {
        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(return new FeatherStrokesGM)
} // namespace rive::gpu
