/*
 * Carousel - jQuery Plugin
 * Simple and fancy slider with controls
 *
 * Examples and documentation at: http://inkdevs.com/javascript/carousel
 * 
 * Copyright (c) 2011 Inkdevs
 * That said, it is hardly a one-person project. Many people have submitted bugs, code, and offered their advice freely. Their support is greatly appreciated.
 * 
 * Version: 1.0 (05/16/2011)
 * Requires:
 * - jQuery v1.6.1+
 * - jQuery UI v1.8.12+ (only needed if you want to use the directional effect)
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Notes:
 * You can have unlimited controllers and slides on your page. This plugin runs off the "active" class and "rel" numbers you give your slides and control links!
 * This plugin is modified for use with dailyupdate.com and will break if not used exactly how it is on this site.
 * To get the official stable version please go to www.inkdevs.com
 */
(function( $ ){
	// Setup Global Variables
		timer = 0;
	
	// Go through and number all the slides and control links
		function number_items(){
			for (i=0; i<slides.length; i++){
				$(slides[i]).attr("rel",i);
				$(controls[i]).attr("rel",i);
			}
		}
	
	// Setup all actions to control the slider
		function controllers(){
			// Setup Control Links
				controls.live('click',function(){
					if( !($(this).hasClass('active')) ){
						var current = $(this).siblings('.active').attr('rel'), direction = $(this).attr('direction');
						if( direction == undefined ) if( $(this).attr('rel') < current ) direction = "forward"; else direction = "forward";
						if( !($(this).hasClass('active')) ) slide_position(direction,$(this).attr('rel'));
					}
					return false;
				})
				
			// Setup Left/Right Arrow key navigation
				$(document).bind({
					'keydown.Carousel': function(e){
						if( slides.length > 1 ){
							var code = (e.keyCode ? e.keyCode : e.which);
							if( code == 37 ) slide_position("prev");
							else if( code == 39 ) slide_position("next");
							if( methods.settings['slideshow_start'] == true ) slideshow('reset');
						}
					}
				});
				
			// Pause/Play Slideshow on Mouseover
				if( methods.settings['hover_pause'] == true ){
					slides.each(function(index, element){ 
						jQuery(element).bind({
							'mouseover.Carousel': function(e){ slideshow( false ); },
							'mouseout.Carousel':  function(e){ slideshow( true ); }
						});
					});
				}
		}
	
	// Setup the slideshow timer
		function slideshow(action){
			// Setup Dynamic sliding: Allows for developer to specify custom timing per slide, only updates if different than current timer
				if(methods.settings['time'] == 'dynamic' && timer != $('.slide.active').attr('time') ) timer = $('.slide.active').attr('time');
				else if(methods.settings['time'] != 'dynamic') timer = methods.settings['time'];
				
			// Set/Update the timer to trigger animation
				switch(action){
					case true: case 'reset':
						clearInterval(methods.settings['slideshow_id']);
						methods.settings['slideshow_id'] = setInterval(function() { slide_position("next"); }, timer);
						break;
					default: clearInterval(methods.settings['slideshow_id']); break;
				}
		}
		
	// The Core Function
	// Animate Slides and reset Active
		function animateSlides(position,direction){
			// Define the slides to interact with and what effect to use
				var slide_current = $('.slide.active'),
					slide_next    = $('.slide[rel="'+position+'"]'),
					ctrl_current  = $('*[slider="yes"] *[slider="controls"] a.active'),
					ctrl_next = '',
					effect_to_use = '';
					
				if( (direction == "prev" || direction == "backward") ) ctrl_next = ctrl_current.prevAll('a[rel="'+position+'"]:first');
				else ctrl_next = ctrl_current.nextAll('a[rel="'+position+'"]:first');
					
			// If direction is on the x or z axis then find the opposite direction to the desired effect
				if( (direction == "prev" || direction == "backward") && (methods.settings['effect'] == "up" || methods.settings['effect'] == "down" || methods.settings['effect'] == "left" || methods.settings['effect'] == "right") ) effect_to_use = find_opposite(methods.settings['effect']); else effect_to_use = methods.settings['effect'];
				
			// Determine which effect to use and run animation
				switch(effect_to_use){
					case 'up': case 'down': case 'left': case 'right':
						slide_current.removeClass('active');
						slide_next.stop(true,true).show( 'slide', { direction: find_opposite(effect_to_use), easing: methods.settings['easing'] }, methods.settings['delay'],function(){ slide_next.addClass('active'); });
						slide_current.stop(true,true).hide( 'slide', { direction: effect_to_use, easing: methods.settings['easing'] }, methods.settings['delay'] );
						break;
					case 'photo':
						slide_current.stop(true,true).fadeOut(methods.settings['delay']/30, 'linear' , function(){ slide_next.addClass('active'); slide_current.removeClass('active'); });
						slide_next.stop(true,true).fadeIn(methods.settings['delay'], 'easeOutQuart' );
						break;
					default:
						slide_current.stop(true,true).fadeOut(methods.settings['delay']);
						slide_next.stop(true,true).fadeIn(methods.settings['delay'],function(){ slide_current.removeClass('active'); slide_next.addClass('active'); });
						break;
				}
				
			// Update the controlers
				ctrl_current.removeClass('active'); ctrl_next.addClass('active');
				$("#thumbs").stop().animate({scrollTop: ctrl_next.prevAll().length*imgHeight}, 800);
				
				if( ctrl_next.prevAll().length > slides.length -1 ) clone_items(ctrl_next);
				
			// Reset the slideshow timer with the new slide's dynamic timer
				if ( methods.settings['slideshow_start'] == true && methods.settings['time'] == 'dynamic' ) slideshow('reset');
		}
	
	// Runs the handling of active slides and animation
		function slide_position(direction,position){
			// Get the active slide position
				current_pos = parseFloat($('.slide.active').attr('rel'));
			
			// Increment position if using the arrow keys or timer, else use the position given
				if( direction == "prev" || direction == "next"){
					animateSlides(slide_increment(direction),direction);
				}else animateSlides(position,direction);
		}
		
	// Helper Functions
		function clone_items(){
			var top_items = controls.slice(0,controls.length)
			top_items.hide().clone().removeClass('active').show().appendTo("#thumbs");
			setTimeout(function(){
				$('*[slider="yes"] *[slider="controls"] a').slice(0,controls.length).remove();
				var scoll_to = $('*[slider="yes"] *[slider="controls"] a.active').position().top;
				
				$("#thumbs").stop().animate({scrollTop: $('*[slider="yes"] *[slider="controls"] a.active').attr('rel') * imgHeight}, 0);
			},800)
		}
		function find_opposite(direction){
			switch(direction){
				case "up":		return "down";	break;
				case "down":	return "up";	break;
				case "left":	return "right";	break;
				case "right":	return "left";	break;
			}
		}
		function slide_increment(direction){
			// Determine the position based on direction
				if( direction == "prev" ) var position = current_pos-1;
				else var position = current_pos+1;
				
			// Setup Infinite Loop
				if( position == -1 ){
					position = slides.length - 1;
				}else if( position > slides.length - 1 ) position = 0;
				
			return position;
		}
		
	var methods = {
		settings: {
			delay: 1500,
			easing: 'swing',
			effect: 'default',
			slideshow_start: false,
			hover_pause: 'pause',
			slideshow_id : '',
			time: 5000
		},
		init : function( options ) {
			return this.each(function(){
				$.extend(methods.settings, options);
				slides = $('.slide');
				controls = $('*[slider="yes"] *[slider="controls"] a');
				imgHeight = controls.height();
				number_items();
				controls.slice(0,controls.length).clone().appendTo("#thumbs");
				slides.first().addClass('active');
				controls.first().addClass('active');
				if( methods.settings['slideshow_start'] == true ) slideshow(true);
				controllers();
			})
		},
		pause : function( ) {
			return this.each(function(){
				if( methods.settings['slideshow_start'] == true ) slideshow(false);
				slides.each(function(index, element){ jQuery(element).unbind('.Carousel'); })
				$(document).unbind('.Carousel');
			})
		},
		play : function() {
			return this.each(function(){
				if( methods.settings['slideshow_start'] == true ) slideshow(true);
				controllers();
			})
		}
	};
	$.fn.carousel = function(method){
		// Method calling logic
			if ( methods[method] ) return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
			else if ( typeof method === 'object' || ! method ) return methods.init.apply( this, arguments );
			else $.error( 'Method ' +  method + ' does not exist on jQuery.carousel' );
	};
})( jQuery );
