/*
 * Copyright 2022 Rive
 */

#ifndef _RIVE_RAW_PATH_HPP_
#define _RIVE_RAW_PATH_HPP_

#include "rive/span.hpp"
#include "rive/math/aabb.hpp"
#include "rive/math/mat2d.hpp"
#include "rive/math/path_types.hpp"
#include "rive/math/vec2d.hpp"

#include <cmath>
#include <stdio.h>
#include <cstdint>
#include <tuple>
#include <vector>

namespace rive
{

class CommandPath;

class RawPath
{
public:
    RawPath() = default;

    // Bulk copy for deserialization, arrays trusted self-consistent. Contour
    // bookkeeping stays default since the path is consumed, not built.
    RawPath(Span<const PathVerb> verbs, Span<const Vec2D> points) :
        m_Points(points.data(), points.data() + points.size()),
        m_Verbs(verbs.data(), verbs.data() + verbs.size())
    {}

    bool operator==(const RawPath& o) const;
    bool operator!=(const RawPath& o) const { return !(*this == o); }

    bool empty() const { return m_Points.empty(); }
    AABB bounds() const;
#ifdef DEBUG
    void printCode() const;
#endif
    AABB preciseBounds() const { return preciseBounds(Mat2D()); }
    // Tight bounds of the path as it would be after xform, without copying it.
    AABB preciseBounds(const Mat2D& xform) const;
    size_t countMoveTos() const;

    void move(Vec2D);
    void line(Vec2D);
    void quad(Vec2D, Vec2D);
    void cubic(Vec2D, Vec2D, Vec2D);
    void close();
    bool isClosed() const;

    void swap(RawPath&);

    // Makes the path empty and frees any memory allocated by the drawing
    // (line, curve, move, close) calls.
    void reset();

    // Makes the path empty but keeps the memory for the drawing calls reserved.
    void rewind();

    RawPath transform(const Mat2D&) const;
    void transformInPlace(const Mat2D&);

    Span<const Vec2D> points() const { return m_Points; }
    Span<Vec2D> points() { return m_Points; }

    Span<const PathVerb> verbs() const { return m_Verbs; }
    Span<PathVerb> verbs() { return m_Verbs; }

    Span<const uint8_t> verbsU8() const
    {
        const uint8_t* ptr = (const uint8_t*)m_Verbs.data();
        return Span<const uint8_t>(ptr, m_Verbs.size());
    }

    // Syntactic sugar for x,y -vs- vec2d

    void moveTo(float x, float y) { move({x, y}); }
    void lineTo(float x, float y) { line({x, y}); }
    void quadTo(float x, float y, float x1, float y1)
    {
        quad({x, y}, {x1, y1});
    }
    void cubicTo(float x, float y, float x1, float y1, float x2, float y2)
    {
        cubic({x, y}, {x1, y1}, {x2, y2});
    }
    void quadToCubic(float x, float y, float x1, float y1);

    // Helpers for adding new contours

    void addRect(const AABB&, PathDirection = PathDirection::cw);
    void addOval(const AABB&, PathDirection = PathDirection::cw);
    void addPoly(Span<const Vec2D>, bool isClosed);

    // Simple STL-style iterator. To traverse using range-for:
    //
    //   for (auto [verb, pts] : rawPath) { ... }
    //
    class Iter
    {
    public:
        Iter() = default;
        Iter(const PathVerb* verbs, const Vec2D* pts) :
            m_verbs(verbs), m_pts(pts)
        {}

        bool operator!=(const Iter& that) const
        {
            assert(m_verbs != that.m_verbs || m_pts == that.m_pts);
            return m_verbs != that.m_verbs;
        }
        bool operator==(const Iter& that) const
        {
            assert(m_verbs != that.m_verbs || m_pts == that.m_pts);
            return m_verbs == that.m_verbs;
        }

        // Generic accessors. The points pointer is adjusted to point to p0 for
        // each specific verb.
        PathVerb verb() const { return *m_verbs; }
        const Vec2D* pts() const { return m_pts + PtsBacksetForVerb(verb()); }
        std::tuple<PathVerb, const Vec2D*> operator*() const
        {
            PathVerb verb = *m_verbs;
            return {verb, m_pts + PtsBacksetForVerb(verb)};
        }

        // Specific point accessors for callers who already know the verb.
        // (These may be a tiny bit faster in some cases since the iterator
        // doesn't have to check the verb.)
        Vec2D movePt() const
        {
            assert(verb() == PathVerb::move);
            return m_pts[0];
        }
        const Vec2D* linePts() const
        {
            assert(verb() == PathVerb::line);
            return m_pts - 1;
        }
        const Vec2D* quadPts() const
        {
            assert(verb() == PathVerb::quad);
            return m_pts - 1;
        }
        const Vec2D* cubicPts() const
        {
            assert(verb() == PathVerb::cubic);
            return m_pts - 1;
        }
        Vec2D ptBeforeClose() const
        {
            assert(verb() == PathVerb::close);
            return m_pts[-1];
        }
        // P0 for a close can be accessed via rawPtsPtr()[-1]. Note than p1 for
        // a close is not in the array at this location.

        // Internal pointers held by the iterator. See PtsBacksetForVerb() for
        // how pts() relates to the data for specific verbs.
        const PathVerb* rawVerbsPtr() const { return m_verbs; }
        const Vec2D* rawPtsPtr() const { return m_pts; }

        Iter& operator++() // "++iter"
        {
            m_pts += PtsAdvanceAfterVerb(*m_verbs++);
            return *this;
        }

        // How much should we advance pts after encountering this verb?
        inline static int PtsAdvanceAfterVerb(PathVerb verb)
        {
            switch (verb)
            {
                case PathVerb::move:
                    return 1;
                case PathVerb::line:
                    return 1;
                case PathVerb::quad:
                    return 2;
                case PathVerb::cubic:
                    return 3;
                case PathVerb::close:
                    return 0;
            }
            RIVE_UNREACHABLE();
        }

        // Where is p0 relative to our m_pts pointer? We find the start point of
        // segments by peeking backwards from the current point, which works as
        // long as there is always a PathVerb::move before any geometry.
        // (injectImplicitMoveToIfNeeded() guarantees this to be the case.)
        inline static int PtsBacksetForVerb(PathVerb verb)
        {
            switch (verb)
            {
                case PathVerb::move:
                    return 0;
                case PathVerb::line:
                    return -1;
                case PathVerb::quad:
                    return -1;
                case PathVerb::cubic:
                    return -1;
                case PathVerb::close:
                    return -1;
            }
            RIVE_UNREACHABLE();
        }

    private:
        const PathVerb* m_verbs;
        const Vec2D* m_pts;
    };
    Iter begin() const { return {m_Verbs.data(), m_Points.data()}; }
    Iter end() const
    {
        return {m_Verbs.data() + m_Verbs.size(),
                m_Points.data() + m_Points.size()};
    }

    template <typename Handler> RawPath morph(Handler proc) const
    {
        RawPath dst;
        // todo: dst.reserve(src.ptCount, src.verbCount);
        for (auto iter : *this)
        {
            PathVerb verb = std::get<0>(iter);
            const Vec2D* pts = std::get<1>(iter);
            switch (verb)
            {
                case PathVerb::move:
                    dst.move(proc(pts[0]));
                    break;
                case PathVerb::line:
                    dst.line(proc(pts[1]));
                    break;
                case PathVerb::quad:
                    dst.quad(proc(pts[1]), proc(pts[2]));
                    break;
                case PathVerb::cubic:
                    dst.cubic(proc(pts[1]), proc(pts[2]), proc(pts[3]));
                    break;
                case PathVerb::close:
                    dst.close();
                    break;
            }
        }
        return dst;
    }

    // Adds the given RawPath to the end of this path, with an optional
    // transform. Returns an iterator at the beginning of the newly added
    // geometry.
    Iter addPath(const RawPath&, const Mat2D* = nullptr);
    Iter addPathBackwards(const RawPath&, const Mat2D* = nullptr);

    void pruneEmptySegments(Iter start);
    void pruneEmptySegments() { pruneEmptySegments(begin()); }

    // Utility for pouring a RawPath into a CommandPath
    void addTo(CommandPath*) const;

    // If there is not currently an open contour, this method opens a new
    // contour at the current pen location, or [0,0] if the path is empty.
    // Otherwise it does nothing.
    void injectImplicitMoveIfNeeded();

    void reserve(size_t numVerbs, size_t numPts)
    {
        m_Verbs.reserve(numVerbs);
        m_Points.reserve(numPts);
    }
    // Approximates the area of the path by linearizing it with a coarse
    // tolerance of 8px in artboard space.
    constexpr static float kCoarseAreaTolerance = 8;
    // Far from the artboard origin the products cancel into rounding noise,
    // pass an origin near the path to keep them small.
    float computeCoarseArea(Vec2D origin = {0, 0}) const;

private:
    std::vector<Vec2D> m_Points;
    std::vector<PathVerb> m_Verbs;
    size_t m_lastMoveIdx;
    // True of the path is nonempty and the most recent verb is not "close".
    bool m_contourIsOpen = false;

    void addPoints(std::vector<Vec2D>::const_reverse_iterator& rev_iter,
                   int count,
                   const Mat2D* = nullptr);
};

} // namespace rive

#endif
