/*** DIVSHOW ***
Author: Paul Sayre
Company: SiteCrafting
Created: 2009-03-27
Updated: 2009-10-28
Version: 1.2
Requires: jQuery 1.2.6 (or 1.3.2)

Usage: (items in <> are optional)

divshow[id].pause(<true/false>); // Sets the pause state (Toggles if not passed true/false)
divshow[id].random(<true/false>); // Stes the random state (Toggles if not passed true/false)
divshow[id].next(); // Transitions to the next slide
divshow[id].prev(); // Transitions to the previous slide
divshow[id].index(<index>); // Transitions to a specific slide by index (Returns current slide index if nothing is passes)
divshow[id].timeout = 10000; // Set the timeout between each slide (start on next transition)
divshow[id].speed = 750; // Sets the speed of the transition between slides

HTML: (items in <> are optional)

<div id="someid" class="divshow <random> <paused>">
	<div class="slide">
		[Slide 1 HTML]
	</div>
	<div class="slide">
		[Slide 2 HTML]
	</div>
	...
</div>

*/

// Global variable
var divshow = {

	// Default options for public variables
	defaults: {
		timeout: 10000, // Timeout between slide transitions
		speed: 1000 // Length of the slide transition
	},
	
	// Configurations for all divshows
	config: {
		// Selectors
		wrapperSelector: '.divshow', // Selects slideshow wrappers
		slideSelector: '.slide', // Selects slides within the wrapper
		prevSelector: '.prev', // Buttons to transition to the previous slide
		nextSelector: '.next', // Button to transition to next slide
		pauseSelector: '.pause', // Button to pause slideshow
		
		// Classes
		pausedClass: 'paused', // If the slideshow is paused
		randomClass: 'random', // If the slideshow should progress randomly
		inTransClass: 'inTrans', // If the slideshow is in a transition
		currentClass: 'current-slide' // Slide that is shown
	}
};

// Scoping for divshow
(function($){ $(function() {
	var config = divshow.config;
	$(config.wrapperSelector).each(function(index) {
		
		/***** Init *****/
		
		this.id = this.id || 'divshow-'+index;
		var pub = divshow[this.id] = divshow[this.id] || {};
		var curr = 0;
		var wrapper = $(this);
		var slides = $(config.slideSelector, wrapper);
		var lastSlide = slides[0];
		var timer;

		// Setup default public values
		for(var key in divshow.defaults) {
			if(!divshow.defaults.hasOwnProperty(key)) continue;
			if(pub[key] === undefined) pub[key] = divshow.defaults[key];
		}
		
		$('#btn-'+curr).addClass('current');
		
		// Set CSS
		slides.not(':first').hide();
		slides.css({
			top: '0px',
			left: '0px',
			position: 'absolute'
		});
		
		
		
		/***** Private Controls *****/
		
		var prev = function() {
			if(wrapper.hasClass(config.pausedClass) || wrapper.hasClass(config.inTransClass)) return;
			curr = (curr - 1 + slides.length) % slides.length;
			swap();
		}
		
		var next = function() {
			if(wrapper.hasClass(config.pausedClass) || wrapper.hasClass(config.inTransClass)) return;
			curr = (curr+1) % slides.length;
			swap();
		}
		
		var goTo = function(index) {
			if(curr == index || wrapper.hasClass(config.pausedClass) || wrapper.hasClass(config.inTransClass)) return;
			curr = index;
			swap();
		}
		
		var random = function() {
			if(wrapper.hasClass(config.pausedClass) || wrapper.hasClass(config.inTransClass)) return;
			if(slides.length < 2) return;
			do {
				curr = parseInt(Math.random() * slides.length);
			} while(lastSlide == slides[curr]);
			swap();
		}
		
		var swap = function() {
			if(slides.length < 2) return;
			wrapper.addClass(config.inTransClass);
			$(lastSlide).removeClass(config.currentClass).fadeOut(pub.speed);
			lastSlide = slides[curr];
			$(lastSlide).addClass(config.currentClass).fadeIn(pub.speed, function() { wrapper.removeClass(config.inTransClass); });
			setActive(curr);
		}
		
		var setRandom = function(setToRandom) {
			if(setToRandom === undefined) setToRandom = !wrapper.hasClass(config.randomClass);
			if(setToRandom) wrapper.addClass(config.randomClass);
			else wrapper.removeClass(config.randomClass);
		}
		
		var setPause = function(setToPaused) {
			if(setToPaused === undefined) setToPaused = !wrapper.hasClass(config.pausedClass);
			(setToPaused ? pause : unpause)();	
		}
		
		var pause = function() {
			wrapper.addClass(config.pausedClass);
			clearTimeout(timer);
		}
		
		var unpause = function() {
			wrapper.removeClass(config.pausedClass);
			(function() {
				var caller = arguments.callee;
				clearTimeout(timer);
				timer = setTimeout(function() {
					(wrapper.hasClass(config.randomClass) ? random : next)();
					caller();
				}, pub.timeout);
			})();
		}
		
		var setActive = function(curr){
			//alert(curr);
			if(slides.length < 2) return;
			for (var key = 0; key < slides.length; key++)
			{
				//alert(key);
				$('#btn-'+key).removeClass('current');
			}
			$('#btn-'+curr).addClass('current');
		}
		
		
		
		/***** Public Controls *****/
		
		pub.prev = function() {
			unpause();
			prev();
			pause();
		};
		
		pub.next = function() {
			unpause();
			next();
			pause();
		};
		
		pub.index = function(val) {
			if(val === undefined) return curr;
			unpause();
			goTo(val);
			pause();
			return curr;
		};
		
		pub.pause = setPause;
		pub.random = setRandom;
		
		
		
		/***** Actions *****/
		
		wrapper.hover(pause, unpause);
		unpause();
		$(config.prevSelector, wrapper).click(pub.prev);
		$(config.nextSelector, wrapper).click(pub.next);
		$(config.pauseSelector, wrapper).click(pub.pause);
	});
}); })(jQuery);