#include "rive/shapes/paint/trim_path.hpp"
#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 (startLength > totalLength)
            {
                startLength -= totalLength;
                endLength -= 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(); }