/*  Juice Library effects.juice.js, version 0.1.1.20071229
 *  Copyright (c) 2007, 2008 Stephen Whiteley (http://jui.ce.it)
 *
 *  See core.juice.js for full license.
 *
/*--------------------------------------------------------------------------*/

(function() {

	if ( typeof Juice == 'undefined' ) {
		throw new Error( 'effects.juice.js requires the core.juice.js component.' );
	}

	Juice.Effect = new function() {

		var effects = [];

		this.track = new function() {

			this.add = function( e, t, c ) {

				effects.push( { ele: e, effect: t, config: c } );

			};

			this.fetch = function( e, t ) {

				for ( var i in effects ) {
					var effect = effects[i];
					if ( effect.ele == e && effect.effect == t  ) {
						return effect;
					}
				}

				return false;

			};

			this.tidy = function( e, t ) {

				for ( var i in effects ) {
					var effect = effects[i];
					if ( effect.ele == e && effect.effect == t  ) {
						delete effect;
						return true;
					}
				}

				return false;

			};

		};

		this.fader = new function() {

			var myself = this, effect = 'fader';

			this.create = function( id ) {

				var n;

				if ( n = Juice.Effect.track.fetch( Juice.$( id ), effect ) ) {
					return n;
				} else {
					n = { ele: Juice.$( id ), config: { interval: 5, duration: 500 } };
				}

				if ( n.ele.style.visibility == 'hidden' ) {
					n.config.opacity = 0;
				} else {
					n.config.opacity = 100;
				}

				Juice.Effect.track.add( n.ele, effect, n.config );

				return n;

			};

			this.start = function( n, d ) {

				n.config.started = new Date().getTime();

				if ( d ) {
					n.config.direction = d;
				}

				n.ele.style.visibility = 'visible';

				n.config.timer = setInterval( function() {
					myself.fade( n );
				}, n.config.interval );

			};

			this.show = function( id ) {

				var n = myself.create( id );

				if ( !n || n.config.running || n.ele.style.visibility != 'hidden' ) { return; }

				n.config.running = true;

				myself.start( n, 'show' );

				return;

			};

			this.hide = function( id ) {

				var n = myself.create( id );

				if ( !n || n.config.running || n.ele.style.visibility == 'hidden' ) { return; }

				n.config.running = true;

				myself.start( n, 'hide' );

				return;

			};

			this.fade = function( n ){

				var t = new Date().getTime() - n.config.started;

				if ( t > n.config.duration ) {

					myself.stop( n );

				} else {

					var o = Juice.Effect.ease( t, n.config.duration, n.config.opacity );

					if ( n.config.direction == 'hide' ) {
						o = n.config.opacity - o;
					}

					Juice.Element.opacity( n.ele, o );

				}

				return;

			};

			this.stop = function( n ){

				clearInterval( n.config.timer );

				if ( n.config.direction == 'hide' ) {
					n.ele.style.visibility = 'hidden';
					Juice.Element.opacity( n.ele, 0 );
				} else {
					n.ele.style.visibility = 'visible';
					Juice.Element.opacity( n.ele, 100 );
				}

				n.config.running = false;

				Juice.Effect.track.tidy( n.ele, effect );

			};

			this.toggle = function( id ) {

				var n = myself.create( id );

				if ( n.config.running ) { return; }

				myself.start( n, ( n.ele.style.visibility != 'hidden' ? 'hide' : 'show' ) );

			};

		};

		this.slider = new function() {

			var myself = this, effect = 'slider';

			this.create = function( id ) {

				var n;

				if ( n = Juice.Effect.track.fetch( Juice.$( id ), effect ) ) {
					return n;
				} else {
					n = { ele: Juice.$( id ), config: { interval: 5, duration: 300 } };
				}

				if ( !n.config.height ) {
					if ( n.ele.style.display == 'none' ) {
						n.ele.style.display = '';
					}
					n.config.height = Juice.Element.dimensions( n.ele ).height;
				}

				Juice.Effect.track.add( n.ele, effect, n.config );

				return n;

			};

			this.start = function( n, d ) {

				n.config.started = new Date().getTime();

				if ( n.config.direction == 'hide' ){
					n.ele.style.height = 0;
				}

				n.ele.style.display = 'block';

				if ( d ) {
					n.config.direction = d;
				}

				n.config.timer = setInterval( function() {
					myself.slide( n );
				}, n.config.interval );

			};

			this.show = function( id ) {

				var n = myself.create( id );

				if ( !n || n.config.running || n.ele.style.display != 'none' ) { return; }

				n.config.running = true;

				myself.start( n, 'show' );

				return;

			};

			this.hide = function( id ) {

				var n = myself.create( id );

				if ( !n || n.config.running || n.ele.style.display == 'none' ) { return; }

				n.config.running = true;

				myself.start( n, 'hide' );

				return;

			};

			this.slide = function( n ){

				var t = new Date().getTime() - n.config.started;

				if ( t > n.config.duration ) {

					myself.stop( n );

				} else {

					var h = Juice.Effect.ease( t, n.config.duration, n.config.height );

					if ( n.config.direction == 'hide' ) {
						h = n.config.height - h;
					}

					n.ele.style.height = h + 'px';

				}

				return;

			};

			this.stop = function( n ){

				clearInterval( n.config.timer );

				if ( n.config.direction == 'hide' ) {
					n.ele.style.display = 'none';
				} else {
					n.ele.style.display = 'block';
					n.ele.style.height = n.config.height + 'px';
				}

				n.config.running = false;

				Juice.Effect.track.tidy( n.ele, effect );

			};

			this.toggle = function( id ) {

				var n = myself.create( id );

				if ( n.config.running ) { return; }

				myself.start( n, ( n.ele.style.display != 'none' ? 'hide' : 'show' ) );

			};

		};

		this.blender = new function() {

			var myself = this, effect = 'blend';

			this.create = function( id, to, from, callback ) {

				var n = {
					ele: Juice.$( id ),
					config: {
						interval: 1,
						percent: 0,
						to: to,
						callback: callback
					}
				};

				if ( from ) {
					n.config.from = from;
				} else {
					var bg = Juice.Element.style( Juice.$( id ), 'backgroundColor' );
					n.config.from = Juice.Type.hexColour( bg ) ? bg : Juice.Convert.fullrgbhex( bg );
				}

				Juice.Effect.track.add( n.ele, effect, n.config );

				return n;

			};

			this.stop = function( n ) {

				clearInterval( n.config.timer );

				n.config.running = false;

				Juice.Effect.track.tidy( n.ele, effect );

			}

			this.blend = function( n ) {

				if ( n.config.percent >= 100 ) { myself.stop( n ); }

				n.config.percent++;

				var start	= Juice.Convert.hexrgb( n.config.from );
				var end		= Juice.Convert.hexrgb( n.config.to );
				var percent = n.config.percent / 100;

				var current = {
					r: Math.floor( start.r + ( percent * ( end.r - start.r ) ) ),
					g: Math.floor( start.g + ( percent * ( end.g - start.g ) ) ),
					b: Math.floor( start.b + ( percent * ( end.b - start.b ) ) )
				}

				var colour = Juice.Convert.rgbhex( current.r, current.g, current.b );

				if ( !colour ) { return };

				if ( Juice.Type.callback( n.config.callback ) ) {
					n.config.callback( colour, n.ele );
				} else {
					n.ele.style.backgroundColor = colour;
				}

			};

			this.show = function( id, to, from, callback ) {

				if ( !id || !to ) { return false; }

				var n = myself.create( id, to, from, callback );

				if ( !n || n.config.running ) { return; }

				n.config.running = true;
				n.config.percent = 0;

				n.config.timer = setInterval( function() {
					myself.blend( n );
				}, n.config.interval );

			};

		};

		this.resize = function( n, s ) {

			var myself = this;

			this.setup = function() {

				n = Juice.$( n );

				var d = Juice.Element.dimensions( n );

				if ( s.width ) {
					var mw = new myself.move( parseInt( s.width ), d.width, s.velocity );
					var w = setInterval( function() {
						if ( mw.stopped() == true ) {
							clearInterval( w );
						}
						n.style.width = mw.update() + 'px';
					}, 15 );
				}

				if ( s.height ) {
					var mh = new myself.move( parseInt( s.height ), d.height, s.velocity );
					var h = setInterval( function() {
						
						if ( mh.stopped() == true ) {
							clearInterval( h );
						} else {
							n.style.height = mh.update() + 'px';
						}
					}, 15 );
				}

			};

			this.move = function( targ, pos, vel ) {

				var p, t, v;

				this.setup = function() {
					p = Math.round( pos );
					t = Math.round( targ );
					v = ( vel ? Math.round( vel ) : 0 );
				};

				this.update = function() {
					p += v;
					if ( v < 0 ){
						if ( p - v * ( v - 1 ) / 2 < t ) {
							v++;
						} else if ( p - ( v - 1 ) * ( v - 2 ) / 2 >= t ) {
							v--;
						}
					} else {
						if ( p + v * ( v + 1 ) / 2 > t ){
							v--;
						} else if ( p + ( v + 1 ) * ( v + 2 ) / 2 <= t ){
							v++;
						}
					}
					return p;
				};

				this.stopped = function() {
					return ( p == t && v == 0 );
				};

				this.setup();

			};

			this.setup();

		};

		this.ease = function( e, d, c ) {

			return Math.round( e / d * c );

		};

	}

})();
