// eRotate, The BRS Elemental Rotator (11.18.11)  
// copyright Blue Ridge Solutions, Inc. www.blueridges.com
//
// INSTRUCTIONS
// Create container with a unique id
// Place your element(s) of choice within the container
// Intialize the plugin with $('#slideshow').eRotate();
// Pass in any of the settings below to achieve a desired effect 
// Default setup: $('#slideshow').eRotate({finalWidth:600, finalHeight:400, fxInterval:4000});

(function($){ 
	$.fn.eRotate = function(options){ 
		var settings = {
			// Set slide element type (img, p, *, .class)
			elementType : '*:not(.eRotate_overlay)',
			direction : 'forward', // forward, backward, random (slide to slide, not random ordering of set)
			randomStart : 0,
			delayStart : 0, // delay the start of the slideshow, pass in time, 0 for no delay
			slide: 0, // left, right, 0, up, down
			isTransparent: 0, // IE can't fade semi-transparent images properly
			triggerEvent: 'click', // click, mouseover (the event which thumbnails use to trigger a rotation (.eRotate_select)
			triggerDelay: 0,
			onRotate: null, // pass in function to trigger as a rotation occurs
			rotateCallback: null, // pass in function to trigger after a rotation completes
			
			// Final States (after fx, completed state)
			finalTop : 0,
			finalLeft : 0,
			finalOpacity : 1,
			finalWidth : 600,
			finalHeight : 400,
			
			// Initial States (animate in, set to final if no fx)
			initialOpacity : 0,
			initialTop : null,
			initialLeft : null, 
			initialWidth : null,
			initialHeight : null,
			
			// Post States (animate out, set to final if no fx)
			postOpacity : null,
			postTop : null, 
			postLeft : null, 
			postWidth : null,
			postHeight : null,
			
			// Set fx Time and Interval
			fxSpeed : 1500,
			fxTime : null,
			fxInterval : 3000, // default 4000 ms, set to 0 to skip automatic transitions
			fxTimerID : 0,
			
			fxResume : null,
			fxHasten : null
		};
		
		return this.each(function(){  
			var $slideshow = $(this);
			
			// override settings with parameters
			if(options) $.extend(settings, options);
			
			if(settings.triggerEvent == 'mouseover') settings.triggerDelay = 100;
			if(settings.initialTop == null) settings.intialTop = settings.finalTop;
			if(settings.initialLeft == null) settings.initialLeft = settings.finalLeft; // change to settings.finalWidth to scroll left to show next item on right
			if(settings.initialHeight == null) settings.initialHeight = settings.finalHeight;
			if(settings.initialWidth == null) settings.initialWidth = settings.finalWidth;
			if(settings.postOpacity == null) settings.postOpacity = settings.initialOpacity;
			if(settings.postTop == null) settings.postTop = settings.finalTop;
			if(settings.postLeft == null) settings.postLeft = settings.finalLeft; // change to -finalWidth to scroll left to show next item on right
			if(settings.postHeight == null) settings.postHeight = settings.finalHeight;
			if(settings.postWidth == null) settings.postWidth = settings.finalWidth;
			if(settings.fxTime == null) settings.fxTime = settings.fxSpeed;
			if(settings.fxResume == null) settings.fxResume = settings.fxInterval * 1.2;
			if(settings.fxHasten == null) settings.fxHasten = settings.fxTime / 5;
			
			// Setup Predefined Effects
			function setupFx(){
				if($slideshow.data('grab')) settings = $slideshow.data('grab').settings;
				if(settings.slide != 0){
					if(settings.slide == 'left')	{ settings.finalLeft = 0; settings.initialLeft = settings.finalWidth; settings.postLeft = -settings.finalWidth; }
					if(settings.slide == 'right')	{ settings.finalLeft = 0; settings.initialLeft = -settings.finalWidth; settings.postLeft = settings.finalWidth; }
					if(settings.slide == 'up') 		{ settings.finalTop = 0; settings.initialTop = settings.finalHeight; settings.postTop = -settings.finalHeight; }
					if(settings.slide == 'down') 	{ settings.finalTop = 0; settings.initialTop = -settings.finalHeight; settings.postTop = settings.finalHeight; }
				}
			}
			setupFx();
			
			// FX Changes
			// function reverseDirection(){}
			
			// Begin setting up animation
			var container = "#"+$slideshow.attr('id');
			var slides = container+' > '+settings.elementType+':not(*[rel='+container+'])';
			var controls = 'a[rel='+container+']:not(.eRotate_overlay)';
			
			// Assign order and get count (keep before random start)
			var count = 1;
			$(slides).each(function(){ 
				$(this).attr('data-slide',count); 
				$(controls+'.eRotate_select').eq(count-1).attr('data-slide',count);
				count++;
			});
			count = count-1;

			if(settings.direction == 'random') settings.fxHasten = settings.fxTime / 10;

			// Set random starting point
			if(settings.randomStart == 1){
				rand = Math.round(count*Math.random())-1;
				for (i=0;i<rand;i++) { $(slides+':first').remove().insertAfter($(slides+':last')); }
			}
			
			var current = parseInt($(slides+':first').attr('data-slide'));
				
			// Track slideshows - grab variables AFTER altering settings (INIT) and BEFORE running plugin functions
			$slideshow.data('grab',{settings:settings,slides:slides,controls:controls});
			
			// Initialize
			if($slideshow.css('position') != 'absolute'){ if(!$slideshow.css('position') != 'relative') { $slideshow.css({position:'relative'}); } }
			$slideshow.css({width: settings.finalWidth, height: settings.finalHeight}); // Set container Size
			initialSettings();
			additionalSettings();
			
			// Automate
			function autoRotate(){
				settings = $slideshow.data('grab').settings;
				clearInterval(settings.fxTimerID); settings.fxTimerID = 0;
				
				settings.fxTimerID = setInterval(function(){ rotate(settings.direction,Math.floor((Math.random()*count)+1)); },settings.fxInterval);
			}
			if($(slides).length > 1 && settings.fxInterval) { 
				if(settings.delayStart > 0) setTimeout(autoRotate,settings.delayStart);
				else autoRotate(); 
			}
			if($(slides).length < 2) $(controls).hide();
			
			// Time
			var time;
			function startTime(){ time = setTimeout(function(){ if(settings.fxInterval) autoRotate(); },settings.fxResume); }
			function clearTime(){ clearTimeout(time); }

			// Control
			$(controls).css({zIndex:5}).bind(settings.triggerEvent,function(e) {
				clearInterval(settings.fxTimerID); settings.fxTimerID = 0;
				settings.fxTime = settings.fxHasten; 
				e.preventDefault();
				// Forward
				if($(this).hasClass('eRotate_forward')){ 
					if(settings.direction == 'backward') settings.direction = 'forward'; 
					if(settings.slide == 'right') settings.slide = 'left'; 
					if(settings.slide == 'up') settings.slide = 'down'; 
					setupFx(); rotate('forward'); 
				}
				// Backward
				else if($(this).hasClass('eRotate_backward')){ 
					if(settings.direction == 'forward') settings.direction = 'backward'; 
					if(settings.slide == 'left') settings.slide = 'right'; 
					if(settings.slide == 'down') settings.slide = 'up'; 
					setupFx(); rotate('backward'); 
				}
				// Jump
				else if($(this).hasClass('eRotate_select')){ rotate('select',$(this).attr('data-slide')); }
				// Restart
				else if($(this).hasClass('eRotate_start')){ settings.fxTime = settings.fxSpeed; if(settings.fxInterval) autoRotate(); }
				// Stop
				else return;
				// Resume
				if(!$(this).hasClass('eRotate_stop')||!$(this).hasClass('eRotate_start')){ settings.fxTime = settings.fxSpeed; clearTime(); startTime(); }
			});
			
			// Prepare
			function initialSettings(){
				settings = $slideshow.data('grab').settings;
				slides = $slideshow.data('grab').slides;
				
				if($.browser.msie && $.browser.version < 9 && settings.isTransparent==1){
					$(slides).hide().css({position:'absolute', top: settings.initialTop, left: settings.initialLeft, width: settings.initialWidth, height: settings.initialHeight, zIndex:0}); // Set All to settings.initial State
					$(slides+'[data-slide='+current+']').show().css({top: settings.finalTop, left: settings.finalLeft, width: settings.finalWidth, height: settings.finalHeight, zIndex:1}); // Set 1st to settings.final State
				} else {
					$(slides).css({position:'absolute', top: settings.initialTop, left: settings.initialLeft, opacity: settings.initialOpacity, width: settings.initialWidth, height: settings.initialHeight, zIndex:0}); // Set All to settings.initial State
					$(slides+'[data-slide='+current+']').css({top: settings.finalTop, left: settings.finalLeft, opacity: settings.finalOpacity, width: settings.finalWidth, height: settings.finalHeight, zIndex:1}); // Set 1st to settings.final State
				}
			}
			
			function additionalSettings(){
				container = $slideshow.data('grab').container;
				controls = $slideshow.data('grab').controls;
				slides = $slideshow.data('grab').slides;
				
				$(controls+'.eRotate_select').removeClass('current_slide');
				$(controls+'[data-slide='+current+'].eRotate_select').addClass('current_slide');
				if($(slides+'[data-slide='+current+']').attr('href')) $('a[rel='+container+'].eRotate_overlay').attr('href',$(slides+'[data-slide='+current+']').attr('href'));
				else $('a[rel='+container+'].eRotate_overlay').removeAttr('href');
			}
			
			function rotate(direction,selection){ 
				container = $slideshow.data('grab').container;
				settings = $slideshow.data('grab').settings;
				slides = $slideshow.data('grab').slides;
				
				var next; 
				// Direct
				if(direction=='forward'){ next=current+1; if(next>count) next=1; if(current==next) next=next+1; }
				else if(direction=='backward'){ next=current-1; if(next<1) next=count; if(current==next) next=next-1; }
				else if(direction=='select'||direction=='random'){ next=selection; if(current==next) return; }
				else return;
				
				// Redirect
				if(direction=='select'){
					if(selection<=current){
						if(settings.direction == 'forward') settings.direction = 'backward'; 
						if(settings.slide == 'left') settings.slide = 'right'; 
						if(settings.slide == 'down') settings.slide = 'up'; 
						setupFx();
					} else {
						if(settings.direction == 'backward') settings.direction = 'forward'; 
						if(settings.slide == 'right') settings.slide = 'left'; 
						if(settings.slide == 'up') settings.slide = 'down'; 
						setupFx();
					}
				}
				
				// Reset
				$(slides).stop(true,true);
				initialSettings();
				var $current = $(slides+'[data-slide='+current+']');
				var $next = $(slides+'[data-slide='+next+']');
				
				// Animate (rotateCallback needs testing)
				if($.browser.msie && $.browser.version < 9 && settings.isTransparent==1){ 
					$current.css({zIndex:0}).animate({top:settings.postTop+'px', left:settings.postLeft+'px', width:settings.postWidth, height:settings.postHeight}, settings.fxTime,function(){ $(this).hide(); if(settings.rotateCallback) settings.rotateCallback(); }); // Animate Out
					$next.css({zIndex:1, top:settings.initialTop+'px', left:settings.initialLeft+'px'}).show().animate({top:settings.finalTop+'px', left:settings.finalLeft+'px', width:settings.finalWidth, height:settings.finalHeight}, settings.fxTime); // Animate In
				} else {
					$current.css({zIndex:0}).animate({top:settings.postTop+'px', left:settings.postLeft+'px', opacity:settings.postOpacity, width:settings.postWidth, height:settings.postHeight}, settings.fxTime,settings.rotateCallback); // Animate Out
					$next.css({zIndex:1, top:settings.initialTop+'px', left:settings.initialLeft+'px'}).animate({top:settings.finalTop+'px', left:settings.finalLeft+'px', opacity:settings.finalOpacity, width:settings.finalWidth, height:settings.finalHeight}, settings.fxTime); // Animate In
				}
				
				// Adjust
				current = next;
				additionalSettings();
				
				// Cooridinate
				if(settings.onRotate) settings.onRotate();
			}
			
		}); 
	}; // eRotate Plugin
})(jQuery);
