var curstyle = null;

function getCurrentStyle(elem, prop) {
  if( elem.currentStyle ) {  
    return elem.currentStyle[prop];
  }
  else if( document.defaultView.getComputedStyle )
  {
    return document.defaultView.getComputedStyle(elem, null).getPropertyValue(prop);
  }
}

function bezier(x0, x1, x2, t) {
	return (1-t)*(1-t)*x0 + 2*(t-t*t)*x1 + t*t*x2;
}

function Property(oObj, name, end_val, prefix, suffix, animstrength) {
	var elm = oObj;
  var prop = name;
  var x0 = 0;
  cur = getCurrentStyle(elm, prop);
  if (cur.length > prefix.length + suffix.length) {
  	x0 = parseFloat(cur.substr(prefix.length, cur.length-prefix.length-suffix.length));
  }
  var x1 = end_val;
  var dx = x1 - x0;
  var xbez = x1 + (dx*animstrength);
  
  this.set = function(t) {
  	elm.style[prop] = prefix + bezier(x0, xbez, x1, t) + suffix;
  }
}

function Animation(oObj, time) {
	var element = oObj;
	var properties = [];
	var postfunctions = [];
	var t0 = 0;
	var t1 = 0;
	var dt = time;
	var hardStop = 0;
	
	this.stop = function() {
		hardStop = 1;
	}
	
	this.paint = function(el) {
		if (!t1 || hardStop) return 1;
		
		var t = (el - t0) / dt;
		if (t > 1) t = 1;
		
		for (var i=0; i<properties.length; i++) {
			properties[i].set(t);
		}
		
		if (t == 1) {
			for (var j=0; j<postfunctions.length; j++) {
				postfunctions[j]();
			}
			return 1;
		}
		else return 0;
	}
	
	this.start = function() {
		t0 = new Date().getTime();
		t1 = t0 + dt;
	}
	
	this.addProperty = function(name, end_val, prefix, suffix, astrength) {
		if (!astrength) astrength = -.5;
		properties[properties.length] = new Property(element, name, end_val, prefix, suffix, astrength);
	}

	this.addPostFunction = function(func) {
		postfunctions[postfunctions.length] = func;
	}
}

function AnimationEngine() {
	var animations = [];
	var timer = null;
	
	
	this.addAnimation = function(oAnim) {
		var idx = animations.length;
		animations[idx] = oAnim;
		if (idx == 0) startEngine();
		oAnim.start();
	}
	
	function startEngine() {
		if (timer) stopEngine();
		timer = setInterval(paintAll, 10);
	}
	
	function stopEngine() {
		clearInterval(timer);
		timer = null;
	}
	
	function paintAll() {
		if (!curstyle) curstyle = document.body.currentStyle ? "currentStyle" : "style"

		var t = new Date().getTime();
		
		for (var i=0; i<animations.length; ) {
			if (animations[i].paint(t)) animations.splice(i, 1);
			else i++;
		}
		
		if (animations.length == 0) stopEngine();
	}
}
