function getTimer(){
	return new Date().getTime();
}

var Tweener = {
	tweens : new Array(),	
	init : function(){
		setInterval("intervalDispatcher()", 20);
	},
	
	onEnterFrame : function(){
		var time = getTimer();
		for(var i=this.tweens.length-1;i>=0; i--){
			if(this.tweens[i].act(time)){
				var obj = this.tweens[i];
				this.tweens.splice(i,1);
				obj.dispatchEvent({type:"onDone", target:obj, element:obj.element})
			}
		}
	},
	
	start : function(element, variable, value, time, args){
		if(!args){
			args = {};
		}
		for(var i=this.tweens.length-1;i>=0; i--){
			if(this.tweens[i].element == element && this.tweens[i].vaname == variable){
				this.tweens.splice(i,1);
			}
		}
		var tw = new TweenWorker($(element), variable, value, time, args);
		this.tweens.push(tw)
		return tw;
	}
}

Tweener.init();

function TweenWorker(e, va, v, t, args){
	EventDispatcher.initialize(this);
	this.element = e;
	this.vaname = va;
	
	if(va.indexOf("f_") == 0){
		var func = va.substring(2,200);
		this.variable = this.element[func];
	} else {
		this.variable = Tweener.Variables[va];
	}

	this.time = t;
	this.args = args;
	this.mode = args.mode ? args.mode : Tweener.Transitions.sinoidal;
	
	if(this.args.start != undefined){
		this.variable.set(this.element, this.args.start);
		this.startValue = this.args.start;
	} else {
		this.startValue = this.variable.get(this.element);
	}
	
	this.deltaValue = v - this.startValue
	this.startTime = getTimer();
	
	this.act = function(t){
		var delta = t-this.startTime;
		if(delta>=this.time || this.deltaValue == 0){
			this.setTween(1);
			return true;
		} else {
			this.setTween(delta / this.time);
			return 0;
		}
	}
	
	this.setTween = function (percent){
		this.variable.set(this.element, this.startValue + this.deltaValue * this.mode(percent));
	}
}



Tweener.Transitions = {}

Tweener.Transitions.linear = function(pos) {
  return pos;
}
Tweener.Transitions.sinoidal = function(pos) {
  return (-Math.cos(pos*Math.PI)/2) + 0.5;
}
Tweener.Transitions.reverse  = function(pos) {
  return 1-pos;
}
Tweener.Transitions.flicker = function(pos) {
  return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
}
Tweener.Transitions.wobble = function(pos) {
  return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
}
Tweener.Transitions.pulse = function(pos) {
  return (Math.floor(pos*10) % 2 == 0 ? 
    (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));
}


Tweener.Variables = {}
Tweener.Variables.opacity = {}
Tweener.Variables.opacity.get = function(element){  
  var opacity;
  if (opacity = Element.getStyle(element, 'opacity'))  
    return parseFloat(opacity);  
  if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))  
    if(opacity[1]) return parseFloat(opacity[1]) / 100;  
  return 1.0;  
}

Tweener.Variables.opacity.set = function(element, value){  
  element= $(element);  
  if (value == 1){
    Element.setStyle(element, { opacity: 
      (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 
      0.999999 : null });
    if(/MSIE/.test(navigator.userAgent))  
      Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});  
  } else {  
    if(value < 0.00001) value = 0;  
    Element.setStyle(element, {opacity: value});
    if(/MSIE/.test(navigator.userAgent))  
     Element.setStyle(element, 
       { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
                 'alpha(opacity='+value*100+')' });  
  }  
} 



Tweener.Variables.x = {}
Tweener.Variables.x.get = function(element){  
	var x;
  if (x = Element.getStyle(element, 'left'))  
    return parseFloat(x);
  return 0;  
}

Tweener.Variables.x.set = function(element, value){  
   value = Math.floor(value);
	 Element.setStyle(element, { left: value + "px"}); 
} 


Tweener.Variables.y = {}
Tweener.Variables.y.get = function(element){  
	var y;
  if (y = Element.getStyle(element, 'top'))  
    return parseFloat(y);
  return 0;  
}

Tweener.Variables.y.set = function(element, value){  
   value = Math.floor(value);
	 Element.setStyle(element, { top: value + "px"}); 
} 


Tweener.Variables.width = {}
Tweener.Variables.width.get = function(element){  
	var w;
  if (w = Element.getStyle(element, 'width'))  
    return parseFloat(w);
  return 0;  
}

Tweener.Variables.width.set = function(element, value){  
   value = Math.floor(value);
	 Element.setStyle(element, { width: value + "px"}); 
} 


Tweener.Variables.height = {}
Tweener.Variables.height.get = function(element){  
	var h;
  if (h = Element.getStyle(element, 'height'))  
    return parseFloat(h);
  return 0;  
}

Tweener.Variables.height.set = function(element, value){  
   value = Math.floor(value);
	 Element.setStyle(element, { height: value + "px"}); 
}

function intervalDispatcher(){
	Tweener.onEnterFrame();
}
