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