#include "rive/math/path_measure.hpp"
#include <algorithm>

using namespace rive;

PathMeasure::PathMeasure() : m_length(0.0f) {}

PathMeasure::PathMeasure(const RawPath* path, float tol) : m_length(0.0f)
{
  auto measure = ContourMeasureIter(path, tol);
  for (auto contour = measure.next(); contour != nullptr;
       contour = measure.next())
  {
    m_length += contour->length();
    m_contours.push_back(contour);
  }
}

ContourMeasure::PosTanDistance PathMeasure::atDistance(float distance) const
{
  float currentDistance = distance;
  for (size_t i = 0; i < m_contours.size(); i++)
  {
    const auto& contour = m_contours[i];
    float contourLength = contour->length();
    // The last contour also takes a distance rounding left just past its
    // end, as 100% can; getPosTan clamps it to the end.
    if (currentDistance - contourLength <= 0 || i + 1 == m_contours.size())
    {
      return ContourMeasure::PosTanDistance(
          contour->getPosTan(currentDistance),
          distance);
    }
    currentDistance -= contourLength;
  }
  return ContourMeasure::PosTanDistance();
}

ContourMeasure::PosTanDistance PathMeasure::atPercentage(
    float percentageDistance) const
{
  float inRangePercentage = fmodf(percentageDistance, 1.0f);
  if (inRangePercentage < 0.0f)
  {
    inRangePercentage += 1.0f;
  }

  // Mod to correct percentage (0-100%) and make sure we actually reach
  // 100%.
  if (percentageDistance != 0.0f && inRangePercentage == 0.0f)
  {
    inRangePercentage = 1.0f;
  }

  return atDistance(m_length * inRangePercentage);
}

void PathMeasure::getSegment(
    float startDistance,
    float endDistance,
    RawPath* dst,
    bool startWithMove) const
{
  if (dst == nullptr || m_contours.empty())
  {
    return;
  }

  // Clamp distances to valid range
  startDistance = std::max(0.0f, std::min(startDistance, m_length));
  endDistance = std::max(0.0f, std::min(endDistance, m_length));

  if (startDistance >= endDistance)
  {
    return;
  }

  float currentDistance = 0.0f;
  bool isFirstSegment = true;

  for (auto contour : m_contours)
  {
    float contourLength = contour->length();
    float contourStart = currentDistance;
    float contourEnd = currentDistance + contourLength;

    // Check if this contour intersects with the requested range
    if (contourEnd > startDistance && contourStart < endDistance)
    {
      // Calculate the local distances within this contour
      float localStart = std::max(0.0f, startDistance - contourStart);
      float localEnd = std::min(contourLength, endDistance - contourStart);

      // Extract from this contour
      contour->getSegment(
          localStart,
          localEnd,
          dst,
          !isFirstSegment || startWithMove);
      isFirstSegment = false;
    }

    currentDistance += contourLength;

    // If we've passed the end distance, we're done
    if (currentDistance >= endDistance)
    {
      break;
    }
  }
}

bool PathMeasure::isClosed() const
{
  // Return true only if there is exactly one contour and it is closed
  return m_contours.size() == 1 && m_contours[0]->isClosed();
}
