module util.animationImpl;
private import std.math;
private import util.animation;
private import util.parts;
private import util.matrix;


public class Swing:Animation{
	public:
	uint degType;
	double amp;
	double alpha;
	double delay;
	public this(int span ,uint degType ,double amp ,double alpha = 0.0 ,int delay = 0 ,bool repeat = false){
		super(span ,repeat);
		this.degType = degType;
		this.amp = amp;
		this.alpha = alpha;
		this.delay = delay;
	}
	public void run(){
		super.run();
		if(parts !is null && parts.exists){
			parts.rotate(degType ,sin(((count + delay) % span) * PI * 2.0 / span) * amp , alpha);
		}
	}

}

public class RotateTo:Animation{
	public:
	double dDeg;
	double targetDeg;
	uint degType;
	double alpha;
	public this(int span ,uint degType ,double targetDeg ,double alpha = 0.0  ,bool repeat = false){
		super(span ,repeat);
		this.degType = degType;
		this.targetDeg = targetDeg;
		this.dDeg = 0;
		this.alpha = alpha;
	}
	public void set(Parts parts){
		super.set(parts);
		if(abs(span - count) > (1e-6)){
			dDeg = (targetDeg - *parts.pDeg(degType)) / cast(double)(span - count);
		}
	}
	public void run(){
		super.run();
		if(parts !is null && parts.exists){
			parts.rotate(degType ,dDeg , alpha);
		}
	}

}
public class Rotate:Animation{
	public:
	double dDeg;
	double alpha;
	uint degType;
	public this(int span ,uint degType ,double dDeg ,double alpha = 0.0 ,bool repeat = false){
		super(span ,repeat);
		this.degType = degType;
		this.dDeg = dDeg;
		this.alpha = alpha;
	}
	public void run(){
		super.run();
		if(parts !is null && parts.exists){
			parts.rotate(degType ,dDeg , alpha);
		}
	}
}
public class RotateAll:Animation{
	public:
	Matrix d;
	public this(int span ,Matrix d ,bool repeat = false){
		super(span ,repeat);
		this.d = cast(Matrix)d.clone();
	}
	public void run(){
		super.run();
		if(parts !is null && parts.exists){
			parts.rotateAll(d);
		}
	}
}

public class ExtendTo:Animation{
	public:
	double dDist;
	double targetDist;
	double alpha;
	public this(int span ,double targetDist ,double alpha = 0.0  ,bool repeat = false){
		super(span ,repeat);
		this.targetDist = targetDist;
		this.dDist = 0;
		this.alpha = alpha;
	}
	public void set(Parts parts){
		super.set(parts);
		if(abs(span - count) > (1e-6)){
			dDist = (targetDist - parts.dist) / cast(double)(span - count);
		}
	}
	public void run(){
		super.run();
		if(parts !is null && parts.exists){
			parts.dist += dDist;
		}
	}

}