/*******************************
class Effect.effect(parms)
parms = {
	target:[element to apply effects on]
	width,height,top,left,opacity,bottom,right,zIndex,backgroundColor,clip+(Top,Right,Bottom,Left):[properties to animate]
	duration:[duration in miliseconts]
	interval:[1000/fps]
	multi:[if true, this effect won't stop other effects running in the object (and won't be able to be stoped by other effects)]
	ease:[
		Effect.eases.sin [sinusiodal movement]
		Effect.eases.lin [linear movement]
	]
}

attributes:
	play() - starts the effect from the beggining
	stop() - stops the effect
	resume() - continues the execution of the stopped effect


EXTRAS:

function Effect.playEffect(parms)
	creates an effect and plays it automatically

*********************/


var Effect={};

Effect.DOMELM=function (elm) {
	this.self=elm;
}

var bIE = (navigator.userAgent.indexOf('MSIE') != -1);

Effect.DOMELM.prototype.settop=function(x){this.self.style.top=x+"px"}
Effect.DOMELM.prototype.gettop=function(){return this.self.offsetTop}
Effect.DOMELM.prototype.setleft=function(x){this.self.style.left=x+"px"}
Effect.DOMELM.prototype.getleft=function(){return this.self.offsetLeft}
Effect.DOMELM.prototype.setright=function(x){this.self.style.right=x+"px"}
Effect.DOMELM.prototype.getright=function(){return this.self.offsetRight}
Effect.DOMELM.prototype.setbottom=function(x){this.self.style.right=x+"px"}
Effect.DOMELM.prototype.getbottom=function(){return this.self.offsetRight}
Effect.DOMELM.prototype.setwidth=function(x){this.self.style.width=x+"px"}
Effect.DOMELM.prototype.getwidth=function(){return this.self.offsetWidth}
Effect.DOMELM.prototype.setheight=function(x){this.self.style.height=x+"px"}
Effect.DOMELM.prototype.getheight=function(){return this.self.offsetHeight}
Effect.DOMELM.prototype.setscrollLeft=function(x){this.self.scrollLeft=x}
Effect.DOMELM.prototype.getscrollLeft=function(){return this.self.scrollLeft}
Effect.DOMELM.prototype.setscrollTop=function(x){this.self.scrollTop=x}
Effect.DOMELM.prototype.getscrollTop=function(){return this.self.scrollTop}

/**********************************************************/
// Since we are allways going to process the 3 colors we only make the operation in the last setter and in the first getter
// Also keep in mind that the getter is only used once in the beggining, and after this we only use the sette, se there's no name conflict error
Effect.DOMELM.prototype.setbackgroundRed=function(x){this.backgroundRed=x}
Effect.DOMELM.prototype.getbackgroundRed=function(){
							var c=Effect.getRGB(this.self.style.backgroundColor)
							this.backgroundGreen=c[1]
							this.backgroundBlue=c[2]
							return c[0]
						}
Effect.DOMELM.prototype.setbackgroundGreen=function(x){this.backgroundGreen=x}
Effect.DOMELM.prototype.getbackgroundGreen=function(){return this.backgroundGreen}
Effect.DOMELM.prototype.setbackgroundBlue=function(x){
							this.self.style.backgroundColor='rgb('+Math.floor(this.backgroundRed)+','+Math.floor(this.backgroundGreen)+','+Math.floor(x)+')'
						}
Effect.DOMELM.prototype.getbackgroundBlue=function(){return this.backgroundBlue}
/**********************************************************/

Effect.DOMELM.prototype.setzIndex=function(x){this.self.style.zIndex=x}
Effect.DOMELM.prototype.getzIndex=function(){return this.self.style.zIndex}

if (!bIE) {
	Effect.DOMELM.prototype.setopacity=function(x){this.self.style.opacity=x}
	Effect.DOMELM.prototype.getopacity=function(){ var opa=this.self.style.opacity; return isNaN(parseInt(opa))?1:opa}
} else {
	Effect.DOMELM.prototype.setopacity=function(x){this.self.style.filter="alpha(opacity="+Math.floor(x*100)+")"}
	Effect.DOMELM.prototype.getopacity=function(){
		var opa=this.self.style.filter;
		if (opa.length && opa.indexOf("opacity")>=0) {
			opa=opa.substr(opa.indexOf("opacity")+8,3)
			while (isNaN(parseInt(opa))) {
				opa=opa.substr(0,opa.length-1)
			}
			opa=parseInt(opa)
		}
		return isNaN(parseInt(opa))?1:opa/100;
	}
}
Effect.getMiliseconds=function() {
	var dat=new Date();
	return dat.getTime();
}

Effect.Track=function (target,prop,dest) {
	this.target=target;
	this.prop=prop;
	this.dest=dest;
	this.orig=target["get"+prop]()
	this.travel=dest-this.orig
}

Effect.eases={}
Effect.eases.sin=function (x) {
	return (-Math.cos(x*Math.PI)/2) + 0.5
}
Effect.eases.lin=function (x) {
	return x
}

Effect.getRGB=function(c) {
	if (c == undefined || c == "" || c == "transparent") return [255,255,255]
	var rgb = c.match(/rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/);
	if (rgb) return [parseInt(rgb[1]),parseInt(rgb[2]),parseInt(rgb[3])]
	return [parseInt(c.substr(1,2),16),parseInt(c.substr(3,2),16),parseInt(c.substr(5,2),16)]
}

Effect.effect=function(info) {
	var loTarget;
	this.target;
	if (info.target) {
		this.target=new Effect.DOMELM(info.target);
		loTarget=info.target;
		delete info.target;
	} else {
		//alert("unknown target");
		this.play=function(){}
		this.resume=function(){}
		this.stop=function(){}
		return;
	}

	if (!info.multi) {
		if (loTarget.paj_internal_effect_ref) {
			loTarget.paj_internal_effect_ref.stop()
		}
		loTarget.paj_internal_effect_ref=this;
		delete info.unique
	}

	this.duration;
	if (info.duration) {
		this.duration=info.duration;
		delete info.duration;
	} else {
		this.duration=500;
	}

	this.interval;
	if (info.interval) {
		this.interval=info.interval;
		delete info.interval;
	} else {
		this.interval=1000/30; // 30fps
	}

	this.timer=0

	if (info.ease) {
		this.ease=info.ease;
		delete info.ease;
	} else {
		this.ease=Effect.eases.lin;
	}

	if (info.backgroundColor) {
		var c=Effect.getRGB(loTarget.style.backgroundColor)
		loTarget.backgroundRed=c[0]
		loTarget.backgroundGreen=c[1]
		loTarget.backgroundBlue=c[2]
		var c=Effect.getRGB(info.backgroundColor)
		info.backgroundRed=c[0]
		info.backgroundGreen=c[1]
		info.backgroundBlue=c[2]
		delete info.backgroundColor
	}

	this.tracks=[]
	for (var i in info) {
		this.tracks.push(new Effect.Track(this.target,i,info[i]));
	}
}

Effect.effect.prototype.play=function() {
	if (arguments.length==0) {
		clearInterval(this.timer);
		this.startTime=Effect.getMiliseconds();
		this.endTime=this.startTime+this.duration;
		var self=this;
		this.timer = setInterval(function(){self.play(true);}, this.interval);
		for (var i=0; i<this.tracks.length;i++) {
			var loT=this.tracks[i];
			this.target["set"+loT.prop](loT.orig);
		}
	} else {
		this.currentTime=Effect.getMiliseconds();
		if (this.currentTime<this.endTime) {
			var tOf = this.ease(1-(this.currentTime-this.startTime)/this.duration);
			for (var i=0; i<this.tracks.length;i++) {
				var loT=this.tracks[i];
				var ammount=loT.dest-tOf*loT.travel
				this.target["set"+loT.prop](ammount);
			}
		} else {
			clearInterval(this.timer);
			for (var i=0; i<this.tracks.length;i++) {
				var loT=this.tracks[i];
				this.target["set"+loT.prop](loT.dest);
			}
		}
	}
}

Effect.effect.prototype.stop=function() {
	clearInterval(this.timer);
}

Effect.effect.prototype.resume=function() {
	var lapsus=Effect.getMiliseconds()-this.currentTime;
	this.startTime+=lapsus
	this.endTime+=lapsus
	var self=this;
	this.timer = setInterval(function(){self.play(true);}, this.interval);
	this.play(true)
}

Effect.playEffect=function(info) {
	var loEff=new Effect.effect(info);
	loEff.play();
	return loEff;
}
