package net.phatcode.rel.math;

import java.util.ArrayList;

public class Spline
{
	
	private ArrayList<Vector2D> coords = new ArrayList<>();

	private Vector2D position = new Vector2D();
	
	private float speed;
	private float time;
	private int index;
	private int numPoints;
	private boolean timeWrapped;
	
	public Spline()
	{
		
		speed = 0.01f;
		time = 0;
		index = 0;
		timeWrapped = false;
		numPoints = 0;		
		
	}
	
	public void reset()
	{
		time = 0;
		index = 0;
		timeWrapped = false;
	}
	
	public Vector2D getPosition()
	{
		return position;
	}
	
	public float getX()
	{
		return position.x;
	}
	
	public float getY()
	{
		return position.y;
	}
	
	public int getNumPoints()
	{
		return numPoints;
	}
	
	
	public float getSpeed()
	{
		return speed;
	}

	public float getTime()
	{
		return time;
	}

	public void setSpeed( float speed )
	{
		this.speed = speed;
	}

	public void setTime( float time )
	{
		this.time = time;
	}

	
	public int getIndex()
	{
		return index;
	}

	public boolean isTimeWrapped()
	{
		return timeWrapped;
	}

	public void setIndex(int index)
	{
		this.index = index;
	}

	public void addPoint( Vector2D v )
	{
		coords.add( v );
		numPoints++;
	}
	
	public float getAngle()
	{
		
		int i1 = ( index + 1 ) % numPoints;
		int i2 = ( index + 2 ) % numPoints;
		int i3 = ( index + 3 ) % numPoints;
		
		Vector2D p0, p1, p2, p3;
		
		p0 = coords.get(index);
		p1 = coords.get(i1);
		p2 = coords.get(i2);
		p3 = coords.get(i3);
		
		float x = Utils.catMullRomDerivative(p0.x, p1.x, p2.x, p3.x, time);
		float y = Utils.catMullRomDerivative(p0.y, p1.y, p2.y, p3.y, time);
		
		return (float)Math.atan2(y,x);
		
	}
	
	public void update()
	{
		
		
		int i1 = ( index + 1 ) % numPoints;
		int i2 = ( index + 2 ) % numPoints;
		int i3 = ( index + 3 ) % numPoints;
		
		Vector2D p0, p1, p2, p3;
		
		p0 = coords.get(index);
		p1 = coords.get(i1);
		p2 = coords.get(i2);
		p3 = coords.get(i3);
		
		position.x = Utils.catMullRom(p0.x, p1.x, p2.x, p3.x, time);
		position.y = Utils.catMullRom(p0.y, p1.y, p2.y, p3.y, time);
		
		timeWrapped = false;
		
		time += speed;

		if( time > 1.0f )
		{
			time -= 1.0f;
			index = ( index + 1 ) % numPoints;
			timeWrapped = true;
		}
		
	}
	
}
