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

	this.each(function() {
		
		var advCount = 1;
		var scid = this.id;
		var list = jQuery(this);
		var wrap = jQuery(this).wrap('<div class="showcase-wrap"></div>').parent();
		var images = [];
		var slideWidth = jQuery('li', jQuery(this)).width();
		var slides = jQuery('li', jQuery(this)).length;
		var currentSlide = 1;
		var lastTimer = null;
		
		// default options
		var autoAdvance = false;
		var displayTime = 5000;
		var transDuration = 1500;
		var jumpClass = 'sc-jump';
		var linkPrefix = scid;
		var loop = true;
		var loopStyle = 'rotate';
		var navContainer = wrap;
		var navCreate = true;
		var navCreateNextPrev = true;
		var navNextLink = scid+separator+'next';
		var navPrevLink = scid+separator+'prev';
		var navSelectedClass = 'sc-selected';
		var numLoops = false;
		var separator = '_';
		
		// process options
		if (options) {
			autoAdvance = (options.autoAdvance != undefined) ? options.autoAdvance : autoAdvance ;
			displayTime = (options.displayTime != undefined) ? options.displayTime : displayTime ;
			jumpClass = (options.jumpClass != undefined) ? options.jumpClass : jumpClass ;
			linkPrefix = (options.linkPrefx != undefined) ? options.linkPrefix : linkPrefix ;
			loop = (options.loop != undefined) ? options.loop : loop;
			loopStyle = (options.loopStyle != undefined) ? options.loopStyle : loopStyle ;
			navContainer = (options.navContainer != undefined) ? options.navContainer : navContainer ;
			navCreate = (options.navCreate != undefined) ? options.navCreate : navCreate ;
			navCreateNextPrev = (options.navCreateNextPrev != undefined) ? options.navCreateNextPrev : navCreateNextPrev ;
			navNextLink = (options.navNextLink != undefined) ? options.navNextLink : navNextLink ;
			navPrevLink = (options.navPrevLink != undefined) ? options.navPrevLink : navPrevLink ;
			navSelectedClass = (options.navSelectedClass != undefined) ? options.navSelectedClass : navSelectedClass ;
			numLoops = (options.numLoops != undefined) ? options.numLoops : numLoops ;
			separator = (options.separator != undefined) ? options.separator : separator ;
			transDuration = (options.transDuration != undefined) ? options.transDuration : transDuration ;
		}
		
		// set some basic CSS stuff we need for the wrapper and the list
		wrap.css({
			'overflow': 'hidden',
			'position': 'relative',
			'width': list.css('width')
		});
		list.css({
			'position': 'relative',
			'width': ((jQuery('li').length+2)*jQuery('li img').width())+'px'
		});
		
		// 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 = jQuery('li:first', jQuery(this)).clone();
		lastSlide = jQuery('li:last', jQuery(this)).clone();
		firstSlide.appendTo(this);
		lastSlide.prependTo(this);
		
		// loop through all the images and hide them
		jQuery('li', list).each(function() {
			images.push(this);
			jQuery(this).css('float', 'left');
		});
		
		if (navCreate) {
			var navString = '';
			if (navCreateNextPrev) navString = navString+'<a id="'+scid+separator+'prev">Previous</a> ';
			for (c = 1; c <= slides; c++) {
				navString = navString+'<a class="'+jumpClass+'" id="'+scid+separator+c+'">'+c+'</a> ';
			}
			if (navCreateNextPrev) navString = navString+'<a id="'+scid+separator+'next"">Next</a> ';
			if (navContainer != wrap) {
				navContainer.html(navString);
			} else {
				wrap.append(navString);
			}
		}
		
		jQuery('#'+navPrevLink).click(function() { list.prev() });
		jQuery('#'+navNextLink).click(function() { list.next() });
		jQuery('a.'+jumpClass, navContainer).click(function() {
			var num = this.id.split(new RegExp(separator))[1];
			list.jumpTo(num);
		});
		
		if (autoAdvance) {
			lastTimer = setTimeout(function() { list.next() }, displayTime);
		}
		
		$('#'+linkPrefix+separator+'1').addClass(navSelectedClass);
		
		/**
		 *	Jumps to the specified slide in the sequence.
		 *
		 *	@param int num
		 */
		list.jumpTo = function(num, durOverride) {
			duration = (durOverride != undefined) ? durOverride : transDuration ;
			list.animate({ left: '-'+(num*slideWidth)+'px' }, duration);
			currentSlide = num;
			$('a.'+jumpClass).removeClass(navSelectedClass);
			$('#'+linkPrefix+separator+num).addClass(navSelectedClass);
			// is autoadvance enabled?
			if (autoAdvance) {
				advCount = advCount + 1;
				clearTimeout(lastTimer);
				if (advCount < ((slides+1)*numLoops)) {
					lastTimer = setTimeout(function() { list.next() }, displayTime);
				}
			}
		};
		
		/**
		 *	Jumps to the next slide in the sequence.
		 */
		list.next = function() {
			if (currentSlide == slides) {
				if (loop) {
					if (loopStyle == 'reset') {
						list.jumpTo(1);
					} else {
						list.jumpTo(slides+1);
						list.jumpTo(1, 0);
					}
				}
			} else {
				list.jumpTo((currentSlide*1)+1);
			}
		};
		
		/**
		 *	Jumps to the previous slide in the sequence.
		 */
		list.prev = function() {
			if (currentSlide == 0) {
				if (loop) {
					if (loopStyle == 'reset') {
						list.jumpTo(slides);
					} else {
						list.jumpTo(-1);
						list.jumpTo(slides, 0);
					}
				}
			} else {
				list.jumpTo((currentSlide*1)-1);
			}
		};
		
		// move things to the "first" slide
		list.jumpTo(1, 0);
		
		return jQuery(this);
	
	});

};
