
var animate = {
	/* Tweakables */
	quality: 10,
	duration: 500,
	zoom : {
		width: 195, // default zoomed Out size
		height: 120,
		from: 1,
		to:1.3,
		zDex: 100,
		duration: 150,
		easeIn: "easeInCubic",
		easeOut: "easeOutCubic"
	},
	fade : {
		from: 0,
		to : 1,
		duration: 500,
		easeIn: "easeInQuad",
		easeOut: "easeOutQuad"
	},
	pale : {
		from: 0.4,
		to : 1,
		duration: 200,
		easeIn: "easeInQuad",
		easeOut: "easeOutQuad"
	},
	/* Go */
	items:[],
	init: function(id, options){
		if(document.getElementById(id)){
			animate.items[id] = {};
			if (options && options.images){
				var imgs = document.getElementById(id).getElementsByTagName('img');
				for(i in imgs){
					if (imgs[i] && imgs[i].nodeType && imgs[i].nodeType == 1){
						if (imgs[i].className == 'small'){
							var theSmallId = imgs[i].id ? imgs[i].id : id+"_small";
							imgs[i].id = theSmallId;
							animate.items[id].smallImg = theSmallId;
						} else if(imgs[i].className == 'large') {
							var theLargeId = imgs[i].id ? imgs[i].id : id+"_large";
							imgs[i].id = theLargeId;
							animate.items[id].largeImg = theLargeId;
						}
					}
				}
			}
		}
	},
	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)}
			var n = dir > 0 ? animate[effect].to : animate[effect].from
			animate.set(id, dir, effect, n, options)
			if (options && options.images){
				animate.end(animate.items[id].smallImg, -dir, "fade");
				animate.end(animate.items[id].largeImg,  dir, "fade");
			}

			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);}
			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){
		animate.items[id].at = n;
		var obj_s = document.getElementById(id).style;
		switch(effect){
			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); },

	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
	 */
	linearTween:   function (t, b, c, d) {return c * t / d + b;},
	easeInQuad:    function (t, b, c, d) {return c * (t/=d)*t + b;},
	easeOutQuad:   function (t, b, c, d) {return -c * (t/=d)*(t-2) + b;},
	easeInOutQuad: function (t, b, c, d) {if ((t/=d/2) < 1){ return c/2*t*t + b;} else {return -c/2 * ((--t)*(t-2) - 1) + b;}},
	easeInCubic:   function (t, b, c, d) {return c * Math.pow (t/d, 3) + b;},
	easeOutCubic:  function (t, b, c, d) {return c * (Math.pow (t/d-1, 3) + 1) + b;},
	easeInOutCubic:function (t, b, c, d) {if ((t/=d/2) < 1) {return c/2 * Math.pow (t, 3) + b;} else {return c/2 * (Math.pow (t-2, 3) + 2) + b;}},
	easeInQuart:   function (t, b, c, d) {return c * Math.pow (t/d, 4) + b;},
	easeOutQuart:  function (t, b, c, d) {return -c * (Math.pow (t/d-1, 4) - 1) + b;},
	easeInOutQuart:function (t, b, c, d) {if ((t/=d/2) < 1)	{return c/2 * Math.pow (t, 4) + b;} else {return -c/2 * (Math.pow (t-2, 4) - 2) + b;}},
	easeInQuint:   function (t, b, c, d) {return c * Math.pow (t/d, 5) + b;},
	easeOutQuint:  function (t, b, c, d) {return c * (Math.pow (t/d-1, 5) + 1) + b;},
  easeInOutQuint:function (t, b, c, d) {if ((t/=d/2) < 1) {return c/2 * Math.pow (t, 5) + b;} else {return c/2 * (Math.pow (t-2, 5) + 2) + b;}},
  easeInSine:    function (t, b, c, d) {return c * (1 - Math.cos(t/d * (Math.PI/2))) + b;},
	easeOutSine:   function (t, b, c, d) {return c * Math.sin(t/d * (Math.PI/2)) + b;},
	easeInOutSine: function (t, b, c, d) {return c/2 * (1 - Math.cos(Math.PI*t/d)) + b;},
	easeInExpo:    function (t, b, c, d) {return c * Math.pow(2, 10 * (t/d - 1)) + b;},
	easeOutExpo:   function (t, b, c, d) {return c * (-Math.pow(2, -10 * t/d) + 1) + b;},
  easeInOutExpo: function (t, b, c, d) {if ((t/=d/2) < 1) {return c/2 * Math.pow(2, 10 * (t - 1)) + b;} else {return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;}},
	easeInCirc:    function (t, b, c, d) {return c * (1 - Math.sqrt(1 - (t/=d)*t)) + b;},
	easeOutCirc:   function (t, b, c, d) {return c * Math.sqrt(1 - (t=t/d-1)*t) + b;},
  easeInOutCirc: function (t, b, c, d) {if ((t/=d/2) < 1) {return c/2 * (1 - Math.sqrt(1 - t*t)) + b;} else {return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;}}
}
