#include "rive/shapes/clipping_shape.hpp"
#include "rive/artboard.hpp"
#include "rive/core_context.hpp"
#include "rive/factory.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();
            }
        }
    }

    // We only need a render path if we have more than 1 clip path as we join them.
    if (m_Shapes.size() > 1)
    {
        m_RenderPath = artboard->factory()->makeEmptyRenderPath();
    }

    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 = static_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))
    {
        if (m_RenderPath)
        {
            m_RenderPath->reset();

            m_RenderPath->fillRule((FillRule)fillRule());
            m_ClipRenderPath = nullptr;
            for (auto shape : m_Shapes)
            {
                if (!shape->isHidden())
                {
                    m_RenderPath->addPath(shape->pathComposer()->worldPath(), identity);
                    m_ClipRenderPath = m_RenderPath.get();
                }
            }
        }
        else
        {
            auto first = m_Shapes.front();
            if (first->isHidden())
            {
                m_ClipRenderPath = nullptr;
            }
            else
            {
                m_ClipRenderPath = first->pathComposer()->worldPath()->renderPath();
            }
        }
    }
}
