/*
 * 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 {
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;
    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
