#include "rive/shapes/metrics_path.hpp"
#include "rive/renderer.hpp"
#include <math.h>

using namespace rive;

float clamp(float v, float lo, float hi) {
    if (v < lo) {
        return lo;
    } else if (v > hi) {
        return hi;
    }
    return v;
}

void MetricsPath::reset() {
    m_ComputedLength = 0.0f;
    m_CubicSegments.clear();
    m_Points.clear();
    m_Parts.clear();
    m_Lengths.clear();
    m_Paths.clear();
}

void MetricsPath::addPath(CommandPath* path, const Mat2D& transform) {
    MetricsPath* metricsPath = reinterpret_cast<MetricsPath*>(path);
    m_ComputedLength += metricsPath->computeLength(transform);
    m_Paths.emplace_back(metricsPath);
}

void MetricsPath::moveTo(float x, float y) {
    assert(m_Points.size() == 0);
    m_Points.emplace_back(Vec2D(x, y));
}

void MetricsPath::lineTo(float x, float y) {
    m_Parts.push_back(PathPart(0, m_Points.size()));
    m_Points.emplace_back(Vec2D(x, y));
}

void MetricsPath::cubicTo(float ox, float oy, float ix, float iy, float x, float y) {
    m_Parts.push_back(PathPart(1, m_Points.size()));
    m_Points.emplace_back(Vec2D(ox, oy));
    m_Points.emplace_back(Vec2D(ix, iy));
    m_Points.emplace_back(Vec2D(x, y));
}

void MetricsPath::close() {}

static void computeHull(const Vec2D& from,
                        const Vec2D& fromOut,
                        const Vec2D& toIn,
                        const Vec2D& to,
                        float t,
                        Vec2D* hull) {
    hull[0] = Vec2D::lerp(from, fromOut, t);
    hull[1] = Vec2D::lerp(fromOut, toIn, t);
    hull[2] = Vec2D::lerp(toIn, to, t);

    hull[3] = Vec2D::lerp(hull[0], hull[1], t);
    hull[4] = Vec2D::lerp(hull[1], hull[2], t);

    hull[5] = Vec2D::lerp(hull[3], hull[4], t);
}

static const float minSegmentLength = 0.05f;
static const float distTooFar = 1.0f;

static bool tooFar(const Vec2D& a, const Vec2D& b) {
    return std::max(std::abs(a[0] - b[0]), std::abs(a[1] - b[1])) > distTooFar;
}

static bool
shouldSplitCubic(const Vec2D& from, const Vec2D& fromOut, const Vec2D& toIn, const Vec2D& to) {
    const Vec2D oneThird = Vec2D::lerp(from, to, 1.0f / 3.0f),
                twoThird = Vec2D::lerp(from, to, 2.0f / 3.0f);
    return tooFar(fromOut, oneThird) || tooFar(toIn, twoThird);
}

static float segmentCubic(const Vec2D& from,
                          const Vec2D& fromOut,
                          const Vec2D& toIn,
                          const Vec2D& to,
                          float runningLength,
                          float t1,
                          float t2,
                          std::vector<CubicSegment>& segments) {

    if (shouldSplitCubic(from, fromOut, toIn, to)) {
        float halfT = (t1 + t2) / 2.0f;

        Vec2D hull[6];
        computeHull(from, fromOut, toIn, to, 0.5f, hull);

        runningLength =
            segmentCubic(from, hull[0], hull[3], hull[5], runningLength, t1, halfT, segments);
        runningLength =
            segmentCubic(hull[5], hull[4], hull[2], to, runningLength, halfT, t2, segments);
    } else {
        float length = Vec2D::distance(from, to);
        runningLength += length;
        if (length > minSegmentLength) {
            segments.emplace_back(CubicSegment(t2, runningLength));
        }
    }
    return runningLength;
}

float MetricsPath::computeLength(const Mat2D& transform) {
    // If the pre-computed length is still valid (transformed with the same
    // transform) just return that.
    if (!m_Lengths.empty() && transform == m_ComputedLengthTransform) {
        return m_ComputedLength;
    }
    m_ComputedLengthTransform = transform;
    m_Lengths.clear();
    m_CubicSegments.clear();

    // We have to dupe the transformed points as we're not sure whether just the
    // transform is changing (path may not have been reset but got added with
    // another transform).
    m_TransformedPoints.resize(m_Points.size());
    for (size_t i = 0, l = m_Points.size(); i < l; i++) {
        m_TransformedPoints[i] = transform * m_Points[i];
    }

    // Should never have subPaths with more subPaths (Skia allows this but for
    // Rive this isn't necessary and it keeps things simpler).
    assert(m_Paths.empty());
    const Vec2D* pen = &m_TransformedPoints[0];
    int idx = 1;
    float length = 0.0f;

    for (PathPart& part : m_Parts) {
        switch (part.type) {
            case PathPart::line: {
                const Vec2D& point = m_TransformedPoints[idx++];

                float partLength = Vec2D::distance(*pen, point);
                m_Lengths.push_back(partLength);
                pen = &point;
                length += partLength;
                break;
            }
            // Anything above 0 is the number of cubic parts...
            default: {
                // Subdivide as necessary...

                // push in the parts

                const Vec2D& from = pen[0];
                const Vec2D& fromOut = pen[1];
                const Vec2D& toIn = pen[2];
                const Vec2D& to = pen[3];

                idx += 3;
                pen = &to;

                int index = (int)m_CubicSegments.size();
                part.type = index + 1;
                float partLength =
                    segmentCubic(from, fromOut, toIn, to, 0.0f, 0.0f, 1.0f, m_CubicSegments);
                m_Lengths.push_back(partLength);
                length += partLength;
                part.numSegments = m_CubicSegments.size() - index;
                break;
            }
        }
    }
    m_ComputedLength = length;
    return length;
}

void MetricsPath::trim(float startLength, float endLength, bool moveTo, RenderPath* result) {
    assert(endLength >= startLength);
    if (!m_Paths.empty()) {
        m_Paths.front()->trim(startLength, endLength, moveTo, result);
        return;
    }
    if (startLength == endLength) {
        // nothing to trim.
        return;
    }
    // We need to find the first part to trim.
    float length = 0.0f;

    int partCount = (int)m_Parts.size();
    int firstPartIndex = -1, lastPartIndex = partCount - 1;
    float startT = 0.0f, endT = 1.0f;
    // Find first part.
    for (int i = 0; i < partCount; i++) {
        float partLength = m_Lengths[i];
        if (length + partLength > startLength) {
            firstPartIndex = i;
            startT = (startLength - length) / partLength;
            break;
        }
        length += partLength;
    }
    if (firstPartIndex == -1) {
        // Couldn't find it.
        return;
    }

    // Find last part.
    for (int i = firstPartIndex; i < partCount; i++) {
        float partLength = m_Lengths[i];
        if (length + partLength >= endLength) {
            lastPartIndex = i;
            endT = (endLength - length) / partLength;
            break;
        }
        length += partLength;
    }

    // Lets make sur we're between 0 & 1f on both start & end.
    startT = clamp(startT, 0.0f, 1.0f);
    endT = clamp(endT, 0.0f, 1.0f);

    if (firstPartIndex == lastPartIndex) {
        extractSubPart(firstPartIndex, startT, endT, moveTo, result);
    } else {
        extractSubPart(firstPartIndex, startT, 1.0f, moveTo, result);
        for (int i = firstPartIndex + 1; i < lastPartIndex; i++) {
            // add entire part...
            const PathPart& part = m_Parts[i];
            switch (part.type) {
                case PathPart::line: {
                    const Vec2D& point = m_TransformedPoints[part.offset];
                    result->lineTo(point[0], point[1]);
                    break;
                }
                default: {
                    const Vec2D& point1 = m_TransformedPoints[part.offset];
                    const Vec2D& point2 = m_TransformedPoints[part.offset + 1];
                    const Vec2D& point3 = m_TransformedPoints[part.offset + 2];
                    result->cubicTo(
                        point1[0], point1[1], point2[0], point2[1], point3[0], point3[1]);
                    break;
                }
            }
        }
        extractSubPart(lastPartIndex, 0.0f, endT, false, result);
    }
}

float lerp(float from, float to, float f) { return from + f * (to - from); }

void MetricsPath::extractSubPart(
    int index, float startT, float endT, bool moveTo, RenderPath* result) {
    assert(startT >= 0.0f && startT <= 1.0f && endT >= 0.0f && endT <= 1.0f);
    const PathPart& part = m_Parts[index];
    switch (part.type) {
        case PathPart::line: {
            const Vec2D& from = m_TransformedPoints[part.offset - 1];
            const Vec2D& to = m_TransformedPoints[part.offset];
            Vec2D dir = to - from;
            if (moveTo) {
                Vec2D point = from + dir * startT;
                result->moveTo(point[0], point[1]);
            }
            dir = from + dir * endT;
            result->lineTo(dir[0], dir[1]);

            break;
        }
        default: {
            auto startingSegmentIndex = part.type - 1;
            auto startEndSegmentIndex = startingSegmentIndex;
            auto endingSegmentIndex = startingSegmentIndex + part.numSegments;

            // Find cubicStartT and cubicEndT
            float length = m_Lengths[index];
            if (startT != 0.0f) {
                float startLength = startT * length;
                for (int si = startingSegmentIndex; si < endingSegmentIndex; si++) {
                    const CubicSegment& segment = m_CubicSegments[si];
                    if (segment.length >= startLength) {
                        if (si == startingSegmentIndex) {
                            startT = segment.t * (startLength / segment.length);
                        } else {
                            float previousLength = m_CubicSegments[si - 1].length;

                            float t =
                                (startLength - previousLength) / (segment.length - previousLength);
                            startT = lerp(m_CubicSegments[si - 1].t, segment.t, t);
                        }
                        // Help out the ending segment finder by setting its
                        // start to where we landed while finding the first
                        // segment, that way it can skip a bunch of work.
                        startEndSegmentIndex = si;
                        break;
                    }
                }
            }

            if (endT != 1.0f) {
                float endLength = endT * length;
                for (int si = startEndSegmentIndex; si < endingSegmentIndex; si++) {
                    const CubicSegment& segment = m_CubicSegments[si];
                    if (segment.length >= endLength) {
                        if (si == startingSegmentIndex) {
                            endT = segment.t * (endLength / segment.length);
                        } else {
                            float previousLength = m_CubicSegments[si - 1].length;

                            float t =
                                (endLength - previousLength) / (segment.length - previousLength);
                            endT = lerp(m_CubicSegments[si - 1].t, segment.t, t);
                        }
                        break;
                    }
                }
            }

            Vec2D hull[6];

            const Vec2D& from = m_TransformedPoints[part.offset - 1];
            const Vec2D& fromOut = m_TransformedPoints[part.offset];
            const Vec2D& toIn = m_TransformedPoints[part.offset + 1];
            const Vec2D& to = m_TransformedPoints[part.offset + 2];

            if (startT == 0.0f) {
                // Start is 0, so split at end and keep the left side.
                computeHull(from, fromOut, toIn, to, endT, hull);
                if (moveTo) {
                    result->moveTo(from[0], from[1]);
                }
                result->cubicTo(
                    hull[0][0], hull[0][1], hull[3][0], hull[3][1], hull[5][0], hull[5][1]);
            } else {
                // Split at start since it's non 0.
                computeHull(from, fromOut, toIn, to, startT, hull);
                if (moveTo) {
                    // Move to first point on the right side.
                    result->moveTo(hull[5][0], hull[5][1]);
                }
                if (endT == 1.0f) {
                    // End is 1, so no further split is necessary just cubicTo
                    // the remaining right side.
                    result->cubicTo(hull[4][0], hull[4][1], hull[2][0], hull[2][1], to[0], to[1]);
                } else {
                    // End is not 1, so split again and cubic to the left side
                    // of the split and remap endT to the new curve range
                    computeHull(
                        hull[5], hull[4], hull[2], to, (endT - startT) / (1.0f - startT), hull);

                    result->cubicTo(
                        hull[0][0], hull[0][1], hull[3][0], hull[3][1], hull[5][0], hull[5][1]);
                }
            }
            break;
        }
    }
}

RenderMetricsPath::RenderMetricsPath() : m_RenderPath(makeRenderPath()) {}
RenderMetricsPath::~RenderMetricsPath() { delete m_RenderPath; }

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

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

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); }
