module gedo.video.polyline;



public import gedo.math.vector;
public import gedo.video.ggl;



public class PolyLine
{
public:
	float radius;
	uint  count;

	this(uint c)
	{
		_points.length = c;

		_vertices.length = c * 2;

		float x = 0.0;

		foreach(inout vertex; _vertices)
		{
			vertex.texCoord[0] = x;
			vertex.texCoord[1] = 0.0;

			x = 1.0 - x;
		}

		radius = 1.0;
		count  = 0;
	}


	Vector[] points()
	{
		return _points[0 .. count];
	}


	GGL_Vertex[] vertices()
	{
		if(count >= 2 && count <= _points.length)
		{
			Vector campos;

			GGL_getCameraPosition(campos.ptr);

			Vector c;
			.gedo.math.vector.subtract(c, _points[0], campos);

			Vector a;
			.gedo.math.vector.subtract(a, _points[1], _points[0]);

			Vector b;

			cross(b, c, a);

			.gedo.math.vector.normalize(b);

			.gedo.math.vector.multiply(b, radius);

			.gedo.math.vector.subtract(_vertices[0].position, _points[0], b);
			.gedo.math.vector.add(_vertices[1].position, _points[0], b);

			if(count > 2)
			{
				.gedo.math.vector.subtract(c, _points[count - 2], campos);
				.gedo.math.vector.subtract(a, _points[count - 1], _points[count - 2]);

				cross(b, c, a);

				.gedo.math.vector.normalize(b);
				.gedo.math.vector.multiply(b, radius);
			}

			.gedo.math.vector.subtract(_vertices[count*2 - 2].position, _points[count - 1], b);
			.gedo.math.vector.add(_vertices[count*2 - 1].position, _points[count - 1], b);

			foreach(ii, point; _points[1 .. count-1])
			{
				auto i = ii + 1;

				.gedo.math.vector.subtract(c, _points[i-1], campos);
				.gedo.math.vector.subtract(a, _points[i+1], _points[i-1]);

				cross(b, c, a);

				.gedo.math.vector.normalize(b);
				.gedo.math.vector.multiply(b, radius);

				.gedo.math.vector.subtract(_vertices[i*2+0].position, point, b);
				.gedo.math.vector.add(_vertices[i*2+1].position, point, b);
			}

			float yt  = 0.0;
			float dyt = 1.0f / (count - 1);

			auto verts = _vertices[0 .. count*2];
			foreach(i, inout vertex; verts)
			{
				vertex.texCoord[1] = yt;
				if(i & 1)
				{
					yt += dyt;
				}
			}

			return verts;
		}
		else
		{
			return null;
		}
	}


	void record(Vector pos)
	{
		foreach(i, inout p; _points[0 .. $-1])
		{
			p[] = _points[i+1][];
		}
		_points[$-1][] = pos[];
	}


	void record(Vector pos, float l)
	{
		_points[1][] = pos[];

		Vector d;

		.gedo.math.vector.subtract(d, _points[0], _points[1]);

		auto ld = .gedo.math.vector.magnitude(d);
		if(ld > l)
		{
			.gedo.math.vector.multiply(d, l/ld);

			.gedo.math.vector.add(_points[0], _points[1], d);
		}
	}


	uint maxCount()
	{
		return _points.length;
	}


private:
	GGL_Vertex[] _vertices;
	Vector[]     _points;
}

