/*
 * Copyright 2022 Rive
 */

#ifndef _RIVE_CONTOUR_MEASURE_HPP_
#define _RIVE_CONTOUR_MEASURE_HPP_

#include "rive/math/raw_path.hpp"
#include "rive/math/vec2d.hpp"
#include "rive/refcnt.hpp"
#include <utility>

namespace rive
{

class ContourMeasure : public RefCnt<ContourMeasure>
{
public:
    static constexpr unsigned kMaxDot30 = (1 << 30) - 1;
    static constexpr float kInvScaleD30 = 1.0f / (float)kMaxDot30;

    // Deliberately making this pack well (12 bytes)
    struct Segment
    {
        float m_distance;       // total distance up to this point
        uint32_t m_ptIndex;     // index of the first point for this line/quad/cubic
        unsigned m_tValue : 30; // Dot30 t value for the end of this segment
        unsigned m_type : 2;    // [private enum]

        float getT() const { return m_tValue * kInvScaleD30; }

        bool operator<(const Segment& other) const { return m_distance < other.m_distance; }

        void extract(RawPath* dst, float fromT, float toT, const Vec2D pts[], bool moveTo) const;
        void extract(RawPath* dst, const Vec2D pts[]) const;
    };

private:
    size_t findSegment(float distance) const;

    std::vector<Segment> m_segments;
    std::vector<Vec2D> m_points;
    const float m_length;
    const bool m_isClosed;

    ContourMeasure(std::vector<Segment>&&, std::vector<Vec2D>&&, float length, bool isClosed);

    friend class ContourMeasureIter;

public:
    float length() const { return m_length; }
    bool isClosed() const { return m_isClosed; }

    struct PosTan
    {
        Vec2D pos, tan;
    };
    PosTan getPosTan(float distance) const;

    void getSegment(float startDistance, float endDistance, RawPath* dst, bool startWithMove) const;

    Vec2D warp(Vec2D src) const
    {
        const auto result = this->getPosTan(src.x);
        return {
            result.pos.x - result.tan.y * src.y,
            result.pos.y + result.tan.x * src.y,
        };
    }

    void dump() const;
};

class ContourMeasureIter
{
    RawPath m_optionalCopy;
    RawPath::Iter m_iter;
    RawPath::Iter m_end;
    const Vec2D* m_srcPoints;
    float m_invTolerance;

    float addQuadSegs(std::vector<ContourMeasure::Segment>&,
                      const Vec2D[],
                      uint32_t ptIndex,
                      float distance) const;
    float addCubicSegs(std::vector<ContourMeasure::Segment>&,
                       const Vec2D[],
                       uint32_t ptIndex,
                       float distance) const;
    rcp<ContourMeasure> tryNext();

public:
    // Tolerance is the max deviation of the curve from its approximating line
    // segments. A smaller tolerance means more line segments, but a better
    // approximation for the curves actual length.
    static constexpr float kDefaultTolerance = 0.5f;

    ContourMeasureIter(const RawPath& path, float tol = kDefaultTolerance)
    {
        this->reset(path, tol);
    }

    void reset(const RawPath&, float = kDefaultTolerance);

    // Returns a measure object for each contour in the path
    //   (contours with zero-length are skipped over)
    // and then returns nullptr when its finished.
    //
    //  ContourMeasureIter iter(path);
    //  while ((auto meas = iter.next())) {
    //      ... meas can be used, and passed to other objects
    //  }
    //
    // Each measure object is stand-alone, and can outlive the ContourMeasureIter
    // that created it. It contains no back pointers to the Iter or to the path.
    //
    rcp<ContourMeasure> next();
};

} // namespace rive

#endif
