#include "rive/shapes/path_composer.hpp"
#include "rive/artboard.hpp"
#include "rive/renderer.hpp"
#include "rive/shapes/path.hpp"
#include <algorithm>
#include <limits>
#include "rive/shapes/shape.hpp"
#include "rive/factory.hpp"
#include "rive/shapes/points_path.hpp"

using namespace rive;

PathComposer::PathComposer(Shape* shape) :
    m_shape(shape),
    m_localPath(true),
    m_worldPath(false),
    m_localClockwisePath(true),
    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 && !m_shapeNotified)
    {
        // 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_shapeNotified = true;
        m_shape->pathChanged();
    }
}

// A local path is each path's geometry mapped by inverseShapeWorld *
// pathTransform -- the path's transform relative to the shape. A rigid move of
// the shape (or of any ancestor) leaves every one of those unchanged, so the
// local path it would rebuild is identical to the one it already holds.
// Rebuilding it anyway costs the copy and, worse, bumps the RenderPath's
// mutation id, which throws away its cached triangulation. Snapshot the inputs
// and compare.
bool PathComposer::localInputsChanged()
{
    auto& paths = m_shape->paths();
    const Mat2D& world = m_shape->worldTransform();
    const Mat2D inverseWorld = world.invertOrIdentity();
    // The composed transform is inverseWorld * pathTransform, and the error
    // in it is dominated by the inverse: its linear part scales the path's
    // coordinates, and inverting a shrunk-down world amplifies everything by
    // 1/det. So bound the tolerance by the terms that actually produce the
    // value rather than by the world transform alone.
    // 16 ULPs of the terms above. A sweep over 1..1024 ULPs on twelve real
    // files moved the skip rate by less than 3 points, so this is nowhere near
    // a knife edge.
    constexpr float kULPs = 16.0f * std::numeric_limits<float>::epsilon();
    const float inverseLinear = std::max({std::abs(inverseWorld[0]),
                                          std::abs(inverseWorld[1]),
                                          std::abs(inverseWorld[2]),
                                          std::abs(inverseWorld[3])});
    const float inverseTranslation =
        std::max(std::abs(inverseWorld[4]), std::abs(inverseWorld[5]));

    m_scratchInputs.clear();
    m_scratchInputs.reserve(paths.size());
    for (auto path : paths)
    {
        const Mat2D& pathWorld = path->pathTransform();
        const float pathLinear = std::max({std::abs(pathWorld[0]),
                                           std::abs(pathWorld[1]),
                                           std::abs(pathWorld[2]),
                                           std::abs(pathWorld[3])});
        const float pathTranslation =
            std::max(std::abs(pathWorld[4]), std::abs(pathWorld[5]));
        const float linearTolerance =
            kULPs * std::max(1.0f, inverseLinear * pathLinear);
        const float translationTolerance =
            kULPs *
            std::max(1.0f,
                     inverseLinear * pathTranslation + inverseTranslation);
        m_scratchInputs.push_back({inverseWorld * pathWorld,
                                   path->geometryVersion(),
                                   path->isHidden() || path->isCollapsed(),
                                   linearTolerance,
                                   translationTolerance});
    }

    // A shape can gain a local path flag after we have already snapshotted
    // (a fill added, a clip registered), so a block that has never been built
    // against this snapshot has to rebuild no matter what the inputs say.
    const PathFlags localFlags =
        m_shape->pathFlags() & (PathFlags::local | PathFlags::localClockwise);
    bool changed = !m_hasLocalInputs || m_localInputs.size() != paths.size() ||
                   (localFlags & ~m_builtLocalFlags) != PathFlags::none;
    for (size_t i = 0; !changed && i < paths.size(); i++)
    {
        changed = !m_localInputs[i].matches(m_scratchInputs[i]);
    }
    if (changed)
    {
        // Only adopt the new inputs when we are about to rebuild from them.
        // Holding the ones the buffer was actually built from is what keeps the
        // tolerance from accumulating frame over frame.
        m_localInputs = m_scratchInputs;
        m_hasLocalInputs = true;
        m_builtLocalFlags = localFlags;
    }
    return changed;
}

namespace
{
// Whether [a] and [b] differ by more than a few ULPs of the larger of them.
bool movedPastULPs(float a, float b)
{
    constexpr float kULPs = 16.0f * std::numeric_limits<float>::epsilon();
    return std::abs(a - b) > kULPs * std::max({1.0f, std::abs(a), std::abs(b)});
}
} // namespace

// A participant's slot is measured from its intrinsic bounds
// (Shape::computeIntrinsicBounds), so compare those rather than what they are
// built from: a path can rebuild without moving them -- a deformed path
// rebuilds on every world transform change -- and they come from each path's
// own transform, so a layout folding the shape to zero can't hide a change.
// Within a few ULPs, since a deformed path round-trips through world space,
// and against the bounds the layout was last told about, so the tolerance
// can't accumulate frame over frame.
bool PathComposer::intrinsicBoundsChanged()
{
    // Measure fresh: a path collapsing moves them without dropping the
    // participant's cached copy.
    if (auto* participant = m_shape->layoutParticipant())
    {
        participant->invalidateHostBounds();
    }
    const AABB bounds = m_shape->computeIntrinsicBounds();
    const AABB& last = m_reportedIntrinsicBounds;
    const bool changed = !m_hasReportedIntrinsicBounds ||
                         movedPastULPs(bounds.minX, last.minX) ||
                         movedPastULPs(bounds.minY, last.minY) ||
                         movedPastULPs(bounds.maxX, last.maxX) ||
                         movedPastULPs(bounds.maxY, last.maxY);
    if (changed)
    {
        m_reportedIntrinsicBounds = bounds;
        m_hasReportedIntrinsicBounds = true;
    }
    return changed;
}

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

        // Only the local blocks consult the snapshot, so a shape with just a
        // world path (a clip source, a world stroke) should not pay for the
        // inverse and the per-path compare. A shape that gains a local flag
        // later still lands here with no snapshot, which reads as changed.
        const bool rebuildLocal =
            m_shape->isFlagged(PathFlags::local | PathFlags::localClockwise) &&
            localInputsChanged();
        if (m_shape->isFlagged(PathFlags::local) && rebuildLocal)
        {
            m_localPath.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_localPath.addPath(path->rawPath(), &localTransform);
                }
            }
        }
        if (m_shape->isFlagged(PathFlags::localClockwise) && rebuildLocal)
        {
            m_localClockwisePath.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())
                {
                    continue;
                }
                const auto localTransform =
                    inverseWorld * path->pathTransform();
                bool isNotClockwise =
                    path->is<PointsPath>() &&
                    localTransform.determinant() *
                            path->as<PointsPath>()->winding() <
                        0;
                bool isHole = path->isHole();
                // Only draw backwards if values are different
                if (isNotClockwise != isHole)
                {
                    m_localClockwisePath.addPathBackwards(path->rawPath(),
                                                          &localTransform);
                }
                else
                {
                    m_localClockwisePath.addPath(path->rawPath(),
                                                 &localTransform);
                }
            }
        }
        if (m_shape->isFlagged(PathFlags::world))
        {
            m_worldPath.rewind();

            for (auto path : m_shape->paths())
            {
                if (!path->isHidden() && !path->isCollapsed())
                {
                    const Mat2D& transform = path->pathTransform();
                    m_worldPath.addPath(path->rawPath(), &transform);
                }
            }
        }
        // A layout participant is measured from its intrinsic bounds, which a
        // rigid move of the shape or an ancestor leaves alone. Telling the
        // layout anyway is what kept a scene with a visible participant busy
        // forever: the solve dirties the host's world transform, which
        // arrives back here as a move.
        bool measuredGeometryChanged = true;
#ifdef WITH_RIVE_LAYOUT
        if (m_shape->hasLayoutParticipant())
        {
            measuredGeometryChanged = intrinsicBoundsChanged();
        }
#endif
        if (measuredGeometryChanged)
        {
            m_shape->markBoundsDirty();
        }
        else
        {
            m_shape->markWorldBoundsDirty();
        }
    }
}

// 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);
    }
}