#include <rive/clip_result.hpp>
#include <rive/file.hpp>
#include <rive/node.hpp>
#include <rive/shapes/clipping_shape.hpp>
#include <rive/shapes/rectangle.hpp>
#include <rive/shapes/shape.hpp>
#include <utils/no_op_renderer.hpp>
#include "rive_file_reader.hpp"
#include <catch.hpp>
#include <cstdio>

TEST_CASE("clipping loads correctly", "[clipping]")
{
    auto file = ReadRiveFile("../../test/assets/circle_clips.riv");

    auto node = file->artboard()->find("TopEllipse");
    REQUIRE(node != nullptr);
    REQUIRE(node->is<rive::Shape>());

    auto shape = node->as<rive::Shape>();
    REQUIRE(shape->clippingShapes().size() == 2);
    REQUIRE(shape->clippingShapes()[0]->source()->name() == "ClipRect2");
    REQUIRE(shape->clippingShapes()[1]->source()->name() == "BabyEllipse");

    file->artboard()->updateComponents();

    rive::NoOpRenderer renderer;
    file->artboard()->draw(&renderer);
}

class ClipTestRenderPath : public rive::RenderPath
{
public:
    rive::RawPath rawPath;
    ClipTestRenderPath(rive::RawPath& path) : rawPath(path) {}

    void rewind() override {}

    void fillRule(rive::FillRule value) override {}
    void addPath(rive::CommandPath* path, const rive::Mat2D& transform) override {}
    void addRenderPath(rive::RenderPath* path, const rive::Mat2D& transform) override {}

    void moveTo(float x, float y) override {}
    void lineTo(float x, float y) override {}
    void cubicTo(float ox, float oy, float ix, float iy, float x, float y) override {}
    void close() override {}
};

class ClippingFactory : public rive::NoOpFactory
{
    std::unique_ptr<rive::RenderPath> makeRenderPath(rive::RawPath& rawPath,
                                                     rive::FillRule) override
    {
        return rivestd::make_unique<ClipTestRenderPath>(rawPath);
    }
};

TEST_CASE("artboard is clipped correctly", "[clipping]")
{
    ClippingFactory factory;
    auto file = ReadRiveFile("../../test/assets/artboardclipping.riv", &factory);

    auto artboard = file->artboard("Center");
    REQUIRE(artboard != nullptr);
    artboard->updateComponents();
    REQUIRE(artboard->originX() == 0.5);
    REQUIRE(artboard->originY() == 0.5);
    {
        auto clipPath = static_cast<ClipTestRenderPath*>(artboard->clipPath());
        auto points = clipPath->rawPath.points();
        REQUIRE(points.size() == 4);

        REQUIRE(points[0] == rive::Vec2D(0.0f, 0.0f));
        REQUIRE(points[1] == rive::Vec2D(500.0f, 0.0f));
        REQUIRE(points[2] == rive::Vec2D(500.0f, 500.0f));
        REQUIRE(points[3] == rive::Vec2D(0.0f, 500.0f));
    }
    // Now disable framing the origin so that the points are in origin space.
    artboard->frameOrigin(false);
    artboard->updateComponents();
    {
        auto clipPath = static_cast<ClipTestRenderPath*>(artboard->clipPath());
        auto points = clipPath->rawPath.points();
        REQUIRE(points.size() == 4);

        REQUIRE(points[0] == rive::Vec2D(-250.0f, -250.0f));
        REQUIRE(points[1] == rive::Vec2D(250.0f, -250.0f));
        REQUIRE(points[2] == rive::Vec2D(250.0f, 250.0f));
        REQUIRE(points[3] == rive::Vec2D(-250.0f, 250.0f));
    }
}

TEST_CASE("Shape does not have any clipping paths visible", "[clipping]")
{
    ClippingFactory factory;
    auto file = ReadRiveFile("../../test/assets/clip_tests.riv", &factory);

    auto artboard = file->artboard("Empty-Shape");
    REQUIRE(artboard != nullptr);
    artboard->updateComponents();
    auto node = artboard->find("Ellipse-clipper");
    REQUIRE(node != nullptr);
    REQUIRE(node->is<rive::Shape>());
    rive::Shape* shape = static_cast<rive::Shape*>(node);
    REQUIRE(shape->isEmpty() == true);
    auto clippedNode = artboard->find("Rectangle-clipped");
    REQUIRE(clippedNode != nullptr);
    REQUIRE(clippedNode->is<rive::Shape>());
    rive::Shape* clippedShape = static_cast<rive::Shape*>(clippedNode);
    rive::NoOpRenderer renderer;
    auto clipResult = clippedShape->clip(&renderer);
    REQUIRE(clipResult == rive::ClipResult::emptyClip);
}

TEST_CASE("Shape has at least a clipping path visible", "[clipping]")
{
    ClippingFactory factory;
    auto file = ReadRiveFile("../../test/assets/clip_tests.riv", &factory);

    auto artboard = file->artboard("Hidden-Path-Visible-Path");
    REQUIRE(artboard != nullptr);
    artboard->updateComponents();
    auto node = artboard->find("Ellipse-clipper");
    REQUIRE(node != nullptr);
    REQUIRE(node->is<rive::Shape>());
    rive::Shape* shape = static_cast<rive::Shape*>(node);
    REQUIRE(shape->isEmpty() == false);
    auto clippedNode = artboard->find("Rectangle-clipped");
    REQUIRE(clippedNode != nullptr);
    REQUIRE(clippedNode->is<rive::Shape>());
    rive::Shape* clippedShape = static_cast<rive::Shape*>(clippedNode);
    rive::NoOpRenderer renderer;
    auto clipResult = clippedShape->clip(&renderer);
    REQUIRE(clipResult == rive::ClipResult::clip);
}

TEST_CASE("Shape returns an empty clip when one clipping shape is empty", "[clipping]")
{
    ClippingFactory factory;
    auto file = ReadRiveFile("../../test/assets/clip_tests.riv", &factory);

    auto artboard = file->artboard("One-Clipping-Shape-Visible-One-Hidden");
    REQUIRE(artboard != nullptr);
    artboard->updateComponents();
    auto node = artboard->find("Rectangle-clipped");
    REQUIRE(node != nullptr);
    REQUIRE(node->is<rive::Shape>());
    rive::Shape* shape = static_cast<rive::Shape*>(node);

    rive::NoOpRenderer renderer;
    auto clipResult = shape->clip(&renderer);
    REQUIRE(clipResult == rive::ClipResult::emptyClip);
}