var slideshow = (function($)
{
	var _msie = false;
	
	/*
		IE's compositor sucks. During animation, the transparent images
		drag their background with them. To force a recomposite of the slide,
		we need to resize the slide. So we bump it wider by 2 and narrower by 2.
	*/
	function wiggle( container ) {
		
		if ( !_msie ) return function(){};
		
		return function()
		{
			container
				.css( { width: container.outerWidth() + 2 + 'px' })
				.css( { width: container.outerWidth() - 2 + 'px' });
		}
	}
	
	function isNumeric( d )
	{
		return d !== undefined && !isNaN(parseFloat(d)) && isFinite(d);
	}
	
	var _Slide = function(params)
	{
		var scope = this;
		this._params = params;		
		this.positions = {};
		this.slide().children().each(function(){
			scope.positions[$(this).index()] = $(this).position();
		})
	}
	
	_Slide.prototype = {
		transitionIn: function( duration, onComplete )
		{
			if ( $.isFunction( this._params.intro ) )
			{				
				this._params.intro.call( this, duration );
				
				setTimeout(function()
				{
					if ( $.isFunction(onComplete)) onComplete();
				}, duration + 1 );
			}
		},
		transitionOut: function( duration )
		{
			var delay = 0;
			if ( $.isFunction( this._params.outro ) )
			{
				var d = this._params.outro.call( this, duration );
				if ( isNumeric(d) ) delay = d;
			}
			
			return delay;
		},
		
		slide: function() { return this._params.slide; },
		id: function() { return this._params.slide.attr( 'id' ); },
		originalPosition: function( obj ) { return this.positions[obj.index()]; },
		msie: function() { return _msie; }
	}
	
	function _Slideshow(params)
	{
		var scope = this;
		this.params = $.extend({
			initialSlide: 0,
			nextSlideTimeout: 0,
			transitionDuration: 500
		}, params );

		this._currentSlideId = null;
		this._hovering = false;
		this._dots = [];


		//
		//	Create and configure dots
		//
		
		$(this.params.slides).each(function()
		{
			var slide = this,
			    identifier = slide.id();
			
			slide.slide().hide();
			
			var dot = scope.params.paginatorFactory(identifier);
			scope.params.paginator.append( dot );
			
			dot.click(function()
			{
				scope.setSlide( $(this).attr('rel'));
				return false;
			})
			
			scope._dots.push(dot);
		})
				
		//
		//	Show first slide
		//

		if ( isNumeric(this.params.initialSlide) )
		{
			this.setSlide( this.params.slides[this.params.initialSlide % this.params.slides.length].id(), false );
		}
		else
		{
			$(this.params.slides).each(function()
			{
				if ( this.id() == this.params.initialSlide )
				{
					this.setSlide( this.id(), false );
				}
			})
		}
		
		//
		//	Configure timeout
		//

		if ( params.nextSlideTimeout > 0 )
		{
			this.params.slideshowContainer.hover(function()
			{
				scope._hovering = true;
			}, function()
			{
				scope._hovering = false;
			})
			
			setInterval( function()
			{
				if ( !scope._hovering )
				{
					scope.nextSlide();
				}
			}, this.params.nextSlideTimeout );
		}
		
		params.nextTrigger.click( function(){ scope.nextSlide(); return false; });
		params.prevTrigger.click( function(){ scope.prevSlide(); return false; });
	}

	_Slideshow.prototype = {

		setSlide: function( slideId, animate )
		{
			animate = animate == undefined ? true : animate;
			var scope = this;

			//
			//	Play out the previous slide
			//

			var introDelay = 0;
			$(this.params.slides).each(function()
			{
				var slide = this;
				if ( slide.id() == scope._currentSlideId )
				{
					introDelay = slide.transitionOut( scope.params.transitionDuration );
					
					if ( animate )
					{
						slide.slide().fadeOut( scope.params.transitionDuration);
					}
					else
					{
						slide.slide().hide();
					}
					
				}
			});

			//
			//	Bring in the new slide
			//
			this._currentSlideId = slideId;
			$(this.params.slides).each(function()
			{
				var slide = this;
				
				if ( slide.id() == slideId )
				{
					slide
						.slide()
							.hide()
							.parent()
								.append(slide.slide());

					if ( animate )
					{
						slide.slide().delay(introDelay).fadeIn(scope.params.transitionDuration, wiggle( scope.params.slideshowContainer ));
					}
					else
					{
						setTimeout(function()
						{
							slide.slide().show();
							wiggle( scope.params.slideshowContainer )();
						}, introDelay );
					}
					
					// play introduction
					setTimeout(function()
					{
						slide.transitionIn( scope.params.transitionDuration, wiggle( scope.params.slideshowContainer ) );
					}, introDelay );
				}
			})
			
			$(this._dots).each(function()
			{
				var dot = $(this);
				dot.toggleClass( 'active', dot.attr('rel').indexOf(slideId) == 0 );
			});			
		},
		
		nextSlide: function()
		{
			var scope = this;
			$(this.params.slides).each(function( idx )
			{
				if ( this.id() == scope._currentSlideId )
				{
					var nextSlide = scope.params.slides[(idx + 1) % scope.params.slides.length];
					scope.setSlide( nextSlide.id());
					return false;
				}
			});
		},

		prevSlide: function()
		{
			var scope = this;
			$(this.params.slides).each(function( idx )
			{
				if ( this.id() == scope._currentSlideId )
				{
					var prevSlide = scope.params.slides[(idx + scope.params.slides.length - 1) % scope.params.slides.length];
					scope.setSlide( prevSlide.id());
					return false;
				}
			});
		}

	}

	//
	//	SliderShow
	//

	var _FlowView = function(params)
	{
		var scope = this;
		this.params = $.extend( {
			padding: 20,
			rate: 30
		}, params );

		this._intervalId = 0;
		this._sliderPosition = 0;
		this.init();
		
		$(window).bind( 'resize orientationchange', function(e){
			scope._reset();
			scope._layoutSlides();
			scope._layout();
		})
	}

	_FlowView.prototype = {
		init:function()
		{			
			this.slides().css({
				margin: 0,
				padding: 0,
				position: 'absolute',
				left: 0 + 'px'
			});
			
			this.params.slideContainer.css({
				position: 'absolute',
				left: 0,
				top: 0
			});
			
			var containerParent = this.params.slideContainer.parent();
			containerParent.css({
				height: this.params.slideContainer.outerHeight() + 'px'
			});
			
			if ( containerParent.css( 'position' ) != 'absolute' )
			{
				containerParent.css( 'position', 'relative' );
			}
			

			this._layoutSlides();
			this._layout();			
		},
		
		slides: function(){ return this.params.slideContainer.children(); },
		
		start: function()
		{
			if ( this.running() )
			{
				this.stop();
			}

			//
			//	compute an optimum fps - no more than 60 - and a subsequent per-frame increment
			//

			this.params.rate = Math.abs( this.params.rate );
			this._fps = 30;
			this._frameIncrement = this.params.rate / this._fps;

			//console.log( 'this.params.rate: ', this.params.rate, ' fps: ', this._fps, ' frameIncrement: ', this._frameIncrement );
			
			var scope = this;
			this._intervalId = setInterval( function(){
				scope._layout( -scope._frameIncrement );
			}, (1000/this._fps) );
		},
		
		stop: function()
		{
			if ( this._intervalId )
			{
				clearInterval( this._intervalId );
				this._intervalId = 0;
			}
		},
		
		running: function()
		{
			return this._intervalId != 0;
		},
		
		_reset: function()
		{
			/*
			this._sliderPosition = 0;
			this.params.slideContainer.css({
				left: 0
			})
			*/
		},
		
		_layoutSlides: function()
		{
			var scope = this;
			var x = 0;
			var verticalCenter = this.params.slideContainer.innerHeight()/2;

			this.slides().each( function(idx)
			{
				$(this).css({
					left: x + 'px',
					top: (verticalCenter - $(this).outerHeight()/2) + 'px'
				});
				
				x += $(this).outerWidth() + scope.params.padding;
			});
			
			this.params.slideContainer.css({
				width: x + 'px'
			})
			
		},
		
		_layout: function( dx )
		{
			dx = dx === undefined ? 0 : dx;
			
			var scope = this;
			var slides = this.slides();
			var slideContainer = this.params.slideContainer;
			
			this._sliderPosition += dx;

			slideContainer.css( {
				left: this._sliderPosition + 'px'
			})
								
			while( true )
			{
				var slides = this.slides();						
				var firstSlideRight = this._right( slides.first(), this.params.padding )
				if ( parseInt(slideContainer.css( 'left' )) + firstSlideRight < 0 )
				{
					this._sliderPosition += firstSlideRight;
					slideContainer.css({
						left: this._sliderPosition + 'px'
					});

					// now we need to move the hidden slide to the end of the stack
					slideContainer.append( slides.first() );
					this._layoutSlides();
				}
				else
				{
					break;
				}
			}
		},				

		_right: function( slide, padding )
		{
			return slide.position().left + slide.outerWidth() + padding;
		}
	}
	
	//
	//	Mark if running IE
	//

	$(function()
	{
		if ( $.browser.msie !== undefined )
		{
			_msie = true;
			$('body').addClass( 'msie' );
		}
	})
	
	///////////////////////////////////////////////////////////

	return {
		Slideshow: _Slideshow,
		Slide: _Slide,
		FlowView: _FlowView
	}
				
})(jQuery);
// mini jquery easing
jQuery.extend( jQuery.easing,
{
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	}
});

jQuery(function($)
{	
	//
	//	FlowView configuration for quotes in #hero-quotes
	//

	var quotesFV = new slideshow.FlowView({				
		slideContainer: $('#hero-quotes-flow-view .flow-container'),
		rate: 30
	})	
	
	//
	//	Slide configuration
	//
	
	function intro( slide, elements, slideTransitionDuration )
	{
		var duration = slideTransitionDuration * 0.5;
		var delay = slideTransitionDuration * 0.25;
		
		$.each(elements, function(idx, element){
			element = $(element)
			element
				.css({
					top: (slide.originalPosition(element).top - 50) + 'px'
				})
				.animate({
					top: slide.originalPosition(element).top + 'px'
				},{
					duration: duration + (idx*delay),
					easing: 'easeOutCirc'
				})
		})
	}
	
	function outro( slide, elements, slideTransitionDuration )
	{
		var duration = slideTransitionDuration * 0.5;
		var delay = slideTransitionDuration * 0.25;

		$.each( elements, function(idx, element ){
			element
				.delay(delay + idx * delay)
				.animate({
					top: (slide.originalPosition(element).top - 50) + 'px'
				},{
					duration: duration,
					easing: 'easeInCirc'
				})
		})
		
		return duration;		
	}
	
	var slides = [
		new slideshow.Slide( { 
			slide: $('#hero-gucht'),
			intro: function(d)
			{
				var hands = this.slide().find( '.hands' );
				var stats = this.slide().find( '.stats' );
				intro( this, [hands,stats], d )
			},
			outro: function(d)
			{
				var hands = this.slide().find( '.hands' );
				var stats = this.slide().find( '.stats' );

				return outro(this,[stats,hands], d );
			}}),
		
		new slideshow.Slide( { 
			slide: $('#hero-clinton'),
			intro: function(d)
			{
				var stats = this.slide().find( '.stats' ),
				    illus = this.slide().find( '.illus' );

				intro( this, [stats,illus], d )	;			
			},
			outro: function(d)
			{
				var illus = this.slide().find( '.illus' );
				var stats = this.slide().find( '.stats' );

				return outro( this, [stats,illus], d );
			}}),

		new slideshow.Slide( { 
			slide: $('#hero-quotes'),
			intro: function(d)
			{
				quotesFV.start();				
			},
			outro: function(d)
			{
				quotesFV.stop();
			}}),
		
/*
		new slideshow.Slide( { 
			slide: $('#hero-duke'),
			intro: function(d)
			{
				var stats = this.slide().find( '.stats' ),
				    illus = this.slide().find( '.illus' );

				intro( this, [stats,illus], d )	;			
			},
			outro: function(d)
			{
				var illus = this.slide().find( '.illus' );
				var stats = this.slide().find( '.stats' );

				return outro( this, [stats,illus], d );
			}}),
*/

		new slideshow.Slide( { 
			slide: $('#hero-hormats'),
			intro: function(d)
			{
				var gears = this.slide().find( '.gears' ),
				    man = this.slide().find( '.man' ),
				    stats = this.slide().find( '.stats' );

				intro( this, [gears,man,stats], d );
			},
			outro: function(d)
			{
				var gears = this.slide().find( '.gears' ),
				    man = this.slide().find( '.man' ),
				    stats = this.slide().find( '.stats' );

				return outro( this, [gears,man,stats], d );
			}})
	];
	
	//
	//	Start the slideshow
	//

	new slideshow.Slideshow({
		slideshowContainer: $('#create-slideshow'),
		slides: slides,
		paginator: $('#create-slideshow .paginator'),
		paginatorFactory: function( target )
		{
			return $('<img src="/sites/all/themes/create/images/slideshow/empty.png">').attr( 'rel', target );
			return $('<a>').attr('href', '#' + target);
		},
		nextSlideTimeout: 8000,
		transitionDuration: 1000,
		nextTrigger: $('#create-slideshow .next' ),
		prevTrigger: $('#create-slideshow .prev' ),
		initialSlide: 0
	});
});

