/*!
 * Features 1.0
 * Inspired by Tiny Carousel 1.8 - http://www.baijs.nl/tinycarousel
 *
 * Andrew Pettican (18/05/2011)
 */
(function($){
	$.fn.features = function(options){
		var defaults = { 
			carouselInterval: -1, // interval time in milliseconds.
			carouselDuration: 1000, // how fast will the carousel move?
			carouselCallback: null, // function that executes after every moveCarousel
			
			contentOutDuration: 250, // how fast will content be faded out?
			contentDelayDuration: 100, // how long should be delay before displaying new content?
			contentInDuration: 650, // how fast will content be faded in?
			autoLoadContentOnCarousel: true, // should the content automatically load when the carousel moves?
			touchDevice: false // is this a touch device?
		};
		var options = $.extend(defaults, options);  

		var oCarouselTimer = null;
		var oContentTimer = null;
		var oWrapper = $(this);
		var sWrapperId = oWrapper.attr('id');
		var oList = oWrapper.find('.items:first ul:first');
		var oFeatureDisplay = oWrapper.find('.feature:first');
		var oFeatureContent = oWrapper.find('ul.features:first > li');
		var bPause = false;
		var bVideoPlaying = false;
		var iActiveContentIndex = -1;
		
		return initialize();
		
		function initialize()
		{
			// Got nodes?
			// - oWrapper        (The wrapper div containing the feature)
			// - oList           (The list <ul> containing the items which may be displayed)
			// - oFeatureDisplay (The main display area showing the activated item from the list)
			// - oFeatureContent (A hidden collection of <li>'s containing the content for each item in oList, the number of <li>'s must match the number in oList)
			if(oWrapper.length === 1 && oList.length === 1 &&  oFeatureDisplay.length === 1 && oFeatureContent.length === oList.children('li').length)
			{
				// Set unique id's on each li element in the format parent_id_item_0 ... parent_id_item_n
				oList.children('li').each(function(index)
				{
					$(this).attr('id', sWrapperId+'_item_'+index);
				});
				
				// Setup events
				setEvents();
				
				// Load initial content
				oFeatureDisplay.html("");
				loadContent(0);
				
				// Start after a delay?
				if(options.carouselInterval >= 0)
				{
					setCarouselTimer();
				}
			}
		}
		function setEvents()
		{
			// Touch devices cannot support hovering so the carousel should never stop
			if(!options.touchDevice)
			{
				// Detect hovering over the entire feature or just the list?
				var oHoverWatch = oWrapper;
				if(!options.autoLoadContentOnCarousel)
				{
					oHoverWatch = oList;
				}
				oHoverWatch.hover(
					function()
					{
						bPause = true;
						if(oCarouselTimer !== null)
						{
							clearTimeout(oCarouselTimer);
						}
					},
					function()
					{
						bPause = false;
						setCarouselTimer();
					}
				);
				
				// We must monitor all video players on a polling loop
				// Not sure why this doesnt work on a setTimeout, maybe because the video element 
				setInterval(function()
				{
					// NB This only works with HTML5 browsers
					// See: http://www.w3schools.com/html5/html5_ref_eventattributes.asp
					$('video, embed').each(function()
					{
						//alert($(this).get(0));
						$(this).get(0).onplaying = function()
						{
							bVideoPlaying = true;
						};
						$(this).get(0).onpause = function()
						{
							bVideoPlaying = false;
						};
					});
					
				}, 1000);
			}
			
			// Detect clicks on the list
			oList.find('li > a').live('click', function()
			{
				// Find li index from id
				var oListItem = $(this).parents('li:eq(0)');
				var sListItemId = oListItem.attr('id');
				var iListItemIndex = parseInt(sListItemId.substr((sWrapperId+'_item_').length), 10);
				
				loadContent(iListItemIndex);
				
				return false;
			});
		}
		function setCarouselTimer()
		{
			if(options.carouselInterval >= 0)
			{
				if(oCarouselTimer !== null)
				{
					clearTimeout(oCarouselTimer);
				}
				if(!bPause && !bVideoPlaying)
				{
					oCarouselTimer = setTimeout(function()
					{
						moveCarousel();
					}, options.carouselInterval);
				}
			}
		}
		function moveCarousel()
		{
			// Find the first feature item, and its height
			var oItemFirst = oList.children('li:first');
			var oItemNext = oList.children('li:eq(1)');
			var iItemFirstHeight = oItemFirst.height();
			
			// Move the carousel
			oList.animate({top: -iItemFirstHeight},
			{
				queue: false,
				carouselDuration: options.carouselDuration,
				complete: function()
				{
					// Move the top item to the bottom
					oList.append(oItemFirst);
					
					// Reset the position
					oList.css({ top: 0 });
					
					// Set a timer to reperform this animation after the requested interval
					setCarouselTimer();
					
					if(typeof options.carouselCallback === 'function')
					{
						options.carouselCallback.call(this);
					}
				}
			});
			
			// loadContent for oItemNext
			if(options.autoLoadContentOnCarousel)
			{
				// Find oItemFirst index from id
				var sItemFirstId = oItemNext.attr('id');
				var iItemFirstIndex = parseInt(sItemFirstId.substr((sWrapperId+'_item_').length), 10);
				
				loadContent(iItemFirstIndex);
			}
		}
		function loadContent(index)
		{
			//alert(oFeatureContent.length);
			// Only perform the load if we are not already viewing this content
			if(iActiveContentIndex != index)
			{
				iActiveContentIndex = index;
				
				// Find related feature content and load it into the feature display area
				var sNewContent = "";
				if(oFeatureContent.length > index)
				{
					sNewContent = oFeatureContent.eq(index).html();
					
					// get all players and their types
					var number_of_players = oFeatureContent.find('ul.overview .mediali > div').length;
					
					if(number_of_players != '')
					{
						var media_box_id = "#"+oFeatureContent.eq(index).find('div:first').attr('id');							
						//alert(number_of_players);
						var media_settings = new Array(number_of_players);
						for(var i = 0; i<media_settings.length; i++){
							media_settings[i] = new Array();
						}
						var m = 0;					
						
						oFeatureContent.find('ul.overview:first .mediali > div').each(function(){
							var n = 0;			
							
							// get type of the media (video or audio)
							media_settings[m][n++]= $(this).attr('class').split(' ').slice(-1);
							
							// get id of the media
							media_settings[m][n++]= "#"+$('div > div', this).eq(0).attr('id');
							
							//get interface id of the media
							media_settings[m][n++]= "#"+$('div > div', this).eq(1).attr('id');						
								
							m++;
						});	

						//console.log(media_settings);
						
						// get filename for this media
						var current_media_filename = oFeatureContent.eq(index).find('ul.overview:first').attr('id');							
					}		
				}
				
				// Determine the fade out duration (this may be instant if there is no content to fade out)
				var iFadeOutDuration = oFeatureDisplay.html().length === 0 ? 0 : options.contentOutDuration;
				
				// Fade out
				oFeatureDisplay.animate({ opacity: 0 },
				{
					queue: false,
					carouselDuration: iFadeOutDuration,
					complete: function()
					{
						// Load new content
						oFeatureDisplay.html(sNewContent);
						
						// Fade in after a short delay
						if(oContentTimer !== null)
						{
							clearTimeout(oContentTimer);
						}
						oContentTimer = setTimeout(function()
						{
							oFeatureDisplay.animate({ opacity: 1 },
							{
								queue: false,
								carouselDuration: options.contentInDuration,
								complete: function()
								{
									// Load jPlayer video player instance
						
									if(number_of_players != '')
									{
										for(var i=0;i<number_of_players;i++)
										{
																					
											// if player with such a name has been already created, destroy it, and create a new one
											
											var array_index = jQuery.inArray(media_settings[i][1],registered_players);
											if(array_index != -1)
											{
												//alert('not new!');
												$(media_settings[i][1]).jPlayer("destroy");
												
												//also remove it from the curently registered players list	
												registered_players.splice(array_index,1);																						
											}
																						
											registerPlayer(current_media_filename,media_settings[i][0],media_settings[i][1],media_settings[i][2], 'features/home');
																						
										}
										
										// Load tinycarousel with minumum settings
										$(media_box_id).tinycarouselplayer();	
										
									}
								}
							});
						}, options.contentDelayDuration);
					}
				});
			}
		}
	};
})(jQuery);
