	function Tween(aTarget, aType, easeFunction, aFrom, aTo, aTime, aFps){
		this.callback=null;
		this.type=aType;
		this.from=aFrom;
		this.to=aTo;
		this.time=aTime;
		this.fps=aFps;
		this.target=aTarget;
		this.tweens=null;
		this.easing=easeFunction;
		if(this.easing==null || this.easing==undefined){
			this.easing=function(me){return Math.round(me.from+(me._step+1)*me._stepSize);};
		}
		this._intID=null;
		this._step=0;
		this._stepCount=0;
		this._reversed=false;
		this._state=0;/*0=stopped,1=playing,2=paused*/
		if(this.time!=null && this.fps!=null){
			this._stepCount=Math.round(this.time*(this.fps/1000));
		}
		this._stepSize=null;
		if(this.to!=null && this.from!=null && this._stepCount!=null){
			this._stepSize=(this.to-this.from)/this._stepCount;
		}
		this._styleSTR=null;
		this.cssSelector=null;
		
		this.modifyValue=function(r){
			return r;
		}
		this.doStep=function(me){
			if((this._reversed==false && me._step<me._stepCount) || (this._reversed==true && me._step>=0)){
				if(me.tweens!=null && me.tweens.length>0){
					for(var i=0; i<me.tweens.length; i++){
						me.tweens[i].doStep(me.tweens[i]);
					}
				}
				
				var stepValue=me.easing(me);//Math.round(me.from+me._step*me._stepSize);
				var modifiedStepValue=me.modifyValue(stepValue);
				for(var j=0; j<me._styleSTR.length; j++){
					var s=me._styleSTR[j].split("_VALUE_").join(stepValue);
					s=s.split("_MODIFIED-VALUE_").join(modifiedStepValue);
					me.target.style[me.cssSelector[j]]=s;
				}
				if(this._reversed==true){
					me._step--;
				}
				else{
					me._step++;
				}
				
			}
			else{
				if(me.intID!=null){
					clearInterval(me.intID);
					me.intID=null;
				}
				this.setRecursiveState(0);/*0=stopped,1=playing,2=paused*/
				this.initPlayback();
				if(this.callback){
					this.callback();
				}
			}
		}
		this.initPlayback=function(){
			if(this._reversed==true){
				this._step=this._stepCount-1;	
			}
			else{
				this._step=0;
			}
			if(this.tweens){
				for(var i=0; i< this.tweens.length; i++){
					this.tweens[i].initPlayback();
				}
			}
		}
		this.start=function(){
			this.initPlayback();
			this.play();
		}
		this.pause=function(){
			if(this.intID){
				clearInterval(this.intID);			
			}
			this.setRecursiveState(2);/*0=stopped,1=playing,2=paused*/	
		}
		this.stop=function(){
			if(this.intID){
				clearInterval(this.intID);			
			}
			if(this._reversed==true){
				this._step=this._stepCount-1;	
			}
			else{
				this._step=0;
			}
			if(this.tweens){
				for(var i=0; i< this.tweens.length; i++){
					this.tweens[i].stop();
				}
			}
			this._state=0;/*0=stopped,1=playing,2=paused*/	
		}
		this.play=function(){
			var runningTween=this;
			if(this.intID){
				clearInterval(this.intID);			
			}
			this.setRecursiveState(1);/*0=stopped,1=playing,2=paused*/	
			this.intID=setInterval(function(){runningTween.doStep(runningTween);},Math.round(1000/this.fps));
		}
		this.reverse=function(){
			this._reversed = !this._reversed;
			if(this._state==0){/*0=stopped,1=playing,2=paused*/
				if(this._reversed==true){
					this._step=this._stepCount-1;	
				}
				else{
					this._step=0;
				}
			}
			if(this.tweens){
				for(var i=0; i< this.tweens.length; i++){
					this.tweens[i].reverse();
				}
			}
		}
		this.setRecursiveState=function(state){
			this._state=state;/*0=stopped,1=playing,2=paused*/
			if(this.tweens){
				for(var i=0; i< this.tweens.length; i++){
					this.tweens[i].setRecursiveState(state);
				}
			}
		}
		this.setType=function(type){
			this.type=type;
			if(type=="top" || type=="left" || type == "bottom" || type== "right" || type=="width" || type=="height" || type=="margin-right" || type=="margin-left" || type=="margin-top" || type=="margin-bottom"){
				this._styleSTR=["_VALUE_px"];
				this.cssSelector=[type];
			}
			else if(type=="alpha"){
				this.cssSelector=["filter","-moz-opacity","opacity"];
				this._styleSTR=["alpha(opacity=_VALUE_)","_MODIFIED-VALUE_","_MODIFIED-VALUE_"];
				this.modifyValue=function(num){
					return num/100;
				}
			}
			else{
				alert("not suported: "+type);
			}	
		}
		
		if(this.type){//initialize _styleSTR and cssSelector
			this.setType(this.type);	
		}	
		this.setFromTo=function(from, to){
			this.from=from;
			this.to=to;
			this._stepSize=(this.to-this.from)/this._stepCount;
		}
		this.setTimeParams=function(time,fps){
			this.time=time;
			this.fps=fps;
			this._stepCount=Math.round(this.time*(this.fps/1000));
			if(this.to!=null && this.from!=null && this._stepCount!=null){
				this._stepSize=(this.to-this.from)/this._stepCount;
			}
			if(this.tweens){
				for(var i=0; i< this.tweens.length; i++){
					this.tweens[i].setTimeParams(time,fps);
				}
			}
		}
		this.addTween=function(tween){
			if(!this.tweens){
				this.tweens=[];
			}
			//tween.target=this.target;
			tween.setTimeParams(this.time,this.fps);
			//tween.setFromTo(tween.from,tween.to);
			this.tweens[this.tweens.length]=tween;
		}
		this.setRecursiveStep=function(aStep){
			this._step=aStep;	
			if(this.tweens){
				for(var i=0; i< this.tweens.length; i++){
					this.tweens[i].setRecursiveStep(aStep);
				}
			}
		}
		this.jumpToLast=function(){
			var aStep=this._stepCount-1;
			if(this._reversed==true){
				aStep=0;	
			}
			this.jumpTo(aStep);
		}
		this.jumpToFirst=function(){
			var aStep=0;
			if(this._reversed==true){
				aStep=this._stepCount-1;	
			}
			this.jumpTo(aStep);
		}
		this.jumpTo=function(aStep){
			this.setRecursiveStep(aStep);
			if(this._state!=1){/*0=stopped,1=playing,2=paused*/
				this.doStep(this);
			}
			if(this._state==0){/*0=stopped,1=playing,2=paused*/
				this.stop();	
			}
		}
	}