#ifndef _RIVE_METRICS_PATH_HPP_
#define _RIVE_METRICS_PATH_HPP_

#include "rive/command_path.hpp"
#include "rive/math/vec2d.hpp"
#include <cassert>
#include <vector>

namespace rive {

struct CubicSegment {
    float t;
    float length;
    CubicSegment(float tValue, float lengthValue) : t(tValue), length(lengthValue) {}
};

struct PathPart {
    static const unsigned char line = 0;
    /// Type is 0 when this is a line segment, it's 1 or greater when it's a
    /// cubic. When it's a cubic it also represents the index in
    /// CubicSegments-1.
    unsigned char type;

    /// Offset is the offset in original path points (which get transformed
    /// when they're added to another path).
    unsigned char offset;

    // Only used by the cubic to count the number of cubic segments used by
    // this part.
    unsigned char numSegments;

    PathPart(unsigned char t, unsigned char l) : type(t), offset(l), numSegments(0) {}
};

class MetricsPath : public CommandPath {
private:
    std::vector<Vec2D> m_Points;
    std::vector<Vec2D> m_TransformedPoints;
    std::vector<CubicSegment> m_CubicSegments;
    std::vector<PathPart> m_Parts;
    std::vector<float> m_Lengths;
    std::vector<MetricsPath*> m_Paths;
    float m_ComputedLength = 0.0f;
    Mat2D m_ComputedLengthTransform;

public:
    const std::vector<MetricsPath*>& paths() const { return m_Paths; }
    void addPath(CommandPath* path, const Mat2D& transform) override;
    void reset() override;
    void moveTo(float x, float y) override;
    void lineTo(float x, float y) override;
    void cubicTo(float ox, float oy, float ix, float iy, float x, float y) override;
    void close() override;

    float length() const { return m_ComputedLength; }

    /// Add commands to the result RenderPath that will draw the segment
    /// from startLength to endLength of this MetricsPath. Requires
    /// computeLength be called prior to trimming.
    void trim(float startLength, float endLength, bool moveTo, RenderPath* result);

private:
    float computeLength(const Mat2D& transform);

    /// Extract a single segment from startT to endT as render commands
    /// added to result.
    void extractSubPart(int index, float startT, float endT, bool moveTo, RenderPath* result);
};

class OnlyMetricsPath : public MetricsPath {
public:
    void fillRule(FillRule value) override {}

    RenderPath* renderPath() override {
        // Should never be used for actual rendering.
        assert(false);
        return nullptr;
    }
};

class RenderMetricsPath : public MetricsPath {
private:
    std::unique_ptr<RenderPath> m_RenderPath;

public:
    RenderMetricsPath(std::unique_ptr<RenderPath>);
    RenderPath* renderPath() override { return m_RenderPath.get(); }
    void addPath(CommandPath* path, const Mat2D& transform) override;

    void fillRule(FillRule value) override;
    void reset() override;
    void moveTo(float x, float y) override;
    void lineTo(float x, float y) override;
    void cubicTo(float ox, float oy, float ix, float iy, float x, float y) override;
    void close() override;
};
} // namespace rive
#endif