// Morpher - Morphs/Pans different 'cells' located inside 'slides'
// -----------
// By: David Rugendyke
// Ver: 0.1 (2011)
// Lib: jQuery (Port of Mootools OOP version by me which is a lot better :)
// Note: You do not need to edit this file at all to add new slides or panels that morph (pan, slide etc). All that can be controlled from the HTML.

$(window).load(function () {
	if($('#morpher')) {
		$('#morpher').morpher();
	}
});


// Create closure
(function($) {
	
	 // Plugin definition
     $.fn.morpher = function(options) 
	 {
		 // Build main options
		 var opts = $.extend({}, $.fn.morpher.defaults, options);
		 
		 // Build element specific options
		 var o = $.meta ? $.extend({}, opts, this.data()) : opts;
		 
		 // Get all the slides for this morpher
		 var slides = this.children('.'+o.slideClass);
	
		 // Set some global plugin vars
		 var a = this;
		 a.slides = Array();
		 a.slideIndexCurrent = null;
		 a.slideIndexPrevious = null;
		 a.slideNavClicked = false;
		 a.options = o;
		 
		 // Lets do this!
		 if(slides.length > 0) {
				// Store the panels for each slide in an array with the key being the index
				slides.each(function(index) 
				{
					var slide = $(this);
					var slideID = $(this).attr('id');
					// Store all the slides and their panels in an object
					a.slides[index] = $(this).find('.'+o.panelClass);
					a.slides[index]['slide'] = slide;
					
					// Create a nav item for each slide
					var navIcon = $("<div/>", {
										'class': o.navButtonClass,
									      click: function(){
												  // Indicate the nav has been clicked
												  a.slideNavClicked = true;
												  // Show the selected slide
												  a.slideIndexCurrent = index;
												  slide_switch(a);
											  }
												
										});		
					
					a.slides[index]['navIcon'] = navIcon;
					
					// Store the first slide and highlight the nav icon
					if(index == 0) {
						navIcon.addClass(o.navButtonOnClass);	
					}

					// Inject icon into the nav container
					a.find('#'+o.navID).prepend(navIcon);

				});
				
				// Start the slides automatically rotating
				slide_auto_rotate(a);
		 }
		 
		 
	};
	
	// The automatic slider
	function slide_auto_rotate($obj)  {
		
		// Only automatically rotate slides if one hasn't been clicked in the nav
		if(!$obj.slideNavClicked) {
			
			// Get the slide we are on, if it's null its the first slide
			if($obj.slideIndexCurrent == null) {
				
				$obj.slideIndexCurrent = 0;
			}else{
				// Get the next slide
				var nextIndex = parseInt($obj.slideIndexCurrent)+1;
				
				if($obj.slides[nextIndex]) {
					// Next slide since it exists
					$obj.slideIndexCurrent = nextIndex;	
				}else{
					// Reset to the start slide if the current one doesn't exist
					$obj.slideIndexCurrent = 0;	
				}
			}
			
			// Now switch to the next slide
			slide_switch($obj);
			// Now call this function for the next slide using the delay
			setTimeout(function() { slide_auto_rotate($obj); }, $obj.options.slideHoldTime);
		}
	};
	
	// Start the transition effects for all panels
	function slide_switch($obj)  {
		
		// Hide all slides if this is the initial load
		if($obj.slideIndexPrevious == null) {
			for(index in $obj.slides) {
					$obj.slides[index]['slide'].css('display', 'none');
			}
		}else{
			// We have a previous slide, fade that one out and fade the next one in
			$obj.slides[$obj.slideIndexPrevious]['slide'].fadeOut($obj.options.slideFadeSpeed);
			$obj.slides[$obj.slideIndexCurrent]['slide'].fadeIn($obj.options.slideFadeSpeed);
		}
	
		// Show the current slide
		$obj.slides[$obj.slideIndexCurrent]['slide'].css('display', 'block');
		// Start the transition morphs for all the panels in this slide
		transition_start($obj);
		// Set the previous slide index
		$obj.slideIndexPrevious = $obj.slideIndexCurrent;
	};
	
	// Start a single transition
	function transition_start($obj) {
	
	    // Remove on state for all nav button icons
		$obj.find('#'+$obj.options.navID).find('.'+$obj.options.navButtonOnClass).removeClass($obj.options.navButtonOnClass);
		// Set 'on' state for this nav button
		$obj.slides[$obj.slideIndexCurrent]['navIcon'].addClass($obj.options.navButtonOnClass);
	
		// For each panel
		$obj.slides[$obj.slideIndexCurrent].each(function(index) 
		{
			var panel = $(this);
			var panelID = panel.attr('id');
			// Get the target image in this panel to morph
			var targets = panel.find('.'+$obj.options.panelTargetClass);
			// Loop through the targets to morph
			if(targets.length > 0) 
			{
				targets.each(function(index) 
				{
					var target = $(this);
					var currentClass = target.attr('class');
					// Only morph if we have a target element to morph
					if(target) 
					{
						// Classes to morph between
						var startClass = target.attr('startClass');
						var endClass = target.attr('endClass');
						// Reset this panel to its start class
						if(currentClass.indexOf(endClass)) 
						{
							target.addClass(startClass);
							target.removeClass(endClass);
						}

						// Morph to the end class if it exists
						if(endClass) 
						{
							var morphTime = target.attr('morphTime');
							if(!morphTime) {
								morphTime = $obj.options.slideHoldTime;	
							}
							
							// Morph between the start and end classes, but only if they are not already being morphed
							if($(target).queue("fx") != 'inprogress') 
							{
								$(target).switchClass(startClass,endClass,parseInt(morphTime), null, function() 
								{
										target.attr('currentClass', endClass);
								});
							}
						}
					}
				}); // End target loop
			}
		});
			
		
	}
  	
	// plugin defaults
	 $.fn.morpher.defaults = 
	 {
		 slideClass: 'slide',
		 panelClass: 'panel',
		 panelTargetClass: 'panel-morph',
		 navID: 'nav',
		 navButtonClass: 'index-button',
		 navButtonOnClass: 'index-button-on',
		 slideHoldTime: 6000,
		 slideFadeSpeed: 1500
	 };
	 

// end of closure
})(jQuery);
