Animator = function (startValue, endValue, f, t) {
	this.step  = 3;	        //The step by which timer counts from 0 to 100
	this.rate  = 10;	    //The rate in ms at which steps are taken
	this.power = 3;         //The steepness of the animation curve
	this.type  = this.EASEINOUT; //The type of easing

	this.min = startValue;
	this.max = endValue;
	this.animateFunction = f;
	this.terminateFunction = t;

	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.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.interval = setInterval(this.createContextFunction("animate"), this.rate);
}
Animator.prototype.stop = function () {
	if (this.interval) clearInterval(this.interval);
	this.interval = null;
}
Animator.prototype.animate = function () {
	if (this.time <= 100) {
		var factor = this.precalc[this.time];
		var result = this.min + factor*(this.max-this.min);
		this.animateFunction(parseInt(result));//log(parseInt(result));
		this.time += this.step;
	} else {
		clearInterval(this.interval);
		this.interval = null;
		if (this.terminateFunction) this.terminateFunction();
	}
}
Animator.prototype.calculate = function (t) {
	t = t/100;
	switch (this.type) {
		case this.NONE      : return this.easeNone(t);
		case this.EASEIN    : return this.easeIn(t);
		case this.EASEOUT   : return this.easeOut(t);
		case this.EASEINOUT : return this.easeInOut(t);
	}
}
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.createContextFunction = function (method) {
	var context = this;
	return (function(){
		eval("context."+method+"()");
		return false;
    });
}
