#if defined(LOW_LEVEL_RENDERING) && defined(CONTOUR_RECURSIVE)

#include "contour_render_path.hpp"
#include "math/cubic_utilities.hpp"
#include <cassert>

using namespace rive;

// TODO when we add strokes, add ranges in the contour that need to be stroked
// as contiguous lines.

// struct StrokeRange
// {
// 	unsigned int start;
// 	unsigned int end;
// };

class RecursiveCubicSegmenter
{
private:
	Vec2D m_Pen, m_PenDown;
	bool m_IsPenDown = false;
	std::vector<Vec2D>* m_Contour;
	// std::vector<StrokeRange> m_StrokeRanges;

	AABB m_Bounds;
	float m_Threshold, m_ThresholdSquared;

public:
	RecursiveCubicSegmenter(std::vector<Vec2D>* contour, float threshold) :
	    m_Contour(contour),
	    m_Bounds(AABB::forExpansion()),
	    m_Threshold(threshold),
	    m_ThresholdSquared(threshold * threshold)
	{
	}

	const Vec2D& pen() { return m_Pen; }
	bool isPenDown() { return m_IsPenDown; }

	void addVertex(const Vec2D& vertex)
	{
		m_Contour->emplace_back(vertex);
		AABB::expandTo(m_Bounds, vertex);
	}

	const AABB& bounds() const { return m_Bounds; }

	inline void penUp()
	{
		if (!m_IsPenDown)
		{
			return;
		}
		m_IsPenDown = false;
	}

	inline void penDown()
	{
		if (m_IsPenDown)
		{
			return;
		}
		m_IsPenDown = true;
		Vec2D::copy(m_PenDown, m_Pen);
		addVertex(m_PenDown);
	}

	inline void close()
	{
		if (!m_IsPenDown)
		{
			return;
		}
		Vec2D::copy(m_Pen, m_PenDown);
		m_IsPenDown = false;

		// TODO: Can we optimize and not dupe this point if it's the last point
		// already in the list? For example: a procedural triangle closes itself
		// with a lineTo the first point.
		addVertex(m_PenDown);
	}

	inline void pen(const Vec2D& position) { Vec2D::copy(m_Pen, position); }

	void segmentCubic(const Vec2D& from,
	                  const Vec2D& fromOut,
	                  const Vec2D& toIn,
	                  const Vec2D& to,
	                  float t1,
	                  float t2)
	{
		if (CubicUtilities::shouldSplitCubic(
		        from, fromOut, toIn, to, m_Threshold))
		{
			float halfT = (t1 + t2) / 2.0f;

			Vec2D hull[6];
			CubicUtilities::computeHull(from, fromOut, toIn, to, 0.5f, hull);

			segmentCubic(from, hull[0], hull[3], hull[5], t1, halfT);

			segmentCubic(hull[5], hull[4], hull[2], to, halfT, t2);
		}
		else
		{
			if (Vec2D::distanceSquared(from, to) > m_ThresholdSquared)
			{
				addVertex(Vec2D(CubicUtilities::cubicAt(
				                    t2, from[0], fromOut[0], toIn[0], to[0]),
				                CubicUtilities::cubicAt(
				                    t2, from[1], fromOut[1], toIn[1], to[1])));
			}
		}
	}
};

void ContourRenderPath::computeContour()
{
	m_IsDirty = false;
	assert(m_ContourVertices.empty());
	RecursiveCubicSegmenter segmenter(&m_ContourVertices, m_ContourThreshold);

	// First four vertices are the bounds.
	m_ContourVertices.emplace_back(Vec2D());
	m_ContourVertices.emplace_back(Vec2D());
	m_ContourVertices.emplace_back(Vec2D());
	m_ContourVertices.emplace_back(Vec2D());

	for (rive::PathCommand& command : m_Commands)
	{
		switch (command.type())
		{
			case PathCommandType::move:
				segmenter.penUp();
				segmenter.pen(command.point());
				break;
			case PathCommandType::line:
				segmenter.penDown();
				segmenter.pen(command.point());
				segmenter.addVertex(command.point());
				break;
			case PathCommandType::cubic:
				segmenter.penDown();
				segmenter.segmentCubic(segmenter.pen(),
				                       command.outPoint(),
				                       command.inPoint(),
				                       command.point(),
				                       0.0f,
				                       1.0f);
				// segmenter.addVertex(command.point());
				segmenter.pen(command.point());
				break;
			case PathCommandType::close:
				segmenter.close();
				break;
		}
	}
	// TODO: when we stroke we may want to differentiate whether or not the path
	// actually closed.
	segmenter.close();

	// TODO: consider if there's a case with no points.
	AABB::copy(m_ContourBounds, segmenter.bounds());
	Vec2D& first = m_ContourVertices[0];
	first[0] = m_ContourBounds.minX;
	first[1] = m_ContourBounds.minY;

	Vec2D& second = m_ContourVertices[1];
	second[0] = m_ContourBounds.maxX;
	second[1] = m_ContourBounds.minY;

	Vec2D& third = m_ContourVertices[2];
	third[0] = m_ContourBounds.maxX;
	third[1] = m_ContourBounds.maxY;

	Vec2D& fourth = m_ContourVertices[3];
	fourth[0] = m_ContourBounds.minX;
	fourth[1] = m_ContourBounds.maxY;
}
#endif