#include "rive/artboard.hpp"
#include "rive/factory.hpp"
#include "rive/layout/axis.hpp"
#include "rive/layout/n_sliced_node.hpp"
#include "rive/math/math_types.hpp"
#include "rive/math/n_slicer_helpers.hpp"

using namespace rive;

std::vector<float> NSlicerHelpers::uvStops(const std::vector<Axis*>& axes,
                                           float size)
{
    std::vector<float> uvs = {0.0};
    for (const Axis* axis : axes)
    {
        if (axis == nullptr)
        {
            continue;
        }
        if (axis->normalized())
        {
            uvs.emplace_back(math::clamp(axis->offset(), 0, 1));
        }
        else
        {
            uvs.emplace_back(math::clamp(axis->offset() / size, 0, 1));
        }
    }
    uvs.emplace_back(1.0);
    std::sort(uvs.begin(), uvs.end());
    return uvs;
}

std::vector<float> NSlicerHelpers::pxStops(const std::vector<Axis*>& axes,
                                           float size)
{
    std::vector<float> result = {0.0};
    for (const Axis* axis : axes)
    {
        if (axis == nullptr)
        {
            continue;
        }
        if (axis->normalized())
        {
            result.emplace_back(math::clamp(axis->offset(), 0, 1) * size);
        }
        else
        {
            result.emplace_back(math::clamp(axis->offset(), 0, size));
        }
    }
    result.emplace_back(size);
    std::sort(result.begin(), result.end());
    return result;
}

ScaleInfo NSlicerHelpers::analyzeUVStops(const std::vector<float>& uvs,
                                         float size,
                                         float scale)
{
    assert(size >= 0 && scale >= 0);
    // Find the percentage of the dimension that should be fixed / not scaled.
    float fixedPct = 0.0;
    int numEmptyPatch = 0;
    for (int i = 0; i < (int)uvs.size() - 1; i++)
    {
        float range = uvs[i + 1] - uvs[i];
        if (isFixedSegment(i))
        {
            fixedPct += range;
        }
        else
        {
            numEmptyPatch += (range == 0 ? 1 : 0);
        }
    }

    // Find the scale that the scalable segments are bearing.
    // If the unscaled image is 300px, how to divide it up between scaled and
    // unscaled patches.
    float fixedSize = fixedPct * size;
    float scalableSize = size - fixedSize;

    // Considering the image's scale, how much should the scalable patches scale
    // by. And if all scalable patches were empty, how much whitespace to leave
    // in those patches.
    bool useScale = scalableSize != 0;
    float scaleFactor =
        useScale ? (size * scale - fixedSize) / scalableSize : 0;

    float fallbackSize = 0;
    if (!useScale && numEmptyPatch != 0)
    {
        fallbackSize = (size - fixedSize / scale) / numEmptyPatch;
    }

    return {useScale, scaleFactor, fallbackSize};
}

float NSlicerHelpers::mapValue(const std::vector<float>& stops,
                               const ScaleInfo& scaleInfo,
                               float size,
                               float value)
{
    if (value < (stops.front() - 0.01))
    {
        return value;
    }

    if (value > (stops.back() + 0.01))
    {
        return value - stops.back() + size;
    }

    float result = 0;
    for (int i = 0; i < (int)stops.size() - 1; i++)
    {
        bool found = value <= stops[i + 1];
        float span = found ? value - stops[i] : stops[i + 1] - stops[i];
        if (isFixedSegment(i))
        {
            result += span;
        }
        else
        {
            result += scaleInfo.useScale ? scaleInfo.scaleFactor * span : 0;
        }
        if (found)
        {
            break;
        }
    }

    return result;
}

void NSlicerHelpers::deformLocalRenderPathWithNSlicer(
    const NSlicedNode& nslicedNode,
    RawPath& localPath,
    const Mat2D& world,
    const Mat2D& inverseWorld)
{
    RawPath tempWorld = localPath.transform(world);
    deformWorldRenderPathWithNSlicer(nslicedNode, tempWorld);
    localPath.rewind();
    localPath.addPath(tempWorld, &inverseWorld);
}

void NSlicerHelpers::deformWorldRenderPathWithNSlicer(
    const NSlicedNode& nslicedNode,
    RawPath& worldPath)
{
    for (Vec2D& point : worldPath.points())
    {
        nslicedNode.mapWorldPoint(point);
    }
}
