/*
 * Copyright 2022 Rive
 */

#include "rive/math/raw_path.hpp"

#include "rive/command_path.hpp"
#include "rive/math/simd.hpp"
#include "rive/math/wangs_formula.hpp"
#include "rive/math/bezier_utils.hpp"
#include <cmath>
#include <cstring>
#include <algorithm>

namespace rive
{
bool RawPath::operator==(const RawPath& o) const
{
    return m_Points == o.m_Points && m_Verbs == o.m_Verbs;
}

AABB RawPath::bounds() const
{
    float4 mins, maxes;
    size_t i;
    if (m_Points.size() & 1)
    {
        mins = maxes = simd::load2f(&m_Points[0].x).xyxy;
        i = 1;
    }
    else
    {
        mins = maxes = m_Points.empty() ? float4{0, 0, 0, 0}
                                        : simd::load4f(&m_Points[0].x);
        i = 2;
    }
    for (; i < m_Points.size(); i += 2)
    {
        float4 pts = simd::load4f(&m_Points[i].x);
        mins = simd::min(mins, pts);
        maxes = simd::max(maxes, pts);
    }
    AABB bounds;
    simd::store(&bounds.minX, simd::min(mins.xy, mins.zw));
    simd::store(&bounds.maxX, simd::max(maxes.xy, maxes.zw));
    return bounds;
}

size_t RawPath::countMoveTos() const
{
    size_t moveToCount = 0;
    for (PathVerb verb : m_Verbs)
    {
        moveToCount += verb == PathVerb::move ? 1 : 0;
    }
    return moveToCount;
}

void RawPath::injectImplicitMoveIfNeeded()
{
    if (!m_contourIsOpen)
    {
        move(m_Points.empty() ? Vec2D{0, 0} : m_Points[m_lastMoveIdx]);
    }
}

void RawPath::move(Vec2D a)
{
    m_contourIsOpen = true;
    m_lastMoveIdx = m_Points.size();
    m_Points.push_back(a);
    m_Verbs.push_back(PathVerb::move);
}

void RawPath::line(Vec2D a)
{
    injectImplicitMoveIfNeeded();
    m_Points.push_back(a);
    m_Verbs.push_back(PathVerb::line);
}

void RawPath::quad(Vec2D a, Vec2D b)
{
    injectImplicitMoveIfNeeded();
    m_Points.push_back(a);
    m_Points.push_back(b);
    m_Verbs.push_back(PathVerb::quad);
}

void RawPath::cubic(Vec2D a, Vec2D b, Vec2D c)
{
    injectImplicitMoveIfNeeded();
    m_Points.push_back(a);
    m_Points.push_back(b);
    m_Points.push_back(c);
    m_Verbs.push_back(PathVerb::cubic);
}

void RawPath::close()
{
    if (m_contourIsOpen)
    {
        m_Verbs.push_back(PathVerb::close);
        m_contourIsOpen = false;
    }
}

bool RawPath::isClosed() const
{
    if (m_Verbs.size() > 0)
    {
        return m_Verbs[m_Verbs.size() - 1] == PathVerb::close;
    }
    return false;
}

RawPath RawPath::transform(const Mat2D& m) const
{
    RawPath path;

    path.m_Verbs = m_Verbs;

    path.m_Points.resize(m_Points.size());
    m.mapPoints(path.m_Points.data(), m_Points.data(), m_Points.size());
    return path;
}

void RawPath::transformInPlace(const Mat2D& m)
{
    m.mapPoints(m_Points.data(), m_Points.data(), m_Points.size());
}

void RawPath::addRect(const AABB& r, PathDirection dir)
{
    // We manually close the rectangle, in case we want to stroke
    // this path. We also call close() so we get proper joins
    // (and not caps).

    m_Points.reserve(5);
    m_Verbs.reserve(6);

    moveTo(r.left(), r.top());
    if (dir == PathDirection::clockwise)
    {
        lineTo(r.right(), r.top());
        lineTo(r.right(), r.bottom());
        lineTo(r.left(), r.bottom());
    }
    else
    {
        lineTo(r.left(), r.bottom());
        lineTo(r.right(), r.bottom());
        lineTo(r.right(), r.top());
    }
    close();
}

void RawPath::addOval(const AABB& r, PathDirection dir)
{
    // see https://spencermortensen.com/articles/bezier-circle/
    constexpr float C = 0.5519150244935105707435627f;
    // precompute clockwise unit circle, starting and ending at {1, 0}
    constexpr rive::Vec2D unit[] = {
        {1, 0},
        {1, C},
        {C, 1}, // quadrant 1 ( 4:30)
        {0, 1},
        {-C, 1},
        {-1, C}, // quadrant 2 ( 7:30)
        {-1, 0},
        {-1, -C},
        {-C, -1}, // quadrant 3 (10:30)
        {0, -1},
        {C, -1},
        {1, -C}, // quadrant 4 ( 1:30)
        {1, 0},
    };

    const auto center = r.center();
    const float dx = center.x;
    const float dy = center.y;
    const float sx = r.width() * 0.5f;
    const float sy = r.height() * 0.5f;

    auto map = [dx, dy, sx, sy](rive::Vec2D p) {
        return rive::Vec2D(p.x * sx + dx, p.y * sy + dy);
    };

    m_Points.reserve(13);
    m_Verbs.reserve(6);

    if (dir == PathDirection::clockwise)
    {
        move(map(unit[0]));
        for (int i = 1; i <= 12; i += 3)
        {
            cubic(map(unit[i + 0]), map(unit[i + 1]), map(unit[i + 2]));
        }
    }
    else
    {
        move(map(unit[12]));
        for (int i = 11; i >= 0; i -= 3)
        {
            cubic(map(unit[i - 0]), map(unit[i - 1]), map(unit[i - 2]));
        }
    }
    close();
}

void RawPath::addPoly(Span<const Vec2D> span, bool isClosed)
{
    if (span.size() == 0)
    {
        return;
    }

    // should we permit must moveTo() or just moveTo()/close() ?

    m_Points.reserve(span.size() + isClosed);
    m_Verbs.reserve(span.size() + isClosed);

    move(span[0]);
    for (size_t i = 1; i < span.size(); ++i)
    {
        line(span[i]);
    }
    if (isClosed)
    {
        close();
    }
}

void RawPath::addPoints(std::vector<Vec2D>::const_reverse_iterator& ptIter,
                        int count,
                        const Mat2D* mat)
{
    while (count > 0)
    {
        auto point = *ptIter;
        if (mat)
        {
            Vec2D transformedPoint = Vec2D::transformMat2D(point, *mat);
            m_Points.emplace_back(transformedPoint);
        }
        else
        {
            m_Points.emplace_back(point);
        }
        ptIter++;
        count--;
    }
}

RawPath::Iter RawPath::addPath(const RawPath& src, const Mat2D* mat)
{
    size_t initialVerbCount = m_Verbs.size();
    size_t initialPointCount = m_Points.size();

    m_Verbs.insert(m_Verbs.end(), src.m_Verbs.cbegin(), src.m_Verbs.cend());

    if (mat)
    {
        const auto oldPointCount = m_Points.size();
        m_Points.resize(oldPointCount + src.m_Points.size());
        Vec2D* dst = m_Points.data() + oldPointCount;
        mat->mapPoints(dst, src.m_Points.data(), src.m_Points.size());
    }
    else
    {
        m_Points.insert(m_Points.end(),
                        src.m_Points.cbegin(),
                        src.m_Points.cend());
    }

    // Return an iterator at the beginning of the newly added geometry.
    return Iter{m_Verbs.data() + initialVerbCount,
                m_Points.data() + initialPointCount};
}

RawPath::Iter RawPath::addPathBackwards(const RawPath& src, const Mat2D* mat)
{
    size_t initialVerbCount = m_Verbs.size();
    size_t initialPointCount = m_Points.size();
    if (!src.m_Verbs.empty())
    {
        bool isClosed = src.m_Verbs.back() == PathVerb::close;

        auto reversePointIterator = src.m_Points.rbegin();
        // Move to first point
        m_Verbs.emplace_back(PathVerb::move);
        addPoints(reversePointIterator, 1, mat);

        auto reverseVerbIterator = src.m_Verbs.rbegin();
        if (isClosed)
        {
            reverseVerbIterator++;
        }

        bool hasPendingMoveCommand = false;

        for (; reverseVerbIterator != src.m_Verbs.rend() - 1;
             reverseVerbIterator++)
        {
            PathVerb verb = *reverseVerbIterator;
            // For paths that have multiple segments (like in certain font
            // glyphs), we need to flip the intermediate move verbs with the
            // previous close path. So we hold on to it and add it after the
            // next close call.
            if (verb == PathVerb::move)
            {
                hasPendingMoveCommand = true;
            }
            else
            {
                if (hasPendingMoveCommand && verb != PathVerb::close)
                {
                    m_Verbs.emplace_back(PathVerb::move);
                    hasPendingMoveCommand = false;
                }
                m_Verbs.emplace_back(verb);
                if (hasPendingMoveCommand && verb == PathVerb::close)
                {
                    m_Verbs.emplace_back(PathVerb::move);
                    hasPendingMoveCommand = false;
                }
            }
            switch (verb)
            {
                case PathVerb::cubic:
                    addPoints(reversePointIterator, 3, mat);
                    break;
                case PathVerb::quad:
                    addPoints(reversePointIterator, 2, mat);
                    break;
                case PathVerb::line:
                case PathVerb::move:
                    addPoints(reversePointIterator, 1, mat);
                    break;
                default:
                    break;
            }
        }
        // This should never be the case, but if for some reason a path ends
        // with a move command, we add it to the list of verbs to ensure the
        // path matches with the number of points
        if (hasPendingMoveCommand)
        {
            m_Verbs.emplace_back(PathVerb::move);
        }
        m_Verbs.emplace_back(PathVerb::close);
    }
    return Iter{m_Verbs.data() + initialVerbCount,
                m_Points.data() + initialPointCount};
}

void RawPath::pruneEmptySegments(Iter start)
{
    auto dstVerb =
        m_Verbs.begin() +
        std::distance<const PathVerb*>(m_Verbs.data(), start.rawVerbsPtr());
    auto dstPts =
        m_Points.begin() +
        std::distance<const Vec2D*>(m_Points.data(), start.rawPtsPtr());
    decltype(m_Verbs)::const_iterator srcVerb = dstVerb;
    decltype(m_Points)::const_iterator srcPts = dstPts;

    int ptsAdvance;
    for (auto end = m_Verbs.end(); srcVerb != end;
         ++srcVerb, srcPts += ptsAdvance)
    {
        PathVerb verb = *srcVerb;
        ptsAdvance = Iter::PtsAdvanceAfterVerb(verb);

        switch (verb)
        {
            case PathVerb::move:
                break;
            case PathVerb::close:
                break;
            case PathVerb::cubic:
                if (srcPts[2] != srcPts[1])
                {
                    break;
                }
                RIVE_FALLTHROUGH;
            case PathVerb::quad:
                if (srcPts[1] != srcPts[0])
                {
                    break;
                }
                RIVE_FALLTHROUGH;
            case PathVerb::line:
                if (srcPts[0] != srcPts[-1])
                {
                    break;
                }
                // This segment is empty! Don't keep it.
                continue;
        }

        if (srcVerb != dstVerb)
        {
            *dstVerb = verb;
            std::copy(srcPts, srcPts + ptsAdvance, dstPts);
        }

        ++dstVerb;
        dstPts += ptsAdvance;
    }

    if (dstVerb != srcVerb)
    {
        m_Verbs.erase(dstVerb, m_Verbs.end());
        m_Points.erase(dstPts, m_Points.end());
    }
}

//////////////////////////////////////////////////////////////////////////
int path_verb_to_point_count(PathVerb v)
{
    static uint8_t ptCounts[] = {
        1, // move
        1, // line
        2, // quad
        2, // conic (unused)
        3, // cubic
        0, // close
    };
    size_t index = (size_t)v;
    assert(index < sizeof(ptCounts));
    return ptCounts[index];
}

void RawPath::swap(RawPath& rawPath)
{
    m_Points.swap(rawPath.m_Points);
    m_Verbs.swap(rawPath.m_Verbs);
}

void RawPath::reset()
{
    m_Points.clear();
    m_Points.shrink_to_fit();
    m_Verbs.clear();
    m_Verbs.shrink_to_fit();
    m_contourIsOpen = false;
}

void RawPath::rewind()
{
    m_Points.clear();
    m_Verbs.clear();
    m_contourIsOpen = false;
}

///////////////////////////////////

void RawPath::addTo(CommandPath* result) const
{
    for (auto iter : *this)
    {
        PathVerb verb = std::get<0>(iter);
        const Vec2D* pts = std::get<1>(iter);
        switch (verb)
        {
            case PathVerb::move:
                result->move(pts[0]);
                break;
            case PathVerb::line:
                result->line(pts[1]);
                break;
            case PathVerb::cubic:
                result->cubic(pts[1], pts[2], pts[3]);
                break;
            case PathVerb::close:
                result->close();
                break;
            case PathVerb::quad:
                // TODO: actually supports quads.
                result->cubic(Vec2D::lerp(pts[0], pts[1], 2 / 3.f),
                              Vec2D::lerp(pts[2], pts[1], 2 / 3.f),
                              pts[2]);
        }
    }
}

void RawPath::quadToCubic(float x, float y, float x1, float y1)
{
    assert(!m_Points.empty());
    if (m_Points.empty())
    {
        return;
    }
    const Vec2D& p0 = m_Points.back();
    const Vec2D p1(x, y);
    const Vec2D p2(x1, y1);
    cubic(Vec2D::lerp(p0, p1, 2 / 3.f), Vec2D::lerp(p2, p1, 2 / 3.f), p2);
}

#ifdef DEBUG
void RawPath::printCode() const
{
    fprintf(stderr, "RawPath path;\n");
    for (auto iter : *this)
    {
        PathVerb verb = std::get<0>(iter);
        const Vec2D* pts = std::get<1>(iter);
        switch (verb)
        {
            case PathVerb::move:
                fprintf(stderr, "path.moveTo(%f, %f);\n", pts[0].x, pts[0].y);
                break;
            case PathVerb::line:
                fprintf(stderr, "path.lineTo(%f, %f);\n", pts[1].x, pts[1].y);
                break;
            case PathVerb::cubic:
                fprintf(stderr,
                        "path.cubicTo(%f, %f, %f, %f, %f, %f);\n",
                        pts[1].x,
                        pts[1].y,
                        pts[2].x,
                        pts[2].y,
                        pts[3].x,
                        pts[3].y);
                break;
            case PathVerb::close:
                fprintf(stderr, "path.close();\n");
                break;
            case PathVerb::quad:
                fprintf(stderr,
                        "path.quadTo(%f, %f, %f, %f);\n",
                        pts[1].x,
                        pts[1].y,
                        pts[2].x,
                        pts[2].y);
        }
    }
    fprintf(stderr, "\n");
}
#endif
#ifdef WITH_RIVE_TOOLS
static void expandAxisBounds(AABB& bounds, int axis, float value)
{
    switch (axis)
    {
        case 0:
            if (value < bounds.minX)
            {
                bounds.minX = value;
            }
            if (value > bounds.maxX)
            {
                bounds.maxX = value;
            }
            break;
        case 1:
            if (value < bounds.minY)
            {
                bounds.minY = value;
            }
            if (value > bounds.maxY)
            {
                bounds.maxY = value;
            }
            break;
        default:
            RIVE_UNREACHABLE();
    }
}

// Expand our bounds to a point (in normalized T space) on the cubic.
static void expandBoundsToCubicPoint(AABB& bounds,
                                     int axis,
                                     float t,
                                     float a,
                                     float b,
                                     float c,
                                     float d)
{
    if (t >= 0.0f && t <= 1.0f)
    {
        float ti = 1.0f - t;
        float pointAtT = ((ti * ti * ti) * a) + ((3.0f * ti * ti * t) * b) +
                         ((3.0f * ti * t * t) * c) + (t * t * t * d);
        expandAxisBounds(bounds, axis, pointAtT);
    }
}

// Based on finding the extremas of the curve as described here:
// https://pomax.github.io/bezierinfo/#extremities and based on PR we provided
// to the Flutter team here: https://github.com/flutter/engine/pull/19054 and
// here:
// https://github.com/luigi-rosso/engine/blob/9ae3efd7dc6bcb9634402b4b8818d0add096c12d/lib/web_ui/lib/src/engine/surface/path.dart#L892
static void expandCubicBoundsForAxis(AABB& bounds,
                                     int axis,
                                     float start,
                                     float cp1,
                                     float cp2,
                                     float end)
{
    // Check start/end as cubic goes through those.
    expandAxisBounds(bounds, axis, start);
    expandAxisBounds(bounds, axis, end);
    // Now check extremas.

    // Find the first derivative
    float a = 3.0f * (cp1 - start);
    float b = 3.0f * (cp2 - cp1);
    float c = 3.0f * (end - cp2);
    float d = a - 2.0f * b + c;

    // Solve roots for first derivative.
    if (d != 0)
    {
        float m1 = -sqrtf(b * b - a * c);
        float m2 = -a + b;

        // First root.
        expandBoundsToCubicPoint(bounds,
                                 axis,
                                 -(m1 + m2) / d,
                                 start,
                                 cp1,
                                 cp2,
                                 end);
        expandBoundsToCubicPoint(bounds,
                                 axis,
                                 -(-m1 + m2) / d,
                                 start,
                                 cp1,
                                 cp2,
                                 end);
    }
    else if (b != c && d == 0)
    {
        expandBoundsToCubicPoint(bounds,
                                 axis,
                                 (2.0f * b - c) / (2.0f * (b - c)),
                                 start,
                                 cp1,
                                 cp2,
                                 end);
    }

    // Derive the first derivative to get the 2nd and use the root of
    // that (linear).
    float d2a = 2.0f * (b - a);
    float d2b = 2.0f * (c - b);
    if (d2a != b)
    {
        expandBoundsToCubicPoint(bounds,
                                 axis,
                                 d2a / (d2a - d2b),
                                 start,
                                 cp1,
                                 cp2,
                                 end);
    }
}

AABB RawPath::preciseBounds() const
{
    AABB bounds = AABB::forExpansion();
    for (auto iter : *this)
    {
        PathVerb verb = std::get<0>(iter);
        const Vec2D* pts = std::get<1>(iter);
        switch (verb)
        {
            case PathVerb::move:
                bounds.expandTo(bounds, pts[0]);
                break;
            case PathVerb::line:
                bounds.expandTo(bounds, pts[1]);
                break;
            case PathVerb::cubic:
                expandCubicBoundsForAxis(bounds,
                                         0,
                                         pts[0].x,
                                         pts[1].x,
                                         pts[2].x,
                                         pts[3].x);
                expandCubicBoundsForAxis(bounds,
                                         1,
                                         pts[0].y,
                                         pts[1].y,
                                         pts[2].y,
                                         pts[3].y);
                break;
            case PathVerb::close:
                break;
            case PathVerb::quad:
                // Rive very rarely computes precise bounds for quadratics so we
                // don't implement this specific case. We do use it in the
                // editor for some cases so we still solve it as a cubic.
                Vec2D pt1 = Vec2D::lerp(pts[0], pts[1], 2 / 3.f);
                Vec2D pt2 = Vec2D::lerp(pts[2], pts[1], 2 / 3.f);
                expandCubicBoundsForAxis(bounds,
                                         0,
                                         pts[0].x,
                                         pt1.x,
                                         pt2.x,
                                         pts[2].x);
                expandCubicBoundsForAxis(bounds,
                                         1,
                                         pts[0].y,
                                         pt1.y,
                                         pt2.y,
                                         pts[2].y);
                break;
        }
    }
    return bounds;
}
#endif

float RawPath::computeCoarseArea() const
{
    float a = 0;
    Vec2D contourP0 = {0, 0}, lastPt = {0, 0};
    for (auto iter : *this)
    {
        PathVerb verb = std::get<0>(iter);
        const Vec2D* pts = std::get<1>(iter);
        switch (verb)
        {
            case PathVerb::move:
                a += Vec2D::cross(lastPt, contourP0);
                contourP0 = lastPt = pts[0];
                break;
            case PathVerb::close:
                break;
            case PathVerb::line:
                a += Vec2D::cross(lastPt, pts[1]);
                lastPt = pts[1];
                break;
            case PathVerb::quad:
                RIVE_UNREACHABLE();
            case PathVerb::cubic:
            {
                // Linearize the cubic in artboard space, then add up the
                // area for each segment.
                float n = ceilf(
                    wangs_formula::cubic(pts, 1.f / kCoarseAreaTolerance));
                if (n > 1)
                {
                    n = std::min(n, 64.f);
                    float4 t = float4{1, 1, 2, 2} * (1 / n);
                    float4 dt = t.w;
                    math::EvalCubic evalCubic(pts);
                    for (; t.x < 1; t += dt)
                    {
                        float4 p = evalCubic(t);
                        Vec2D lo = {p.x, p.y};
                        a += Vec2D::cross(lastPt, lo);
                        lastPt = lo;
                        if (t.y < 1)
                        {
                            Vec2D hi = {p.z, p.w};
                            a += Vec2D::cross(lastPt, hi);
                            lastPt = hi;
                        }
                    }
                }
                a += Vec2D::cross(lastPt, pts[3]);
                lastPt = pts[3];
                break;
            }
        }
    }
    a += Vec2D::cross(lastPt, contourP0);
    return a * .5f;
}
} // namespace rive
