/*

	Lost Boys 2006.
	
	De inhoud van dit bestand is in opdracht vervaardigd en eigendom van onze opdrachtgever.
	Niet hergebruiken zonder toestemming.
	Neem voor vragen contact op met Lost Boys, www.lostboys.nl.

	The contents of this file have been produced for and are the property of our client.
	Do not reuse without permission.
	Any questions? Please contact Lost Boys, www.lostboys.nl.

*/

Animator = function (startValue, endValue, f, t, r) {
	this.step  = 5;	    			//The step by which timer counts from 0 to 100
	this.rate  = 5;	  			  	//The rate in ms at which steps are taken
	this.power = 2;         		//The steepness of the animation curve
	this.type  = this.EASEINOUT; 	//The type of easing
	this.duration = 0;				//The total duration

	this.min = startValue;
	this.max = endValue;
	this.isReversing = false;
	this.animateFunction = f;
	this.terminateFunction = t;
	this.reversalFunction = r;

	this.precalc = new Array(100);
	for (var i=0; i <= 100; i++) this.precalc[i] = this.calculate(i);
}
Animator.prototype.NONE      = 0;
Animator.prototype.EASEIN    = 1;
Animator.prototype.EASEOUT   = 2;
Animator.prototype.EASEINOUT = 3;

Animator.prototype.setDuration = function (duration) {
	this.duration = duration;
}
Animator.prototype.setStep = function (step) {
	this.step = step;
}
Animator.prototype.setRate = function (rate) {
	this.rate = rate;
}
Animator.prototype.setPower = function (power) {
	this.power = power;
	for (var i=0; i <= 100; i++) this.precalc[i] = this.calculate(i);
}
Animator.prototype.setType = function (type) {
	this.type = type;
	for (var i=0; i <= 100; i++) this.precalc[i] = this.calculate(i);
}
Animator.prototype.setAnimateFunction = function (f) {
	this.animateFunction = f;
}
Animator.prototype.start = function () {
	if (this.interval) return;
	this.time = 0;
	this.startTime = new Date();
	this.isReversing = false;
	this.interval = setInterval(this.method(this.animate), this.rate);
}
Animator.prototype.reverse = function () {
	this.isReversing = (this.isReversing) ? false : true;
}

Animator.prototype.stop = function () {
	if (this.interval) clearInterval(this.interval);
	this.timeLeft = 0;
	this.interval = null;
}
Animator.prototype.pause = function () {
	if (this.interval) clearInterval(this.interval);
	this.interval = null;
	if (this.duration) {
		var now = new Date() - this.startTime;
		this.timeElapsed = now;
	}
}
Animator.prototype.resume = function () {
	if (this.duration) {
		var now = new Date().getTime();
		this.startTime = new Date(now-this.timeElapsed);
	}
	this.interval = setInterval(this.method(this.animate), this.rate);
}
Animator.prototype.isAnimating = function () {
	return Boolean(this.interval);
}
Animator.prototype.animate = function () {
	var finished = false;

	if (this.duration) {
		var now = new Date() - this.startTime;
		if (now < this.duration) {
			this.animateFunction(this.calculate(now/this.duration));
		} else finished = true;
	} else {
		if (this.time >= 0 && this.time <= 100) {
			this.animateFunction(this.precalc[this.time]);
			this.time = (this.isReversing) ? this.time - this.step : this.time + this.step;
		} else finished = true;
	}
	if (finished) {
		clearInterval(this.interval);
		this.animateFunction(this.max);
		this.interval = null;
		if (!this.isReversing && this.terminateFunction) this.terminateFunction();
		if (this.isReversing && this.reversalFunction) this.reversalFunction();
	}
}
Animator.prototype.calculate = function (t) {
	if (!this.duration) t = t/100;
	var factor;
	switch (this.type) {
		case this.NONE      : factor = this.easeNone(t);break;
		case this.EASEIN    : factor = this.easeIn(t);break;
		case this.EASEOUT   : factor = this.easeOut(t);break;
		case this.EASEINOUT : factor = this.easeInOut(t);break;
	}
	return parseInt(this.min + factor*(this.max-this.min));
}
Animator.prototype.easeNone = function (t) {
	return t;
}
Animator.prototype.easeIn = function (t) {
	return Math.pow(t,this.power);
}
Animator.prototype.easeOut = function (t) {
	return 1-this.easeIn(1-t);
}
Animator.prototype.easeInOut = function (t) {
	if (t < 0.5) return this.easeIn(t*2)/2;
	return 0.5+this.easeOut((t-0.5)*2)/2;
}
Animator.prototype.method = function (method) {
	var context = this;
	return function () {
		return method.apply(context, arguments);
	}
}

