#include "rive/shapes/paint/trim_path.hpp"
#include "rive/shapes/paint/stroke.hpp"
using namespace rive;

StatusCode TrimPath::onAddedClean(CoreContext* context)
{
    if (!parent()->is<Stroke>())
    {
        return StatusCode::InvalidObject;
    }

    parent()->as<Stroke>()->addStrokeEffect(this);

    return StatusCode::Ok;
}

void TrimPath::trimPath(const RawPath* source)
{
    auto rawPath = m_path.mutableRawPath();
    auto renderOffset = std::fmod(std::fmod(offset(), 1.0f) + 1.0f, 1.0f);

    // Build up contours if they're empty.
    if (m_contours.empty())
    {
        ContourMeasureIter iter(source);
        while (auto meas = iter.next())
        {
            m_contours.push_back(meas);
        }
    }
    switch (mode())
    {
        case TrimPathMode::sequential:
        {
            float totalLength = 0.0f;
            for (auto contour : m_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 (startLength > totalLength)
            {
                startLength -= totalLength;
                endLength -= totalLength;
            }

            int i = 0, subPathCount = (int)m_contours.size();
            std::vector<int> indices;
            std::vector<float> lengths;
            while (endLength > 0)
            {
                auto currentContourIndex = i % subPathCount;
                auto contour = m_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 = m_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())
                {
                    rawPath->close();
                }
                prevContourIndex = contourIndex;
                indexCount++;
                startingIndex--;
            }
        }
        break;

        case TrimPathMode::synchronized:
        {
            for (auto contour : m_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())
                {
                    rawPath->close();
                }
            }
        }
        break;
        default:
            RIVE_UNREACHABLE();
    }
}

void TrimPath::invalidateEffect()
{
    invalidateTrim();
    // This is usually sent when the path is changed so we need to also
    // invalidate the contours, not just the trim effect.
    m_contours.clear();
}

void TrimPath::invalidateTrim()
{
    m_path.rewind();
    if (parent() != nullptr)
    {
        auto stroke = parent()->as<Stroke>();
        stroke->parent()->addDirt(ComponentDirt::Paint);
        stroke->invalidateRendering();
    }
}

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

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(const ShapePaintPath* source)
{
    if (m_path.hasRenderPath())
    {
        // Previous result hasn't been invalidated, it's still good.
        return;
    }
    m_path.rewind(source->isLocal(), source->fillRule());
    trimPath(source->rawPath());
}

ShapePaintPath* TrimPath::effectPath() { return &m_path; }