/*!
 * Uberbox
 * http://mattfroese.ca/
 *
 * Revision 22
 * Copyright (c) 2010 Matt Froese
 * Licenced under GPL
 */

(function($){

$.fn.uberbox = function( options ) {
	var defaults = {
		width: "0px",
		height: "0px",
		startDelay: 0, // delay transition
		speed: 5000, // 5 seconds
		theme: "",
		transition: {
			fx: "fade",
			speed: "fast"
		},	
		next: "",
		prev: "",
		pager: "",
		pause: "",
		thumber: "",
		auto: true,
		pauseOnHover: false,
		timer: null
		
	}, 	settings = $.extend({}, defaults, options);		

	this.each(function()
	{	
		var $box = $(this); 
			id = $(this).attr( "id" );
		
		$( "#" + id + " ul" ).addClass( "uberbox-slides" );
		
		if( settings.width > 0 ) { $(this).css( "width", settings.width ); }
		if( settings.height > 0 ) { $(this).css( "height", settings.height ) };

		settings.width = $(this).css( "width" );
		settings.height = $(this).css( "height" );
		
		$( "#" + id + " ul.uberbox-slides" ).css( "width", $(this).css( "width" ) );
		$( "#" + id + " ul.uberbox-slides" ).css( "height", $(this).css( "height" )  );

		// theme preparation
		$box.addClass( "uberbox" );		
		if( settings.theme != "" ) {
			$box.addClass( settings.theme );
		}

		var top = $box.position().top;
				left = $box.position().left;
				settings.slides = $( "#" + id + " ul.uberbox-slides li" ).size();
				count = 0;

		if( settings.transition.fx == "slide" ) {
			// set overflow on container and place slides side by side, got that mclyde?
			// order slides side by side
			$( "#" + id + " ul.uberbox-slides" ).css( "overflow", "hidden" );
			$( "#" + id + " ul.uberbox-slides" ).css( "position", "relative" );

			$( "#" + id + " ul.uberbox-slides li" ).each( function() {
				count++;
				$(this).data( "uberbox-cnt", count ); 
				$(this).css( "position", "absolute" );
				$(this).css( "left", settings.width );
			});
			$( "#" + id + " ul li:first" ).css( "left", "0px" );
		} else {
			// stack slides for wipe and fade transitions	
			$( "#" + id + " ul.uberbox-slides li" ).each( function() {
				count++;
				$(this).data( "uberbox-cnt", count ); 
				$(this).css( "position", "absolute" );
				$(this).css( "z-index", count );			
			});
			$( "#" + id + " ul li:not(:first)" ).css( "display", "none" );
		}
		
		$( "#" + id + " ul li:first" ).addClass( "uberbox-current-slide" );

		// pager
		if( settings.pager != "" ) {
			$( settings.pager ).addClass( "uberbox-pagination" );
			$( settings.pager ).addClass( settings.theme );
			for( i = 1; i <= settings.slides; i++ ) {
				$( settings.pager ).append( "<li><a class=\"slide\" rel=\"" + i + "\" href=\"javascript: void(0);\">" + i + "</a></li>" );
			}
			$( settings.pager + " li:first-child" ).addClass( "uberbox-on" );
			
			$( settings.pager + " li a.slide" ).click( function( e ) {
		
				var slide = $( "#" + $box.attr( "id" ) + " ul.uberbox-slides li.uberbox-current-slide" );
					nextSlide = $( "#" + $box.attr( "id" ) + " ul li:nth-child(" + $(this).attr( "rel" ) + ")" );
				
				for( i = 1; i <= settings.slides; i++ ) {
					$( settings.pager + " li" ).removeClass( "uberbox-on" );
				}	
				$(this).parent().addClass( "uberbox-on" );

				e.navType = "paginator";
				
				settings = slideAdvance( $box.attr( "id" ), slide, nextSlide, settings, e );
			});
		}

		// thumber!
		if( settings.thumber != "" ) {
			var t = 0;
			$( "#" + id + " ul.uberbox-slides li" ).each( function() {
				t++;
				var thumb = $( this ).attr( "rel" );
				$( settings.thumber ).append( "<li><a class=\"thumb\" rel=\"" + t + "\" href=\"javascript: void(0);\"><img src=\"" + thumb + "\" alt=\"Slide " + t + " Thumbnail\" /></a></li>" );
			});
			$( settings.thumber + " li:first-child" ).addClass( "uberbox-on" );
			
			$( settings.thumber + " li a.thumb" ).click( function( e ) {
		
				var slide = $( "#" + $box.attr( "id" ) + " ul.uberbox-slides li.uberbox-current-slide" );
					nextSlide = $( "#" + $box.attr( "id" ) + " ul li:nth-child(" + $(this).attr( "rel" ) + ")" );
				
				for( i = 1; i <= settings.slides; i++ ) {
					$( settings.thumber + " li" ).removeClass( "uberbox-on" );
				}	
				$(this).parent().addClass( "uberbox-on" );

				e.navType = "thumber";
				
				settings = slideAdvance( $box.attr( "id" ), slide, nextSlide, settings, e );
			});
		}
		
		// next / prev
		if( settings.next ) {
			$( settings.next ).addClass( "uberbox-button-next" );
			$( settings.next ).addClass( settings.theme );

			$( settings.next ).bind("click", function( e ){
				if( settings.auto && settings.pause )
				{
					$( settings.pause ).attr( "rel", "" );
				}
				next( $box.attr( "id" ), settings, e );
			});
		}

		if( settings.prev ) {
			$( settings.prev ).addClass( "uberbox-button-prev" );
			$( settings.prev ).addClass( settings.theme );

			$( settings.prev ).bind("click", function( e ){
				if( settings.auto && settings.pause )
				{
					$( settings.pause ).attr( "rel", "" );
				}
				prev( $box.attr( "id" ), settings, e );
			});
		}
		
		if( settings.auto && settings.pause ) {
			$( settings.prev ).addClass( "uberbox-button-prev" );
			$( settings.prev ).addClass( settings.theme );

			$( settings.prev ).bind("click", function( e ){
				if( $( this ).attr( "rel" ) == "paused" ) {
					$( this ).attr( "rel", "" );
					clearTimeout( settings.timer );
					settings.timer = setTimeout( function() { go( $box.attr( "id" ), settings ); }, settings.speed );
				}
				else {
					$( this ).attr( "rel", "paused" );
					clearTimeout( settings.timer );
				}
			});
		}
		
		if( settings.auto && settings.pauseOnHover ) {
			$( this ).mouseover( function( e ) {
				clearTimeout( settings.timer );
			});
			$( this ).mouseout( function( e ) {
				clearTimeout( settings.timer );
				settings.timer = setTimeout( function() { go( $box.attr( "id" ), settings ); }, settings.speed );
			});
		}

		if( settings.auto ) {
			var startDelay = settings.startDelay > 0 ? settings.startDelay : settings.speed;
			settings.timer = setTimeout(function() { go( $box.attr( "id" ), settings ); }, startDelay );
		}
	});

	// returns the jQuery object to allow for chainability.
	return this;
};


})(jQuery);

function go( id, settings )
{
	//console.log( id + " go " );
	settings = next( id, settings );	
	clearTimeout( settings.timer );
	settings.timer = setTimeout( function() { go( id, settings ); }, settings.speed );
}

function next( id, settings, event )
{
	var slide = $( "#" + id + " ul.uberbox-slides li.uberbox-current-slide" );
		nextSlide = slide.next().is( "li" ) ? slide.next() : $( "#" + id + " ul li:first-child" );
	
	return slideAdvance( id, slide, nextSlide, settings, event );
}

function prev( id, settings, event )
{
	var slide = $( "#" + id + " ul.uberbox-slides li.uberbox-current-slide" );
		prevSlide = slide.prev().is( "li" ) ? slide.prev() : $( "#" + id + " ul li:last-child" );

	// should probably reset the timer here instead of onmouseover the button
	return slideAdvance( id, slide, prevSlide, settings, event );
}

function slideAdvance( id, currentSlide, nextSlide, settings, event ) {

	if( currentSlide.html() == nextSlide.html() ) return settings;

	if( settings.pager != "" ) {
		for( i = 1; i <= settings.slides; i++ ) {
			$( settings.pager + " li" ).removeClass( "uberbox-on" );
		}	
		$( settings.pager + " li:nth-child(" + nextSlide.data( "uberbox-cnt" ) + ")" ).addClass( "uberbox-on" );
	}
	if( settings.thumber != "" ) {
		for( i = 1; i <= settings.slides; i++ ) {
			$( settings.thumber + " li" ).removeClass( "uberbox-on" );
		}	
		$( settings.thumber + " li:nth-child(" + nextSlide.data( "uberbox-cnt" ) + ")" ).addClass( "uberbox-on" );
	}

	if( settings.transition.fx == "slide" ) {
		
		var currentPos = currentSlide.data("uberbox-cnt");
			nextPos = nextSlide.data("uberbox-cnt");
			prevClicked = event == undefined ? false : ( event.target.id == settings.prev.replace( "#", "" ) ? true : false );
			nextClicked = event == undefined ? false : ( event.target.id == settings.next.replace( "#", "" ) ? true : false );
				
		if( prevClicked || ( ( ( event != undefined && event.navType == "paginator" ) || currentPos < settings.slides ) && currentPos - 1 == nextPos ) ) { // prev
			nextSlide.css( "left", "-" + settings.width );
			currentSlide.animate( { left: settings.width }, settings.transition.speed );
			nextSlide.animate( { left: "0px" }, settings.transition.speed );
		} else {
			nextSlide.css( "left", settings.width );
			currentSlide.animate( { left: "-" + settings.width }, settings.transition.speed );
			nextSlide.animate( { left: "0px" }, settings.transition.speed );		
		}
		
	} else {	
		// make sure next is below currentSlide currentSlide
		if( currentSlide.css( "z-index" ) < nextSlide.css( "z-index" ) ) { //then swap
			var top = nextSlide.css( "z-index" );
				bottom = currentSlide.css( "z-index" );		
			currentSlide.css( "z-index", top );
			nextSlide.css( "z-index", bottom );
		}
		nextSlide.show();
		if( settings.transition.fx == "wipe" ) {
			var dr = settings.transition.direction;
				sp = settings.transition.speed == "" ? "normal" : settings.transition.speed;
			if( dr == "left" ) {
				currentSlide.css( "overflow", "hidden" );
				currentSlide.animate( { width: "0px" }, sp, function(){ $(this).css("width", "" ); $(this).css("height", "" ); $(this).hide(); } );
			} else if( dr == "right" ) {
				currentSlide.css( "overflow", "hidden" );
				currentSlide.animate( { marginLeft: settings.width, width: "0px" }, sp, function(){ $(this).css("margin-left", "" ); $(this).css("width", "" ); $(this).hide(); }  );
			} else if( dr == "down" ) {
				currentSlide.css( "overflow", "hidden" );
				currentSlide.animate( { marginTop: settings.height, height: "0px" }, sp, function(){ $(this).css("margin-top", "" ); $(this).css("height", "" ); $(this).hide(); }  );
			} else {
				currentSlide.slideUp( settings.transition.speed );
			}
		} else if( settings.transition.fx == "fade" ) {
			currentSlide.fadeOut( settings.transition.speed );
		}
	}
	currentSlide.removeClass( "uberbox-current-slide" );
	nextSlide.addClass( "uberbox-current-slide" );

	// if auto reset timer
	if( settings.auto ) {
		clearTimeout( settings.timer );
		settings.timer = setTimeout( function() { go( id, settings ); }, settings.speed );
	}
	return settings;
}
