#include "rive/shapes/path_composer.hpp"
#include "rive/artboard.hpp"
#include "rive/renderer.hpp"
#include "rive/shapes/path.hpp"
#include "rive/shapes/shape.hpp"
#include "rive/factory.hpp"

using namespace rive;

PathComposer::PathComposer(Shape* shape) :
    m_shape(shape), m_deferredPathDirt(false)
{}

void PathComposer::buildDependencies()
{
    assert(m_shape != nullptr);
    m_shape->addDependent(this);
    for (auto path : m_shape->paths())
    {
        path->addDependent(this);
    }
}

void PathComposer::onDirty(ComponentDirt dirt)
{
    if (m_deferredPathDirt)
    {
        // We'd deferred the update, let's make sure the rest of our
        // dependencies update too. Constraints need to update too, stroke
        // effects, etc.
        m_shape->pathChanged();
    }
}

void PathComposer::update(ComponentDirt value)
{
    if (hasDirt(value, ComponentDirt::Path | ComponentDirt::NSlicer))
    {
        if (m_shape->canDeferPathUpdate())
        {
            m_deferredPathDirt = true;
            return;
        }
        m_deferredPathDirt = false;

        if (m_shape->isFlagged(PathFlags::local))
        {
            if (m_localPath == nullptr)
            {
                m_localPath = artboard()->factory()->makeEmptyRenderPath();
            }
            else
            {
                m_localPath->rewind();
                m_localRawPath.rewind();
            }
            auto world = m_shape->worldTransform();
            Mat2D inverseWorld = world.invertOrIdentity();
            // Get all the paths into local shape space.
            for (auto path : m_shape->paths())
            {
                if (!path->isHidden() && !path->isCollapsed())
                {
                    const auto localTransform =
                        inverseWorld * path->pathTransform();
                    m_localRawPath.addPath(path->rawPath(), &localTransform);
                }
            }

            // TODO: add a CommandPath::copy(RawPath)
            m_localRawPath.addTo(m_localPath.get());
        }
        if (m_shape->isFlagged(PathFlags::world))
        {
            if (m_worldPath == nullptr)
            {
                m_worldPath = artboard()->factory()->makeEmptyRenderPath();
            }
            else
            {
                m_worldPath->rewind();
                m_worldRawPath.rewind();
            }
            for (auto path : m_shape->paths())
            {
                if (!path->isHidden() && !path->isCollapsed())
                {
                    const Mat2D& transform = path->pathTransform();
                    m_worldRawPath.addPath(path->rawPath(), &transform);
                }
            }

            // TODO: add a CommandPath::copy(RawPath)
            m_worldRawPath.addTo(m_worldPath.get());
        }
        m_shape->markBoundsDirty();
    }
}

// Instead of adding dirt and rely on the recursive behavior of the addDirt
// method, we need to explicitly add dirt to the dependents. The reason is that
// a collapsed shape will not clear its dirty path flag in the current frame
// since it is collapsed. So in a future frame if it is uncollapsed, we mark its
// path flag as dirty again, but since it was already dirty, the recursive part
// will not kick in and the dependents won't update. This scenario is not
// common, but it can happen when a solo toggles between an empty group and a
// path for example.
void PathComposer::pathCollapseChanged()
{
    addDirt(ComponentDirt::Path);
    for (auto d : dependents())
    {
        d->addDirt(ComponentDirt::Path, true);
    }
}