/**
 * jQuery Editorial Pod
 * 
 * @version 0.01 - Initial build of the plugin.
 * 
 * @author Filip Michalowski / Fi Stockholm
 */
var videoPlayerCallback;

(function ($) {
	$.fn.editorial = function (options) {

		// Define our element
		if (!this[0]) {
			return;
		}		
				
		// Set our default options
		options = $.extend({		
			videoPlayerUrl: "/media/swf/videoplayer.swf",	// path to the video player swf		
			localization: "/media/swf/xml/videoplayer_locale_en.xml",	// url of the localization xml file	
			minTillAgeExpires: "30",							// time till age gate expiration (in minutes)
			rotationDelay: 5000,							// rotation delay			
			enableAutoRotation: false,						// sets the autoration on/off
			moduleData: []									// data object of the module ( defines the media paths and more info links )
			
		}, options || {});
		
		//private variables:
		
		var moduleContainer = $(this[0]);			// module container
		var mediaContainer;							// container of images and video player
		var mediaListHolder;						// holder element of the thumbnail list
		var rotationInterval;						// interval time of the rotation timer
		var numItems;								// number of items in the thumbnail list
		var currentItemIndex;						// index of current displayed item
		var image;									// image element
		var imageCopy;								// image copy element
		var overlayButton;							// overlay element ( mask and border )
		var videoPlayer;							// video player ( swf )
		var visibleItems = 3;						// number of visible thumbnails
		var isAnimating = false;					// flags if big image is currently animating
		var isSliding = false;						// flags if thumbnail list is currently animating
		var isShowingVideo = false;					// flags if video is currently visible
		var itemWidth;								// width of the thumbnail
		var itemHeight;								// height of the thumbnail
		var itemPadding;							// padding of the thumbnail
		var itemTotalWidth;							// total width of the item in the thumbnail list (width+padding)
		var showVideoTimer;							// timer that shows the video element
		var scrollTimer;							// timer that scrolls the thumbnail list ( while pressing the next/previous button )
		var scrollTimerInterval = 50;				// interval time of the scrollTimer
		var scrollStartTimer;						// timer that starts the scrollTimer ( delay after pressing the next/previous button )
		var scrollStartTimerInterval = 300;			// interval time of the scrollStartTimer
		var scrollStep = 20;						// amount of pixels to scroll while pressing the next/previous button
		
		//private methods:
		
		/**
		 * Renders the component
		 */
		var draw = function() {		
			
			mediaContainer = moduleContainer.find("div.imageContainer");
			mediaListHolder = moduleContainer.find("div.mediaListHolder");
			playButton = moduleContainer.find(".expandedContainer .playButton");
			videoPlayer = moduleContainer.find(".expandedContainer .videoPlayer");
			
			// remove noJS CSS class
			moduleContainer.removeClass("noJS");
			
			// calculate the size of thumbnail
			itemWidth = mediaListHolder.find("li").width();
			itemHeight = mediaListHolder.find("li").height();
			itemPadding = Number( mediaListHolder.find("li").css("margin-right").split("px").join("") );
			itemTotalWidth = itemWidth + itemPadding;
			
			// hide horizontal scrollbar
			moduleContainer.find("div.mediaListHolderWrapper").css({overflowX:"hidden", height: itemHeight});			
			
			// set the width of list holder
			numItems = mediaListHolder.find("ul").children().length;		
			var listWidth = numItems * itemTotalWidth;
			mediaListHolder.css("width", listWidth + "px");
			
			//set mouse events listeners for thumbs
			mediaListHolder.find("a.image").click(function(index){
				selectItem(mediaListHolder.find("a.image").index(this),true);
				resetRotationInterval();
				return false;
			});		
			
			// create a holder for a copy of the image (used for animation)
			imageCopy = moduleContainer.find(".expandedContainer .image").clone().removeClass("image").addClass("imagecopy");
			image = moduleContainer.find(".expandedContainer .image").before( imageCopy );
			
			//create video player
			videoPlayerCallback = onVideoComplete;			
			var flashvars = { callback: "videoPlayerCallback", closeCallback: "videoPlayerCallback", localeURL: options.localization, minTillAgeExpires: options.minTillAgeExpires };
			var params = {bgcolor:"#242424", allowScriptAccess: "always", wmode: "opaque"};
			var attributes = {id: "atari_video_player"};
			swfobject.embedSWF(options.videoPlayerUrl, "videoPlayerContainer", String($(".videoPlayer").width()), String($(".videoPlayer").height()), "8", "media/swf/expressInstall.swf", flashvars, params, attributes, onSWFReady);
						
			//initialize video play button
			playButton.bind( "click", function(e) { showVideo(); return false; } );	
						
			//initialize navigation
			initNavigation();
			
			//select first item		
			selectItem(0,false);
			
			//start rotation
			startRotationInterval();
					
		};
				
		/**
		 * Called when SWF has been embedded 
		 */
		var onSWFReady = function() {			
			$("#atari_video_player").hide();
		}
		
		/**
		 * Initializes the navigation scroll bar and buttons
		 */
		var initNavigation = function() {
			
			var prevButton = moduleContainer.find("a.imageprev");
			var nextButton = moduleContainer.find("a.imagenext");
			
			moduleContainer.find(".navigation").css({ display:"block" });
						
			if (numItems > visibleItems) {			
				
				var listWidth = numItems * itemTotalWidth;		
				var left = 0;
				var maxLeft = 0;
				var minLeft = - listWidth + visibleItems * itemTotalWidth;
				var expandedContainer = moduleContainer.find(".expandedContainer");			
				
				// set the scrolling params depending on the browser type
				if ( $.browser.msie )
				{
					scrollTimerInterval = 50;
					scrollStep = 20;
				}
				else if ( $.browser.safari )
				{
					scrollTimerInterval = 33;
					scrollStep = 13;
				}
				else if ( $.browser.mozilla )
				{
					scrollTimerInterval = 50;
					scrollStep = 20;
				}
				
				prevButton.fadeTo(50, 0.5).css("cursor", "default").addClass("disabled");
			
				// set listeners for prev and next buttons
				nextButton.click(function(){				
					left = Number(mediaListHolder.css("left").split("px").join("")) - itemTotalWidth;					
					left = Math.ceil( left / itemTotalWidth) * itemTotalWidth;
					if (left <= minLeft) {
						left = minLeft;					
					}				
					
					animateMediaList( left, true );
					return false;
				});
				
				nextButton.mousedown(function(){					
					setScrollTimers(-1);					
					return false;
				});
				
				nextButton.mouseup(function(){		
					clearScrollTimers();
					return false;
				});
				
				nextButton.mouseout(function(){	
					if ( scrollTimer )
					{
						nextButton.click();
					}				
					clearScrollTimers();
					return false;
				});
				
				prevButton.click(function(){
					left = Number(mediaListHolder.css("left").split("px").join("")) + itemTotalWidth;
					left = Math.floor( left / itemTotalWidth) * itemTotalWidth;
					if (left >= maxLeft) {
						left = maxLeft;
					}
					
					animateMediaList( left, true );
					return false;
				});	
				
				prevButton.mousedown(function(){	
					setScrollTimers(1);					
					return false;
				});
				
				prevButton.mouseup(function(){					
					clearScrollTimers();					
					return false;
				});
				
				prevButton.mouseout(function(){					
					if ( scrollTimer )
					{
						prevButton.click();
					}
					clearScrollTimers();					
					return false;
				});	
				
				// stop rotating items when user mouse over the image
				expandedContainer.mouseover(function() {
					stopRotationInterval();
				});
				expandedContainer.mouseout(function() {
					startRotationInterval();
				});				
			}
			else
			{
				prevButton.fadeTo(50, 0.5).css("cursor", "default").addClass("disabled");
				nextButton.fadeTo(50, 0.5).css("cursor", "default").addClass("disabled");
				
				nextButton.click(function(){
					return false;
				});
				prevButton.click(function(){
					return false;
				});	
			}
		};
		
		/**
		 * Creates the scroll timers
		 * 
		 * @param {Object} dir		Direction of scroll
		 */
		var setScrollTimers = function(dir) {
			scrollStartTimer = setTimeout( function(){
					scrollTimer = setInterval( function(){onScrollTimer(dir)}, scrollTimerInterval );
					scrollStartTimer = null;
				}, scrollStartTimerInterval );	
		}
		
		/**
		 * Clears the scroll timers
		 */
		var clearScrollTimers = function() {
			clearTimeout(scrollStartTimer);			
			clearInterval(scrollTimer);
			scrollStartTimer = null;
			scrollTimer = null;
		}
		
		/**
		 * @param {Object} dir		Direction of scroll
		 */
		var onScrollTimer = function(dir) {
			var listWidth = numItems * itemTotalWidth;		
			var left = 0;
			var maxLeft = 0;
			var minLeft = - listWidth + visibleItems * itemTotalWidth;			
			
			left = Number(mediaListHolder.css("left").split("px").join("")) + scrollStep * dir;
			
			if (left <= minLeft)
			{
				left = minLeft;
				clearInterval(scrollTimer);
				scrollTimer = null;
			}
			else if (left >= maxLeft)
			{
				left = maxLeft;
				clearInterval(scrollTimer);
				scrollTimer = null;
			}
						
			mediaListHolder.css("left",left+"px");
			
			setNavigationButtons(left);
		}
		
		/**
		 * Shows the video player
		 */
		var showVideo = function() {
			isShowingVideo = true;
			stopRotationInterval();
			if ( $.browser.msie )
			{
				playButton.hide();
			}
			else
			{
				playButton.fadeOut(100);	
			}			
									
			videoPlayer.addClass("videoPlayerShow").css({top:0});			
			$("#atari_video_player").fadeIn(250);
			
			// call the video player to start playing
			var itemData = options.moduleData[currentItemIndex];
			
			showVideoTimer = setInterval( function(){
					onShowVideo();
				}, 10 );			
		}
		
		/**
		 * 
		 */
		var onShowVideo = function() {
			var itemData = options.moduleData[currentItemIndex];
			
			try
			{				
				VideoPlayerAPI.Play( itemData.mediaurl, itemData.link, itemData.ageLimit );
				mediaContainer.addClass("videoShow");	
				clearInterval(showVideoTimer);	
				showVideoTimer = null;
			}
			catch(e)
			{
				// video player error
			}			
		}
		
		/**
		 * Called on video complete event.
		 * Shows the image.
		 */
		var onVideoComplete = function() {				
			
			// hide video
			hideVideo();
			
			// show the same item again						
			isAnimating = true;				
			image.stop().css({					
					opacity: 0
				}).animate({
					opacity: 1					
				}, {
					duration: 250,
					complete: onItemFadedIn,
					easing: "easeOutQuad"
				});
			
			// hide play button 
			if ( $.browser.msie )
			{
				playButton.hide();
			}
			else
			{
				playButton.fadeOut(100);	
			}	
		}
		
		/**
		 * Hides the video player
		 */
		var hideVideo = function() {
			isShowingVideo = false;
						
			// call the video player to stop playing			
			VideoPlayerAPI.Stop();
			
			mediaContainer.removeClass("videoShow");
			videoPlayer.removeClass("videoPlayerShow").removeClass("videoPlayerPrepareToHide");		
			$("#atari_video_player").hide();
		}
		
		/**
		 * Resets the PNG alpha transparency setting for IE browsers (required after animating the opacity of the image)
		 */
		var resetOpacityForIe = function() {
			playButton.css("filter", "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=x.png,sizingMethod='scale')");
		}
		
		/**
		 * Animates the thumbnail list
		 * 
		 * @param {Object} position - value of final x position
		 * @param {Object} fromUser - flag if the call is comming from clicking the previous or next button
		 */
		var animateMediaList = function( position, fromUser ) {
			
			if ( isSliding )
			{
				return;
			}
			
			isSliding = true;
			
			var slideDuration = fromUser ? 350 : 400;
										
			mediaListHolder.stop().animate({left: position + "px"}, {
				duration: slideDuration,
				easing: "easeOutQuad",
				complete: onAnimateComplete,
				queue: false
			});
			
			setNavigationButtons(position);			
					
			stopRotationInterval();
		};
		
		/**
		 * 
		 */
		var onAnimateComplete = function() {
			isSliding = false;
			startRotationInterval();
		};
		
		/**
		 * Sets the visibility of the navigation buttons
		 */
		var setNavigationButtons = function(position) {
			var listWidth = numItems * itemTotalWidth;		
			var maxLeft = 0;
			var minLeft = - listWidth + visibleItems * itemTotalWidth;				
			var prevButton = moduleContainer.find("a.imageprev");
			var nextButton = moduleContainer.find("a.imagenext");
			
			if (position === minLeft) {
				nextButton.fadeTo(50, 0.5).css("cursor", "default").addClass("disabled");
			} else if (nextButton.css("opacity") != 1) {
				nextButton.fadeTo(50, 1).css("cursor", "pointer").removeClass("disabled");				
			}
			
			if (position === maxLeft) {
				prevButton.fadeTo(50, 0.5).css("cursor", "default").addClass("disabled");
			} else if (prevButton.css("opacity") != 1) {
				prevButton.fadeTo(50, 1).css("cursor", "pointer").removeClass("disabled");				
			}
		}
		
		/**
		 * Selects item
		 * 
		 * @param {Object} index
		 */
		var selectItem = function(index,animate) {
			
			if ( ( currentItemIndex == index ) || isAnimating ) 
			{
				return;
			}
			
			isAnimating = true;						
			currentItemIndex = index;
			
			// select the thumbnail
			var previousThumb = moduleContainer.find("a.selected").removeClass("selected");
			var currentThumb = moduleContainer.find("ul").children().eq(index).find("a.image").addClass("selected");
			
			// enable the download link for the current thumbnail
			currentThumb.parent().find("div.download").show();
			
			//disable the download link for the previous thumbnail
			previousThumb.parent().find("div.download").removeClass("selected");
									
			// animate the thumbnail
			var slideImageDuration = 550;
			var slideThumbDuration = 500;
			var fadeImageDuration = 300;
			var fadeThumbDuration = 200;
			var easing = "easeOutCubic";
			
			$("img",previousThumb).css({opacity:0,top:0}).animate({ 
			        opacity: 1
			      }, {
				  	duration: fadeThumbDuration,
					complete: function() { previousThumb.parent().find("div.download").hide(); }
				  } );
			$("img",currentThumb).animate({ 
			        top: -itemHeight
			      }, {
				  	duration: slideThumbDuration,	
					easing: easing,				
					complete: function() { currentThumb.parent().find("div.download").addClass("selected");}
				  } );
					
			if (isShowingVideo) {
				// hide video
				// hideVideo();
				videoPlayer.stop().addClass("videoPlayerPrepareToHide").animate({
					top: -videoPlayer.height()
				}, {
					duration: slideImageDuration,
					complete: hideVideo,
					easing: easing
				});
				
			}
			else {
				// create a copy image
				imageCopy.attr("src", image.attr("src")).css({top: 1});
				imageCopy.show();
			}
			
			// create image
			var itemData = options.moduleData[index];
			image.attr({src: moduleContainer.find(".imagesHolder img").eq(index).attr("src"), alt: itemData.title});
			
			// animate image	
			if (animate) {
				image.stop().css({					
					top: image.height()+1
				}).animate({
					top: 1					
				}, {
					duration: slideImageDuration,
					complete: onItemFadedIn,
					easing: easing
				});
				imageCopy.stop().animate({
					top: -imageCopy.height()+1					
				}, {
					duration: slideImageDuration,
					easing: easing
				});
			}
			else
			{
				image.stop().css({					
					opacity: 0
				}).animate({
					opacity: 1					
				}, {
					duration: fadeImageDuration,
					complete: onItemFadedIn,
					easing: easing
				});
			}			
			
			// hide play button 
			playButton.fadeOut(100);	
			
			// slide the list
			slideToCenter();
		};
		
		/**
		 * 
		 */
		var onItemFadedIn = function() {			
			isAnimating = false;
			imageCopy.hide();
			
			var itemData = options.moduleData[currentItemIndex];
			if ( itemData.type == "video" )
			{
				var o = { duration: 200 };
				
				if ( $.browser.msie )
				{
					resetOpacityForIe();
					o.step = resetOpacityForIe;
					o.complete = resetOpacityForIe;
				}
				
				playButton.show().css({					
					opacity: 0
				}).animate({
					opacity: 1					
				}, o);				
			}
		};
		
		/**
		 * Starts the autorotation timer
		 */
		var startRotationInterval = function() {
			if (rotationInterval === undefined && options.enableAutoRotation && !isShowingVideo) {
				rotationInterval = setInterval(function(){
					onRotationInterval();
				}, options.rotationDelay);
			}		
		};
		
		/**
		 * Stops the autorotation timer
		 */
		var stopRotationInterval = function() {
			clearInterval( rotationInterval );
			rotationInterval = undefined;		
		};
		
		/**
		 * 
		 */
		var resetRotationInterval = function() {
			stopRotationInterval();
			startRotationInterval();
		};
		
		/**
		 * 
		 */
		var onRotationInterval = function() {
			var nextItemIndex = currentItemIndex + 1;
			
			if ( nextItemIndex === numItems ) {
				nextItemIndex = 0;
			}		
			
			selectItem( nextItemIndex, true );
			
			var mediaListPos = mediaListHolder.css("left").substring( 0, mediaListHolder.css("left").length-2 );
			var nextItemPos = nextItemIndex * itemTotalWidth;
					
			if ( nextItemPos + itemTotalWidth >= -mediaListPos + visibleItems*itemTotalWidth ) {
				if (nextItemIndex != numItems - 1) {
					animateMediaList(-(nextItemIndex - visibleItems + 2) * itemTotalWidth);
				}
				else {
					animateMediaList(-(numItems - visibleItems) * itemTotalWidth);
				}
			} else if ( nextItemPos < -mediaListPos ) {
				animateMediaList(-(nextItemIndex) * itemTotalWidth);			
			} else if ( nextItemIndex === 0 && numItems > visibleItems ) {
				animateMediaList(0);	
			}
			
		};
		
		/**
		 * Animates the media list to show the current item in the middle
		 * @param {Object} direction
		 */
		var slideToCenter = function() {
						
			if ( currentItemIndex === numItems-1 || currentItemIndex === 0 ) {
				return;
			}
			var newItemIndex = currentItemIndex - 1;
			animateMediaList(-(newItemIndex) * itemTotalWidth);
		};
	
		draw();
		
	};
}(jQuery));