/**	Small 'animation' library, which purpose is to simplify process of
 *	animation, without having it slowed down with some heavy framework
 *	author: Tomasz 'blue' Blukis
 *	if You have any questions, please, contact me:
 *	http://blue.ovh.org/kontakt
 */    

var anim = new function(){
	var m=this,anims=[],period=13,T;
	
	function animation(){		// (int,int,int) || ({},int) || ([{},{}],int)
		var n=this;
		n.dir=1; n.f=0; n.ranges=[], n.stopit=!1, n.inprogress=!1;
		if(arguments[0].constructor===Array){
			n.ranges = arguments[0];
			n.time = arguments[1];
		} else if(typeof arguments[0]=='object'){
			n.ranges = [arguments[0]];
			n.time = arguments[1];
		} else {
			n.ranges = [{from: arguments[0], to: arguments[1], trans: 'linear'}];
			n.time = arguments[2];
		}
		n.ranges.each(function(i,r){
			r.delta = r.to - r.from;
		})
		
		n.launch = function(f1,f2){	// (fn) || (fn,fn) || {}
			if(typeof f1=='function'){
				n.stepFn = f1||new Function;
				n.endFn = f2||new Function;
			} else if(typeof f1=='object'){
				n.stepFn = f1.step||new Function;
				n.endFn = f1.end||new Function;
			}
			n.stopit = !1;
			n.inprogress = !0;
			anims.push(n);
			if(!T) T = setInterval(roll,period)
		}
		n.reverse = function(d){
			n.dir=d||-n.dir;
		}
		n.stop = function(){
			n.stopit = !0;
		}
		n.reset = function(d){
			n.dir = d||1;
			n.f = d!==undefined?d:0;
		}
	}
	
	function roll(){
		for(var i=0,a; a=anims[i++];){
			a.f += period*a.dir;
			if(a.f<=0||a.f>=a.time) a.f -= a.f%a.time;
			a.stepFn.apply(a,giveValues(a))
			if(!a.f||a.f==a.time||a.stopit){
				anims.splice(--i,1)
				a.endFn.apply(a,[a.f/a.time]);
				a.inprogress = !1;
				if(!anims.length) T = clearInterval(T);
			}
		}
	}
	
	function giveValues(a){
		var transitions={};
		var fraction = a.trans=='linear'? a.f/a.time : trans(a.trans, a.f/a.time);
		for(var i=0,r,val=[]; r=a.ranges[i]; i++){
			if(!(r.trans in transitions))
				transitions[r.trans] = r.trans=='linear'? a.f/a.time : trans(r.trans, a.f/a.time);
			val[i] = r.from + r.delta*transitions[r.trans];
		}
		return val;
	}
	
	function trans(type, x){
		switch(type){
			case 'sin':
				return Math.sin(Math.PI*(x-0.5))/2+0.5;
			case 'koloIn':
				return Math.sqrt(1-(x-1)*(x-1));
			case 'koloOut':
				return -Math.sqrt(1-x*x)+1;
			case 'sinIn':
				return Math.sin(Math.PI*x/2);
			case 'sinOut':
				return -Math.cos(Math.PI*x/2)+1;
		}
	}
	
	return animation;
}
