#include "rive/shapes/metrics_path.hpp"
#include "rive/renderer.hpp"
#include <math.h>

using namespace rive;

float clamp(float v, float lo, float hi)
{
	if (v < lo)
	{
		return lo;
	}
	else if (v > hi)
	{
		return hi;
	}
	return v;
}

void MetricsPath::reset()
{
	m_ComputedLength = 0.0f;
	m_CubicSegments.clear();
	m_Points.clear();
	m_Parts.clear();
	m_Lengths.clear();
	m_Paths.clear();
}

void MetricsPath::addPath(CommandPath* path, const Mat2D& transform)
{
	MetricsPath* metricsPath = reinterpret_cast<MetricsPath*>(path);
	m_ComputedLength += metricsPath->computeLength(transform);
	m_Paths.emplace_back(metricsPath);
}

void MetricsPath::moveTo(float x, float y)
{
	assert(m_Points.size() == 0);
	m_Points.emplace_back(Vec2D(x, y));
}

void MetricsPath::lineTo(float x, float y)
{
	m_Parts.push_back(PathPart(0, m_Points.size()));
	m_Points.emplace_back(Vec2D(x, y));
}

void MetricsPath::cubicTo(
    float ox, float oy, float ix, float iy, float x, float y)
{
	m_Parts.push_back(PathPart(1, m_Points.size()));
	m_Points.emplace_back(Vec2D(ox, oy));
	m_Points.emplace_back(Vec2D(ix, iy));
	m_Points.emplace_back(Vec2D(x, y));
}

void MetricsPath::close() {}

static void computeHull(const Vec2D& from,
                        const Vec2D& fromOut,
                        const Vec2D& toIn,
                        const Vec2D& to,
                        float t,
                        Vec2D* hull)
{
	Vec2D::lerp(hull[0], from, fromOut, t);
	Vec2D::lerp(hull[1], fromOut, toIn, t);
	Vec2D::lerp(hull[2], toIn, to, t);

	Vec2D::lerp(hull[3], hull[0], hull[1], t);
	Vec2D::lerp(hull[4], hull[1], hull[2], t);

	Vec2D::lerp(hull[5], hull[3], hull[4], t);
}

static const float minSegmentLength = 0.05f;
static const float distTooFar = 1.0f;

static bool tooFar(const Vec2D& a, const Vec2D& b)
{
	return std::max(std::abs(a[0] - b[0]), std::abs(a[1] - b[1])) > distTooFar;
}

static bool shouldSplitCubic(const Vec2D& from,
                             const Vec2D& fromOut,
                             const Vec2D& toIn,
                             const Vec2D& to)
{
	Vec2D oneThird, twoThird;
	Vec2D::lerp(oneThird, from, to, 1.0f / 3.0f);
	Vec2D::lerp(twoThird, from, to, 2.0f / 3.0f);
	return tooFar(fromOut, oneThird) || tooFar(toIn, twoThird);
}

static float segmentCubic(const Vec2D& from,
                          const Vec2D& fromOut,
                          const Vec2D& toIn,
                          const Vec2D& to,
                          float runningLength,
                          float t1,
                          float t2,
                          std::vector<CubicSegment>& segments)
{

	if (shouldSplitCubic(from, fromOut, toIn, to))
	{
		float halfT = (t1 + t2) / 2.0f;

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

		runningLength = segmentCubic(from,
		                             hull[0],
		                             hull[3],
		                             hull[5],
		                             runningLength,
		                             t1,
		                             halfT,
		                             segments);
		runningLength = segmentCubic(
		    hull[5], hull[4], hull[2], to, runningLength, halfT, t2, segments);
	}
	else
	{
		float length = Vec2D::distance(from, to);
		runningLength += length;
		if (length > minSegmentLength)
		{
			segments.emplace_back(CubicSegment(t2, runningLength));
		}
	}
	return runningLength;
}

float MetricsPath::computeLength(const Mat2D& transform)
{
	// If the pre-computed length is still valid (transformed with the same
	// transform) just return that.
	if (!m_Lengths.empty() && transform == m_ComputedLengthTransform)
	{
		return m_ComputedLength;
	}
	m_ComputedLengthTransform = transform;
	m_Lengths.clear();
	m_CubicSegments.clear();

	// We have to dupe the transformed points as we're not sure whether just the
	// transform is changing (path may not have been reset but got added with
	// another transform).
	m_TransformedPoints.resize(m_Points.size());
	for (size_t i = 0, l = m_Points.size(); i < l; i++)
	{
		Vec2D::transform(m_TransformedPoints[i], m_Points[i], transform);
	}

	// Should never have subPaths with more subPaths (Skia allows this but for
	// Rive this isn't necessary and it keeps things simpler).
	assert(m_Paths.empty());
	const Vec2D* pen = &m_TransformedPoints[0];
	int idx = 1;
	float length = 0.0f;

	for (PathPart& part : m_Parts)
	{
		switch (part.type)
		{
			case PathPart::line:
			{
				const Vec2D& point = m_TransformedPoints[idx++];

				float partLength = Vec2D::distance(*pen, point);
				m_Lengths.push_back(partLength);
				pen = &point;
				length += partLength;
				break;
			}
			// Anything above 0 is the number of cubic parts...
			default:
			{
				// Subdivide as necessary...

				// push in the parts

				const Vec2D& from = pen[0];
				const Vec2D& fromOut = pen[1];
				const Vec2D& toIn = pen[2];
				const Vec2D& to = pen[3];

				idx += 3;
				pen = &to;

				int index = (int)m_CubicSegments.size();
				part.type = index + 1;
				float partLength = segmentCubic(
				    from, fromOut, toIn, to, 0.0f, 0.0f, 1.0f, m_CubicSegments);
				m_Lengths.push_back(partLength);
				length += partLength;
				part.numSegments = m_CubicSegments.size() - index;
				break;
			}
		}
	}
	m_ComputedLength = length;
	return length;
}

void MetricsPath::trim(float startLength,
                       float endLength,
                       bool moveTo,
                       RenderPath* result)
{
	assert(endLength >= startLength);
	if (!m_Paths.empty())
	{
		m_Paths.front()->trim(startLength, endLength, moveTo, result);
		return;
	}
	if (startLength == endLength)
	{
		// nothing to trim.
		return;
	}
	// We need to find the first part to trim.
	float length = 0.0f;

	int partCount = (int)m_Parts.size();
	int firstPartIndex = -1, lastPartIndex = partCount - 1;
	float startT = 0.0f, endT = 1.0f;
	// Find first part.
	for (int i = 0; i < partCount; i++)
	{
		float partLength = m_Lengths[i];
		if (length + partLength > startLength)
		{
			firstPartIndex = i;
			startT = (startLength - length) / partLength;
			break;
		}
		length += partLength;
	}
	if (firstPartIndex == -1)
	{
		// Couldn't find it.
		return;
	}

	// Find last part.
	for (int i = firstPartIndex; i < partCount; i++)
	{
		float partLength = m_Lengths[i];
		if (length + partLength >= endLength)
		{
			lastPartIndex = i;
			endT = (endLength - length) / partLength;
			break;
		}
		length += partLength;
	}

	// Lets make sur we're between 0 & 1f on both start & end.
	startT = clamp(startT, 0.0f, 1.0f);
	endT = clamp(endT, 0.0f, 1.0f);

	if (firstPartIndex == lastPartIndex)
	{
		extractSubPart(firstPartIndex, startT, endT, moveTo, result);
	}
	else
	{
		extractSubPart(firstPartIndex, startT, 1.0f, moveTo, result);
		for (int i = firstPartIndex + 1; i < lastPartIndex; i++)
		{
			// add entire part...
			const PathPart& part = m_Parts[i];
			switch (part.type)
			{
				case PathPart::line:
				{
					const Vec2D& point = m_TransformedPoints[part.offset];
					result->lineTo(point[0], point[1]);
					break;
				}
				default:
				{
					const Vec2D& point1 = m_TransformedPoints[part.offset];
					const Vec2D& point2 = m_TransformedPoints[part.offset + 1];
					const Vec2D& point3 = m_TransformedPoints[part.offset + 2];
					result->cubicTo(point1[0],
					                point1[1],
					                point2[0],
					                point2[1],
					                point3[0],
					                point3[1]);
					break;
				}
			}
		}
		extractSubPart(lastPartIndex, 0.0f, endT, false, result);
	}
}

float lerp(float from, float to, float f) { return from + f * (to - from); }

void MetricsPath::extractSubPart(
    int index, float startT, float endT, bool moveTo, RenderPath* result)
{
	assert(startT >= 0.0f && startT <= 1.0f && endT >= 0.0f && endT <= 1.0f);
	const PathPart& part = m_Parts[index];
	switch (part.type)
	{
		case PathPart::line:
		{
			const Vec2D& from = m_TransformedPoints[part.offset - 1];
			const Vec2D& to = m_TransformedPoints[part.offset];
			Vec2D dir;
			Vec2D::subtract(dir, to, from);
			if (moveTo)
			{
				Vec2D point;
				Vec2D::scaleAndAdd(point, from, dir, startT);
				result->moveTo(point[0], point[1]);
			}
			Vec2D::scaleAndAdd(dir, from, dir, endT);
			result->lineTo(dir[0], dir[1]);

			break;
		}
		default:
		{
			auto startingSegmentIndex = part.type - 1;
			auto startEndSegmentIndex = startingSegmentIndex;
			auto endingSegmentIndex = startingSegmentIndex + part.numSegments;

			// Find cubicStartT and cubicEndT
			float length = m_Lengths[index];
			if (startT != 0.0f)
			{
				float startLength = startT * length;
				for (int si = startingSegmentIndex; si < endingSegmentIndex;
				     si++)
				{
					const CubicSegment& segment = m_CubicSegments[si];
					if (segment.length >= startLength)
					{
						if (si == startingSegmentIndex)
						{
							startT = segment.t * (startLength / segment.length);
						}
						else
						{
							float previousLength =
							    m_CubicSegments[si - 1].length;

							float t = (startLength - previousLength) /
							          (segment.length - previousLength);
							startT =
							    lerp(m_CubicSegments[si - 1].t, segment.t, t);
						}
						// Help out the ending segment finder by setting its
						// start to where we landed while finding the first
						// segment, that way it can skip a bunch of work.
						startEndSegmentIndex = si;
						break;
					}
				}
			}

			if (endT != 1.0f)
			{
				float endLength = endT * length;
				for (int si = startEndSegmentIndex; si < endingSegmentIndex;
				     si++)
				{
					const CubicSegment& segment = m_CubicSegments[si];
					if (segment.length >= endLength)
					{
						if (si == startingSegmentIndex)
						{
							endT = segment.t * (endLength / segment.length);
						}
						else
						{
							float previousLength =
							    m_CubicSegments[si - 1].length;

							float t = (endLength - previousLength) /
							          (segment.length - previousLength);
							endT =
							    lerp(m_CubicSegments[si - 1].t, segment.t, t);
						}
						break;
					}
				}
			}

			Vec2D hull[6];

			const Vec2D& from = m_TransformedPoints[part.offset - 1];
			const Vec2D& fromOut = m_TransformedPoints[part.offset];
			const Vec2D& toIn = m_TransformedPoints[part.offset + 1];
			const Vec2D& to = m_TransformedPoints[part.offset + 2];

			if (startT == 0.0f)
			{
				// Start is 0, so split at end and keep the left side.
				computeHull(from, fromOut, toIn, to, endT, hull);
				if (moveTo)
				{
					result->moveTo(from[0], from[1]);
				}
				result->cubicTo(hull[0][0],
				                hull[0][1],
				                hull[3][0],
				                hull[3][1],
				                hull[5][0],
				                hull[5][1]);
			}
			else
			{
				// Split at start since it's non 0.
				computeHull(from, fromOut, toIn, to, startT, hull);
				if (moveTo)
				{
					// Move to first point on the right side.
					result->moveTo(hull[5][0], hull[5][1]);
				}
				if (endT == 1.0f)
				{
					// End is 1, so no further split is necessary just cubicTo
					// the remaining right side.
					result->cubicTo(hull[4][0],
					                hull[4][1],
					                hull[2][0],
					                hull[2][1],
					                to[0],
					                to[1]);
				}
				else
				{
					// End is not 1, so split again and cubic to the left side
					// of the split and remap endT to the new curve range
					computeHull(hull[5],
					            hull[4],
					            hull[2],
					            to,
					            (endT - startT) / (1.0f - startT),
					            hull);

					result->cubicTo(hull[0][0],
					                hull[0][1],
					                hull[3][0],
					                hull[3][1],
					                hull[5][0],
					                hull[5][1]);
				}
			}
			break;
		}
	}
}

RenderMetricsPath::RenderMetricsPath() : m_RenderPath(makeRenderPath()) {}
RenderMetricsPath::~RenderMetricsPath() { delete m_RenderPath; }

void RenderMetricsPath::addPath(CommandPath* path, const Mat2D& transform)
{
	MetricsPath::addPath(path, transform);
	m_RenderPath->addPath(path->renderPath(), transform);
}

void RenderMetricsPath::reset()
{
	MetricsPath::reset();
	m_RenderPath->reset();
}

void RenderMetricsPath::moveTo(float x, float y)
{
	MetricsPath::moveTo(x, y);
	m_RenderPath->moveTo(x, y);
}

void RenderMetricsPath::lineTo(float x, float y)
{
	MetricsPath::lineTo(x, y);
	m_RenderPath->lineTo(x, y);
}

void RenderMetricsPath::cubicTo(
    float ox, float oy, float ix, float iy, float x, float y)
{
	MetricsPath::cubicTo(ox, oy, ix, iy, x, y);
	m_RenderPath->cubicTo(ox, oy, ix, iy, x, y);
}

void RenderMetricsPath::close()
{
	MetricsPath::close();
	m_RenderPath->close();
}

void RenderMetricsPath::fillRule(FillRule value)
{
	m_RenderPath->fillRule(value);
}
