#include "rive/shapes/clipping_shape.hpp"
#include "rive/artboard.hpp"
#include "rive/core_context.hpp"
#include "rive/node.hpp"
#include "rive/renderer.hpp"
#include "rive/shapes/path_composer.hpp"
#include "rive/shapes/shape.hpp"

using namespace rive;

StatusCode ClippingShape::onAddedClean(CoreContext* context)
{
    auto clippingHolder = parent();

    auto artboard = static_cast<Artboard*>(context);
    for (auto core : artboard->objects())
    {
        if (core == nullptr)
        {
            continue;
        }
        // Iterate artboard to find drawables that are parented to this clipping
        // shape, they need to know they'll be clipped by this shape.
        if (core->is<Drawable>())
        {
            auto drawable = core->as<Drawable>();
            for (ContainerComponent* component = drawable; component != nullptr;
                 component = component->parent())
            {
                if (component == clippingHolder)
                {
                    drawable->addClippingShape(this);
                    break;
                }
            }
        }

        // Iterate artboard to find shapes that are parented to the source,
        // their paths will need to be RenderPaths in order to be used for
        // clipping operations.
        if (core->is<Shape>() && core != clippingHolder)
        {
            auto component = core->as<ContainerComponent>();
            while (component != nullptr)
            {
                if (component == m_Source)
                {
                    auto shape = core->as<Shape>();
                    shape->addDefaultPathSpace(PathSpace::World |
                                               PathSpace::Clipping);
                    m_Shapes.push_back(shape);
                    break;
                }
                component = component->parent();
            }
        }
    }

    m_RenderPath = rive::makeRenderPath();

    return StatusCode::Ok;
}

StatusCode ClippingShape::onAddedDirty(CoreContext* context)
{
    StatusCode code = Super::onAddedDirty(context);
    if (code != StatusCode::Ok)
    {
        return code;
    }
    auto coreObject = context->resolve(sourceId());
    if (coreObject == nullptr || !coreObject->is<Node>())
    {
        return StatusCode::MissingObject;
    }

    m_Source = reinterpret_cast<Node*>(coreObject);

    return StatusCode::Ok;
}

void ClippingShape::buildDependencies()
{
    for (auto shape : m_Shapes)
    {
        shape->pathComposer()->addDependent(this);
    }
}

static Mat2D identity;
void ClippingShape::update(ComponentDirt value)
{
    if (hasDirt(value, ComponentDirt::Path | ComponentDirt::WorldTransform))
    {
        m_RenderPath->reset();

        m_RenderPath->fillRule((FillRule)fillRule());
        for (auto shape : m_Shapes)
        {
            if (!shape->isHidden())
            {
                m_RenderPath->addPath(shape->pathComposer()->worldPath(),
                                      identity);
            }
        }
    }
}

ClippingShape::~ClippingShape() { delete m_RenderPath; }