/**
 * 	@author Jeremy Clifton <jeremy@engagency.com>
 * 	@desc Transforms a unordered list of content into a slideshow. Slides optionally auto-advance.
 * 	@version 0.9.1
 * 	@example $('#slides').slideshow();
 * 	@license BSD
 */
(function($) {

	$.fn.showcase = function(params) {
	
		this.each(function() {
			
			var priv = {
				scid: this.id,
				list: $(this),
				wrap: $(this).wrap('<div class="showcase-wrap"></div>').parent(),
				images: [],
				height: $(this).height(),
				width: $('li', $(this)).width(),
				numSlides: $('li', $(this)).length,
				currentSlide: 1,
				lastTimer: null
			};
			
			var options = $.extend({
				autoAdvance: false,
				displayTime: 5000,
				jumpClass: 'sc-jump',
				linkPrefix: priv.scid,
				loop: true,
				navContainer: priv.wrap,
				navCreate: true,
				navCreateNextPrev: true,
				navNextLink: priv.scid+'_next',
				navPrevLink: priv.scid+'_prev',
				navSelectedClass: 'sc-selected',
				numLoops: 0,
				transDuration: 1500,
				transSlideStyle: 'rotate',
				transType: 'slide'
			}, (params || {}));
			
			// set some basic CSS stuff we need for the wrapper and the list
			priv.wrap.css({
				'overflow': 'hidden',
				'position': 'relative',
				'width': priv.list.css('width'),
				'height': priv.height
			});
			priv.list.css({
				'position': 'relative',
				'width': (($('li').length+2)*$('li img').width())+'px'
			});
			
			priv.list._fade_init = function() {
			
				// loop through all the images and stack them
				$('li', priv.list).each(function() {
					priv.images.push($(this).html());
				});
				priv.list.css('display', 'none');
				
				// create the top and bottom panes
				priv.wrap.append('<div id="sc-top"></div><div id="sc-bot"></div>');
				$('#sc-top').css({
					position: 'absolute',
					top: '0',
					left: '0',
					zIndex: '11',
					height: priv.height,
					width: priv.width
				});
				$('#sc-bot').css({
					position: 'absolute',
					top: '0',
					left: '0',
					zIndex: '10',
					height: priv.height,
					width: priv.width
				});
				
				$('#sc-top').html(priv.images[0]);
			
			};
			
			priv.list._slide_init = function() {

				// clone the first and last slides and add them to the beginning and end of the list; 
				// this will help us appear to "rotate" the slides
				firstSlide = $('li:first', $(this)).clone();
				lastSlide = $('li:last', $(this)).clone();
				firstSlide.appendTo(this);
				lastSlide.prependTo(this);
		
				// loop through all the images and hide them
				$('li', priv.list).each(function() {
					priv.images.push(this);
					$(this).css('float', 'left');
				});
			
			};
			
			/**
			 *	Jumps to the specified slide in the sequence (slide).
			 *
			 *	@param int num
			 */
			priv.list.jumpTo = function(num, durOverride) {
			
				duration = (durOverride != undefined) ? durOverride : options.transDuration ;
				
				if (options.transType == 'slide') {
					priv.list.animate({ left: '-'+(num*priv.width)+'px' }, duration);
				} else if (options.transType == 'fade') {
					$('#sc-bot').html(priv.images[(num-1)]);
					$('#sc-top').animate({ opacity: 0 }, duration, function() {
						$('#sc-top').html(priv.images[(num-1)]);
						$('#sc-top').css('opacity', 1);
					});				
				}
				
				priv.currentSlide = num;
				$('a.'+options.jumpClass).removeClass(options.navSelectedClass);
				$('#'+options.linkPrefix+'_'+num).addClass(options.navSelectedClass);

				// is autoadvance enabled?
				if (options.autoAdvance) {
					clearTimeout(priv.lastTimer);
					if (priv.currentSlide < ((priv.numSlides+1)*options.numLoops) || options.numLoops == 0) {
						priv.lastTimer = setTimeout(function() { priv.list.next() }, options.displayTime);
					}
				}
				
			};
			
			/**
			 *	Jumps to the next slide in the sequence.
			 */
			priv.list.next = function() {
				if (priv.currentSlide == priv.numSlides) {
					if (options.loop) {
						if (options.transSlideStyle == 'reset') {
							priv.list.jumpTo(1);
						} else {
							priv.list.jumpTo(priv.numSlides+1);
							priv.list.jumpTo(1, 0);
						}
					}
				} else {
					priv.list.jumpTo((priv.currentSlide*1)+1);
				}
			};
			
			/**
			 *	Jumps to the previous slide in the sequence.
			 */
			priv.list.prev = function() {
				if (priv.currentSlide == 0) {
					if (options.loop) {
						if (options.transSlideStyle == 'reset') {
							priv.list.jumpTo(priv.numSlides);
						} else {
							priv.list.jumpTo(-1);
							priv.list.jumpTo(priv.numSlides, 0);
						}
					}
				} else {
					priv.list.jumpTo((priv.currentSlide*1)-1);
				}
			};				

			eval('priv.list._'+options.transType+'_init()');
			
			if (options.navCreate) {
				var navString = '';
				if (options.navCreateNextPrev) navString = navString+'<a id="'+priv.scid+'_prev">Previous</a> ';
				for (c = 1; c <= priv.numSlides; c++) {
					navString = navString+'<a class="'+options.jumpClass+'" id="'+priv.scid+'_'+c+'">'+c+'</a> ';
				}
				if (options.navCreateNextPrev) navString = navString+'<a id="'+priv.scid+'_next"">Next</a> ';
				if (options.navContainer != priv.wrap) {
					options.navContainer.html(navString);
				} else {
					priv.wrap.append(navString);
				}
			}
			
			$('#'+options.navPrevLink).click(function() { priv.list.prev() });
			$('#'+options.navNextLink).click(function() { priv.list.next() });
			$('a.'+options.jumpClass, options.navContainer).click(function() {
				var num = this.id.split(new RegExp('_'))[1];
				priv.list.jumpTo(num);
			});
			
			if (options.autoAdvance) {
				priv.lastTimer = setTimeout(function() { priv.list.next() }, options.displayTime);
			}
			
			$('#'+options.linkPrefix+'_1').addClass(options.navSelectedClass);
				
			// move things to the "first" slide
			priv.list.jumpTo(1, 0);
			
			return $(this);
			
		});
	
	};
	
})(jQuery);