/*
 * Copyright 2022 Rive
 */

#include "pls_path.hpp"

#include "eval_cubic.hpp"
#include "rive/math/simd.hpp"
#include "rive/math/wangs_formula.hpp"

namespace rive::pls
{
PLSPath::PLSPath(FillRule fillRule, RawPath& rawPath)
{
    m_rawPath.swap(rawPath);
    m_rawPath.pruneEmptySegments();
}

void PLSPath::rewind()
{
    assert(m_rawPathMutationLockCount == 0);
    m_rawPath.rewind();
    m_dirt = kAllDirt;
}

void PLSPath::moveTo(float x, float y)
{
    assert(m_rawPathMutationLockCount == 0);
    m_rawPath.moveTo(x, y);
    m_dirt = kAllDirt;
}

void PLSPath::lineTo(float x, float y)
{
    assert(m_rawPathMutationLockCount == 0);

    // Make sure to start a new contour, even if this line is empty.
    m_rawPath.injectImplicitMoveIfNeeded();

    Vec2D p1 = {x, y};
    if (m_rawPath.points().back() != p1)
    {
        m_rawPath.line(p1);
    }

    m_dirt = kAllDirt;
}

void PLSPath::cubicTo(float ox, float oy, float ix, float iy, float x, float y)
{
    assert(m_rawPathMutationLockCount == 0);

    // Make sure to start a new contour, even if this cubic is empty.
    m_rawPath.injectImplicitMoveIfNeeded();

    Vec2D p1 = {ox, oy};
    Vec2D p2 = {ix, iy};
    Vec2D p3 = {x, y};
    if (m_rawPath.points().back() != p1 || p1 != p2 || p2 != p3)
    {
        m_rawPath.cubic(p1, p2, p3);
    }

    m_dirt = kAllDirt;
}

void PLSPath::close()
{
    assert(m_rawPathMutationLockCount == 0);
    m_rawPath.close();
    m_dirt = kAllDirt;
}

void PLSPath::addRenderPath(RenderPath* path, const Mat2D& matrix)
{
    assert(m_rawPathMutationLockCount == 0);
    PLSPath* plsPath = static_cast<PLSPath*>(path);
    RawPath::Iter transformedPathIter = m_rawPath.addPath(plsPath->m_rawPath, &matrix);
    if (matrix != Mat2D())
    {
        // Prune any segments that became empty after the transform.
        m_rawPath.pruneEmptySegments(transformedPathIter);
    }
    m_dirt = kAllDirt;
}

const AABB& PLSPath::getBounds() const
{
    if (m_dirt & kPathBoundsDirt)
    {
        m_bounds = m_rawPath.bounds();
        m_dirt &= ~kPathBoundsDirt;
    }
    return m_bounds;
}

float PLSPath::getCoarseArea() const
{
    if (m_dirt & kPathCoarseAreaDirt)
    {
        float a = 0;
        Vec2D contourP0 = {0, 0}, lastPt = {0, 0};
        for (auto [verb, pts] : m_rawPath)
        {
            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;
                        EvalCubic evalCubic(pts);
                        for (; t.x < 1; t += dt)
                        {
                            float4 p = evalCubic.at(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);
        m_coarseArea = a * .5f;
        m_dirt &= ~kPathCoarseAreaDirt;
    }
    return m_coarseArea;
}

uint64_t PLSPath::getRawPathMutationID() const
{
    static std::atomic<uint64_t> uniqueIDCounter = 0;
    if (m_dirt & kRawPathMutationIDDirt)
    {
        m_rawPathMutationID = ++uniqueIDCounter;
        m_dirt &= ~kRawPathMutationIDDirt;
    }
    return m_rawPathMutationID;
}
} // namespace rive::pls
