#include "rive/shapes/metrics_path.hpp"
#include "rive/renderer.hpp"
#include "rive/math/raw_path.hpp"
#include "rive/math/contour_measure.hpp"
#include <iostream>

using namespace rive;

void MetricsPath::rewind()
{
    for (auto ptr : m_Paths)
    {
        delete ptr;
    }
    m_Paths.clear();
    m_Contour.reset(nullptr);
    m_RawPath.rewind();
    m_ComputedLengthTransform = Mat2D();
    m_ComputedLength = 0;
}

MetricsPath::~MetricsPath() { rewind(); }

void MetricsPath::addPath(CommandPath* path, const Mat2D& transform)
{
    MetricsPath* metricsPath = static_cast<MetricsPath*>(path);
    m_ComputedLength += metricsPath->computeLength(transform);
    // We need to copy the data to avoid contention between multiple uses of the same path
    // for example when the same path is added as localPath and worldPath
    auto metricsPathCopy = new OnlyMetricsPath();
    metricsPathCopy->m_Contour = metricsPath->m_Contour;
    metricsPathCopy->m_RawPath = metricsPath->m_RawPath;
    metricsPathCopy->m_ComputedLength = metricsPath->m_ComputedLength;
    m_Paths.emplace_back(metricsPathCopy);
}

RawPath::Iter MetricsPath::addToRawPath(RawPath& rawPath, const Mat2D& transform) const
{
    return rawPath.addPath(m_RawPath, &transform);
}

void MetricsPath::moveTo(float x, float y)
{
    assert(m_RawPath.points().size() == 0);
    m_RawPath.move({x, y});
}

void MetricsPath::lineTo(float x, float y) { m_RawPath.line({x, y}); }

void MetricsPath::cubicTo(float ox, float oy, float ix, float iy, float x, float y)
{
    m_RawPath.cubic({ox, oy}, {ix, iy}, {x, y});
}

void MetricsPath::close()
{
    // Should we pass the close() to our m_RawPath ???
}

float MetricsPath::computeLength(const Mat2D& transform)
{
    // Only compute if our pre-computed length is not valid
    if (!m_Contour || transform != m_ComputedLengthTransform)
    {
        m_ComputedLengthTransform = transform;
        RawPath transformedPath = m_RawPath.transform(transform);
        m_Contour = ContourMeasureIter(&transformedPath).next();
        m_ComputedLength = m_Contour ? m_Contour->length() : 0;
    }
    return m_ComputedLength;
}

void MetricsPath::trim(float startLength, float endLength, bool moveTo, RawPath* result)
{
    assert(endLength >= startLength);
    if (!m_Paths.empty())
    {
        m_Paths.front()->trim(startLength, endLength, moveTo, result);
        return;
    }
    if (!m_Contour)
    {
        // All the contours were 0 length, so there's nothing to segment.
        return;
    }
    // TODO: if we can change the signature of MetricsPath and/or trim() to speak native
    //       rawpaths, we wouldn't need this temporary copy (since ContourMeasure speaks
    //       native rawpaths).
    RawPath tmp;
    m_Contour->getSegment(startLength, endLength, result, moveTo);
}

RenderMetricsPath::RenderMetricsPath(rcp<RenderPath> path) : m_RenderPath(std::move(path)) {}

void RenderMetricsPath::addPath(CommandPath* path, const Mat2D& transform)
{
    MetricsPath::addPath(path, transform);
    m_RenderPath->addPath(path->renderPath(), transform);
}

void RenderMetricsPath::rewind()
{
    MetricsPath::rewind();
    m_RenderPath->rewind();
}

void RenderMetricsPath::moveTo(float x, float y)
{
    MetricsPath::moveTo(x, y);
    m_RenderPath->moveTo(x, y);
}

void RenderMetricsPath::lineTo(float x, float y)
{
    MetricsPath::lineTo(x, y);
    m_RenderPath->lineTo(x, y);
}

void RenderMetricsPath::cubicTo(float ox, float oy, float ix, float iy, float x, float y)
{
    MetricsPath::cubicTo(ox, oy, ix, iy, x, y);
    m_RenderPath->cubicTo(ox, oy, ix, iy, x, y);
}

void RenderMetricsPath::close()
{
    MetricsPath::close();
    m_RenderPath->close();
}

void RenderMetricsPath::fillRule(FillRule value) { m_RenderPath->fillRule(value); }
