var iteration = Class.create();
iteration.prototype = {
	curveHelper:null,
	interval:null,
	this_alias:this,
	executor:null,
	curve: function(t, b, c, d) { 
		// smoothInOut
		if ((t/=d/2) < 1) return c/2*(t*t*(((this.curveHelper*=(1.525))+1)*t - this.curveHelper)) + b;
		return c/2*((t-=2)*t*(((this.curveHelper*=(1.525))+1)*t + this.curveHelper) + 2) + b;
		
		// straight
		//return c*t/d + b;
		
		// backword bounce in
		//if (this_alias.curveHelper == null) this_alias.curveHelper = 1.70158;
		//return c*((t/d-1)*t*((this_alias.curveHelper+1)*(t/d-1) + this_alias.curveHelper) + 1) + b;
		
		// backword bounce out
		//if (this_alias.curveHelper == null) this_alias.curveHelper = 1.70158;
		//return c*((t/d-1)*t*((this_alias.curveHelper+1)*(t/d-1) + this_alias.curveHelper) + 1) + b;
		
		// bounce out
		//if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!this_alias.curveHelper) this_alias.curveHelper=d*.3;
		//if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
		//else var s = this_alias.curveHelper/(2*Math.PI) * Math.asin (c/a);
		//return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/this_alias.curveHelper ) + c + b);
	},
	func:null,
	begin:null,
	change:null,
	position:null,
	duration:null,
	_time:null,
	_pos:null,
	
	initialize: function(func, curve, begin, finish, duration) {
		this_alias = this;
		if(this.executor != null) { this.executor.stop(); }
		this.begin = begin;
		this.position = begin;
		this.duration = duration;
		if (func != null) this.func = func;
		if (curve != null) this.curve = curve;
		this.change = finish - this.begin;
		this.start();
	},
	start: function() {
		this_alias.jumpToBegin();
		this_alias.executor = setInterval(this_alias.nextFrame,1000/25);
	},
	wait: function () {
		window.clearInterval(this_alias.executor);
		this_alias.onStop();
	},
	jumpToBegin: function (t) {
		if (t != undefined){ this_alias._time = t; } else { this_alias._time = 0; }
		this_alias.update();
	},
	jumpToEnd: function() {
		this_alias.time = this_alias.duration;
	},
	nextFrame: function () {
		this_alias.time = this_alias._time + 1;
		this_alias.setIterator(this_alias.time);	
	},
	setIterator: function(t){
		this_alias.prevTime = this_alias._time;
		if (t > this_alias.duration) {
			this_alias._time = this_alias.duration;
			this_alias.update();
			this_alias.wait();
			this_alias.onFinish();
		} else if (t < 0) {
			this_alias.jumpToBegin();
			this_alias.update();
		} else {
			this_alias._time = t;
			this_alias.update();
		}
	},
	update: function (){
		this_alias.prevPos = this_alias._pos;
		this_alias.position = this_alias._pos = this_alias.getPosition(this_alias._time);
		this_alias.func(this_alias.time, this_alias.begin, this_alias.change, this_alias.duration);
		this_alias.onChange();
	},
	getPosition: function(t) {
		return this_alias.curve (t, this_alias.begin, this_alias.change, this_alias.duration);
	},
	onChange: function (){},
	onStop: function (){},
	onFinish: function (){}
};	
