#include "rive/shapes/paint/trim_path.hpp"
#include <algorithm>
#include <cmath>
#include "rive/shapes/paint/shape_paint.hpp"
#include "rive/profiler/profiler_macros.h"
using namespace rive;

void TrimEffectPath::invalidateEffect()
{
  m_path.rewind();
  m_contours.clear();
}

StatusCode TrimPath::onAddedClean(CoreContext* context)
{
  auto effectsContainer = EffectsContainer::from(parent());
  if (!effectsContainer)
  {
    return StatusCode::InvalidObject;
  }
  effectsContainer->addStrokeEffect(this);

  return StatusCode::Ok;
}

void TrimPath::trimPath(
    ShapePaintPath* destination,
    std::vector<rcp<ContourMeasure>>& contours,
    const RawPath* source,
    ShapePaintType shapePaintType)
{
  RIVE_PROF_SCOPE_L(3)
  auto rawPath = destination->mutableRawPath();
  auto renderOffset = std::fmod(std::fmod(offset(), 1.0f) + 1.0f, 1.0f);
  auto closeShape = shapePaintType == ShapePaintType::fill;

  // Build up contours if they're empty.
  if (contours.empty())
  {
    ContourMeasureIter iter(source);
    while (auto meas = iter.next())
    {
      contours.push_back(meas);
    }
  }
  switch (mode())
  {
    case TrimPathMode::sequential:
    {
      float totalLength = 0.0f;
      for (auto contour : contours)
      {
        totalLength += contour->length();
      }
      auto startLength = totalLength * (start() + renderOffset);
      auto endLength = totalLength * (end() + renderOffset);

      if (endLength < startLength)
      {
        float swap = startLength;
        startLength = endLength;
        endLength = swap;
      }

      if (totalLength > 0.0f && startLength > totalLength)
      {
        float wrapped = std::fmod(startLength, totalLength);
        endLength -= startLength - wrapped;
        startLength = wrapped;
      }
      // A span past one full loop draws nothing more, and walking it would
      // take a pass over the contours per loop.
      endLength = std::min(
          endLength,
          std::max(startLength, 0.0f) + totalLength);

      int i = 0, subPathCount = (int)contours.size();
      std::vector<int> indices;
      std::vector<float> lengths;
      while (endLength > 0)
      {
        auto currentContourIndex = i % subPathCount;
        auto contour = contours[currentContourIndex];
        auto contourLength = contour->length();

        if (startLength < contourLength)
        {
          indices.push_back(currentContourIndex);
          lengths.push_back(startLength);
          lengths.push_back(endLength);
          endLength -= contourLength;
          startLength = 0;
        }
        else
        {
          startLength -= contourLength;
          endLength -= contourLength;
        }
        i++;
      }

      // This is inintuitive but works. If the last segment and the first
      // segment of the trim path belong to the same contour, we want to
      // draw the first semgment first, then the last one and then the
      // rest. This is intentional to make sure the last segment is
      // connected to the first one in order to avoid a gap. A linear way
      // without reordering indices is to start at index 0 and go
      // backwards. For the remaining segments it's not important in what
      // order they are drawn
      int startingIndex = 0;
      int indexCount = 0;

      int prevContourIndex = -1;
      while (indexCount < indices.size())
      {
        auto index = (startingIndex < 0 ? startingIndex + indices.size()
                                        : startingIndex) %
                     indices.size();
        auto contourIndex = indices[index];
        auto contour = contours[contourIndex];
        auto contourLength = contour->length();
        auto lengthIndex = index * 2;
        auto startLength = lengths[lengthIndex];
        auto endLength = lengths[lengthIndex + 1];
        // if two consecutive segments belong to the same contour, draw
        // them connected.
        contour->getSegment(
            startLength,
            endLength,
            rawPath,
            prevContourIndex != contourIndex || !contour->isClosed());
        // Close contours that are fully used as
        // segments
        if ((startLength == 0.0f && endLength - startLength >= contourLength &&
             contour->isClosed()) ||
            closeShape)
        {
          rawPath->close();
        }
        prevContourIndex = contourIndex;
        indexCount++;
        startingIndex--;
      }
    }
    break;

    case TrimPathMode::synchronized:
    {
      for (auto contour : contours)
      {
        auto contourLength = contour->length();
        auto startLength = contourLength * (start() + renderOffset);
        auto endLength = contourLength * (end() + renderOffset);
        if (endLength < startLength)
        {
          auto length = startLength;
          startLength = endLength;
          endLength = length;
        }

        if (startLength >= contourLength)
        {
          startLength -= contourLength;
          endLength -= contourLength;
        }
        contour->getSegment(startLength, endLength, rawPath, true);
        while (endLength > contourLength)
        {
          startLength = 0;
          endLength -= contourLength;
          contour->getSegment(
              startLength,
              endLength,
              rawPath,
              !contour->isClosed());
        }

        if ((start() == 0.0f && end() == 1.0f && contour->isClosed()) ||
            closeShape)
        {
          rawPath->close();
        }
      }
    }
    break;
    default:
      RIVE_UNREACHABLE();
  }

  // getSegment has its own precision guards, but a tiny trim window can
  // still land a segment on a single point.
  rawPath->pruneEmptySegments();
}

void TrimPath::startChanged() { invalidateEffectFromLocal(); }
void TrimPath::endChanged() { invalidateEffectFromLocal(); }
void TrimPath::offsetChanged() { invalidateEffectFromLocal(); }
void TrimPath::modeValueChanged() { invalidateEffectFromLocal(); }

StatusCode TrimPath::onAddedDirty(CoreContext* context)
{
  auto code = Super::onAddedDirty(context);
  if (code != StatusCode::Ok)
  {
    return code;
  }
  switch (mode())
  {
    case TrimPathMode::sequential:
    case TrimPathMode::synchronized:

      return StatusCode::Ok;
  }
  return StatusCode::InvalidObject;
}

void TrimPath::updateEffect(
    PathProvider* pathProvider,
    const ShapePaintPath* source,
    const ShapePaint* shapePaint)
{
  auto effectPathIt = m_effectPaths.find(pathProvider);
  if (effectPathIt != m_effectPaths.end())
  {
    auto trimEffectPath = static_cast<TrimEffectPath*>(effectPathIt->second);
    auto path = trimEffectPath->path();
    if (path->hasRenderPath())
    {
      // Previous result hasn't been invalidated, it's still good.
      return;
    }
    path->rewind(source->isLocal(), source->fillRule());
    trimPath(
        path,
        trimEffectPath->contours(),
        source->rawPath(),
        shapePaint->paintType());
  }
}

EffectsContainer* TrimPath::parentPaint()
{
  return EffectsContainer::from(parent());
}

EffectPath* TrimPath::createEffectPath() { return new TrimEffectPath(); }