
var animate = {
	/* Tweakables */
	quality: 10,
	slip : {
		width: 213,
		to: function (){return animate.slip.width && animate.slip.ind !== null && animate.slip.ind < 8 ? animate.slip.width * animate.slip.ind : 0},
		duration: 500,
		easeOut: "linear"
	},
	/* Go */
	items:[],
	init: function(id, options){
		if(document.getElementById(id)){
			animate.items[id] = {};
		}
	},
	end: function(id, dir, effect, options){
		if(document.getElementById && document.getElementById(id)){
			if (animate.items[id] == null) {animate.init(id, options);}
			if(animate.items[id].interval){clearInterval(animate.items[id].interval)}
			if (options && options.ind !== null) {animate[effect].ind = options.ind}
			var n = dir > 0 ? animate[effect].to() : animate[effect].from;
			animate.set(id, dir, effect, n, options);
			animate.items[id].isAnimating = false;
		}
	},
	start: function(id, dir, effect, options) {
		if(document.getElementById && document.getElementById(id)){
			if (animate.items[id] == null) {animate.init(id, options);}
			if (options && options.ind !== null) {animate[effect].ind = options.ind}
			animate.items[id].isAnimating = true;
			if (animate.items[id].at == null) {
				animate.items[id].at = dir > 0 ? animate[effect].to() : animate[effect].from;
			}
			var obj = document.getElementById(id);
			switch(effect) {
				case "zoom":
					animate.zoom.zDex++;
					obj.parentNode.style.zIndex = animate.zoom.zDex;
				break;
				case "fade":
					obj.style.display = 'block';
				break;
			}
			if(animate.items[id].interval){clearInterval(animate.items[id].interval)}
			animate.items[id].time = 0;
			animate.items[id].interval = setInterval("animate.run('"+id+"',"+dir+",'"+effect+"')", animate.quality);
			if (options && options.images){
				animate.start(animate.items[id].largeImg,  dir, "fade");
				animate.start(animate.items[id].smallImg, -dir, "fade");
			}
		}
	},
	run: function(id, dir, effect){
		if (animate.items[id] == null) {animate.init(id);}
		if(animate.items[id].time >= animate[effect].duration){
			animate.end(id, dir, effect);
		} else {
			var n = 1;
			var time = animate.items[id].time += animate.quality;
			var begin = animate.items[id].at;
			var change = dir > 0 ? animate[effect].to() - animate.items[id].at : animate[effect].from - animate.items[id].at;
			var duration = animate[effect].duration;
			var easeDir = dir > 0 ? "easeOut" : "easeIn";
			n = ease[animate[effect][easeDir]](time, begin, change, duration);
			animate.set(id, dir, effect, n);
		}
	},
	set: function(id, dir, effect, n, options){
		if (options && options.ind !== null) {animate[effect].ind = options.ind}
		animate.items[id].at = n;
		var obj_s = document.getElementById(id).style;
		switch(effect){
			case "slip":
				obj_s.left = -Math.round(n)+"px";
			break;
			case "zoom":
				obj_s.width  =  Math.floor(  animate.zoom.width  * n) +"px";
				obj_s.height =  Math.floor(  animate.zoom.height * n) +"px";
				obj_s.top    = -Math.floor(((animate.zoom.height * n) - animate.zoom.height) / 2) + "px";
				obj_s.left   = -Math.floor(((animate.zoom.width  * n) - animate.zoom.width ) / 2) + "px";
			break;
			case "fade": //it's supposed to go through :)
			case "pale":
				obj_s.display = n ? 'block' : 'none';
				if (!(options && options.switchIE && browser.ie))  {
					//It doesn't like this being set on semi-transparent pngs. gets all crappy looking.
					obj_s.opacity = n;
					obj_s.filter  = "alpha(opacity="+n*100+")";
				}
			break;
		}
	},
	// Syntactic Sugar :)
	fadeIn  : function (id, options){if (options && options.switchIE && browser.ie){animate.show(id, options)} else {animate.start(id, 1, 'fade', options);} },
	fadeOut : function (id, options){if (options && options.switchIE && browser.ie){animate.hide(id, options)} else {animate.start(id,-1, 'fade', options);} },
	show    : function (id, options){ animate.end  (id, 1, 'fade', options); },
	hide    : function (id, options){ animate.end  (id,-1, 'fade', options); },

  slide   : function (id, options){ animate.start(id, 1, 'slip', options); },
	jump    : function (id, options){ animate.end  (id, 1, 'slip', options); },


	grow    : function (id, options){ animate.start(id, 1, 'zoom', options); },
	shrink  : function (id, options){ animate.start(id,-1, 'zoom', options); },
	grown   : function (id, options){ animate.end  (id, 1, 'zoom', options); },
	shrunk  : function (id, options){ animate.end  (id,-1, 'zoom', options); },

	darken  : function (id, options){ animate.start(id, 1, 'pale', options); },
	lighten : function (id, options){ animate.start(id,-1, 'pale', options); },
	dark    : function (id, options){ animate.end  (id, 1, 'pale', options); },
  light   : function (id, options){ animate.end  (id,-1, 'pale', options); }
}
var ease = {
	/*#^ FROM http://www.robertpenner.com/easing/penner_chapter7_tweening.pdf ^#*/
	/* t is time
	 * b is begin number
	 * c is end number
	 * d is duration
	 */
	linear:    function(t,b,c,d){return c*t/d+b;},
	InQuad:    function(t,b,c,d){return c*(t/=d)*t+b;},
	OutQuad:   function(t,b,c,d){return -c*(t/=d)*(t-2)+b;},
	InOutQuad: function(t,b,c,d){return (t/=d/2)<1?c/2*t*t+b:-c/2*((--t)*(t-2)-1)+b},
	InCubic:   function(t,b,c,d){return c*Math.pow(t/d,3)+b;},
	OutCubic:  function(t,b,c,d){return c*(Math.pow(t/d-1,3)+1)+b;},
	InOutCubic:function(t,b,c,d){return (t/=d/2)<1?c/2*Math.pow(t, 3)+b:c/2*(Math.pow(t-2,3)+2)+b},
	InQuart:   function(t,b,c,d){return c*Math.pow(t/d,4)+b;},
	OutQuart:  function(t,b,c,d){return -c*(Math.pow(t/d-1,4)-1)+b;},
	InOutQuart:function(t,b,c,d){return (t/=d/2)<1?c/2*Math.pow(t,4)+b:-c/2*(Math.pow(t-2,4)-2)+b},
	InQuint:   function(t,b,c,d){return c*Math.pow(t/d,5)+b;},
	OutQuint:  function(t,b,c,d){return c*(Math.pow(t/d-1,5)+1)+b;},
  InOutQuint:function(t,b,c,d){return (t/=d/2)<1?c/2*Math.pow(t,5)+b:c/2*(Math.pow(t-2,5)+2)+b},
  InSine:    function(t,b,c,d){return c*(1-Math.cos(t/d*(Math.PI/2)))+b;},
	OutSine:   function(t,b,c,d){return c*Math.sin(t/d*(Math.PI/2))+b;},
	InOutSine: function(t,b,c,d){return c/2*(1-Math.cos(Math.PI*t/d))+b;},
	InExpo:    function(t,b,c,d){return c*Math.pow(2,10*(t/d-1))+b;},
	OutExpo:   function(t,b,c,d){return c*(-Math.pow(2,-10*t/d)+1)+b;},
  InOutExpo: function(t,b,c,d){return (t/=d/2)<1?c/2*Math.pow(2,10*(t-1))+b:c/2*(-Math.pow(2,-10*--t)+ 2)+b},
	InCirc:    function(t,b,c,d){return c*(1-Math.sqrt(1-(t/=d)*t))+b;},
	OutCirc:   function(t,b,c,d){return c*Math.sqrt(1-(t=t/d-1)*t)+b;},
  InOutCirc: function(t,b,c,d){return (t/=d/2)<1?c/2*(1-Math.sqrt(1-t*t))+b:c/2*(Math.sqrt(1-(t-=2)*t)+1)+b}
}
