/* MINIFY ME FOR RELEASE */
/* NOTE FROM SAPIENT: CAN BE USED SITE-WIDE - SO SHOULD BE PLACED IN GLOBAL SCRIPTS ROOT AS OPPOSED TO DUPLICATED PER PRODUCT*/

/* @smartCarousel - custom sape plugin intended to be capable of extending to manage all carousel scenarios*/
jQuery.fn.smartCarousel = function(customArgs) {

	/* @settings (custom || default) */	
	var settings = {
		// Structure
		outerE : $(this),
		innerE : $(customArgs.wrapperElement,this) || $('.sc-inner',this),
		cardsE : $(customArgs.cardElements,this) || $('.sc-item',this),
		cardsV : customArgs.visibleCards || 1, 
		minH : customArgs.minHeight || 0,
		
		// Navigation
		nav: customArgs.navButtons || false,
		prevT : customArgs.prevText || "Previous",
		nextT : customArgs.nextText || "Next",
		paginate : customArgs.paginate || false,
		paginateCustom : customArgs.paginateElement || false,
		paginateAni : customArgs.animatePagination || false,
		loop : customArgs.loop || false,
		
		// Events
		slideCur : customArgs.startingSlide || 1,
		autoplay : customArgs.autoplay || false,
		transition : customArgs.transition || false,
		menuTransitionSpeed : customArgs.menuTransitionSpeed || 1000,
		slideTransitionSpeed : customArgs.slideTransitionSpeed || 1000,
		uniqueType : customArgs.uniqueType || false
	};




	/* @slideCurE - find first card within current slide - returns element (initiated whenever slide specific manipulation is needed)*/
	var slideCurE = function() {
		var el = settings.cardsE.eq( settings.slideCur*settings.cardsV-1 );
		return el;
	};
	
	
	
	
		
	/* @init - executes once on load */
	var init = (function() {
		
		/***** reset hash location on load *****/
				
		if (window.location.hash){window.location.hash = '';}
		
		/***** stop if key elements missing *****/
		
		if (!settings.outerE.length || !settings.innerE.length || !settings.cardsE.length) {
			return false;
		} 

		/***** set essential numbers/booleans *****/
	
		/* Increase min-height if not enough */
		settings.cardsE.each(function() {
			if ($(this).outerHeight() > settings.minH) {
				settings.minH = $(this).outerHeight(true);
			} 
		});
				
		/* Calculate essential numbers */
		settings._cardsX = settings.cardsE.length; // total cards
		settings._cardsW = settings.cardsE.outerWidth(true); // width of cards (assumed to be equal for all)
		settings._slidesW = ( settings.cardsV * settings._cardsW ); // combined width of visible cards
		settings._slidesH = ( settings.cardsV * settings.minH ); // combined height of visible cards
		settings._slidesX = Math.round( (settings._cardsX * settings._cardsW) / settings._slidesW ); // total slides (horizontal scenario)
		settings._totalW = ( settings._cardsX * settings._cardsW ); // combined width of all cards
		settings._totalH = ( settings._cardsX * settings.minH ); // combined height of all cards
		settings._scrollDef = -settings._slidesW; // default scroll (horizontal scenario)
		settings._scrollMax = -( settings._cardsW * (settings._cardsX - settings.cardsV) ); // max scroll (horizontal scenario)

		/***** transition specific settings *****/
			
		/* Common transition groupings */
		if (settings.transition === "cover-up" || settings.transition === "cover-up-layer" || settings.transition === "cover-down" || settings.transition === "cover-down-layer"){
			settings.transitionGroup = "y-cover";
		} 
		
		/* Override scroll numbers for cover left transition */
		if (settings.transition === "cover-left") {
			settings._scrollDef = settings._slidesW; // default scroll
			settings._scrollMax = ( settings._cardsW * (settings._cardsX - settings.cardsV) ); // max scroll
		} 
		
		/* Override scroll numbers for vertical transitions */
		else if (settings.transitionGroup === "y-cover" || settings.transition === "slide-y") {
			settings._slidesX = Math.round( (settings._cardsX * settings.minH) / settings._slidesH ); // total slides
			settings._scrollDef = -settings.minH; // default scroll
			settings._scrollMax = -( settings.minH * settings._slidesX ); // max scroll
			if (settings.transition === "cover-up" || settings.transition === "cover-up-layer" ){
				settings._scrollDef = settings.minH; // default scroll
				settings._scrollMax = ( settings.minH * settings._slidesX ); // max scroll
			} 
		} 

		/***** apply essential CSS properties dependent on transition type *****/

		// Cover transitions
		if (settings.transitionGroup === "y-cover" || settings.transition === "cover-left" || settings.transition === "cover-right") {
			
			settings.innerE.css({
				'width': settings._slideW,
				'height': settings.minH,
				'position': 'relative',
				'overflow' : 'hidden'
			});
			settings.cardsE.css({
				'display': 'block',
				'position': 'absolute',
				'left': settings._scrollDef,
				'top': 0,
				'z-index':10
			});	
	
			// Exception for vertical covers
			if (settings.transitionGroup === "y-cover") {
				settings.cardsE.css({
					'left': 0,
					'top': settings._scrollDef
				});		
			} 
			
			// Active slide
			slideCurE().css({
				'left': 0,
				'top': 0,
				'z-index': 15
			});
		} 
		
		// Slide transitions
		else {
			settings.outerE.css({
				'width': settings._slidesW,
				'height': settings.minH,
				'position': 'relative',
				'overflow': 'hidden'
			});
			settings.innerE.css({
				'width': settings._totalW,
				'left': 0,
				'top': 0,
				'position': 'absolute'
			});
			settings.cardsE.css({
				'clear' : 'none',
				'float' : 'left'
			});	
			
			// Exception for vertical slides
			if (settings.transition === "slide-y") {
				settings.innerE.css({
					'width': settings._slidesW,
					'height': settings._totalH
				});
				settings.cardsE.css({
					'clear': 'both'
				});				
			} 
		} 
		
		// mark as active
		settings.outerE.addClass('activated').removeClass('not-activated');
			
		/***** insert slide navigation elements *****/
	
		/* Prev/next */
		if (settings.nav === true) {
			settings.prevE = '<a href="#" class="sc-prev sc-action">' + settings.prevT + '</a>';
			settings.nextE = '<a href="#" class="sc-next sc-action">' + settings.nextT + '</a>';
			settings.outerE.prepend(settings.prevE);
			settings.outerE.append(settings.nextE);			
		} 
	
		/* Pagination */
		if ( (settings.paginate || settings.paginateCustom) && settings._slidesX > 1) {
	
			/* Custom pagination */
			if (settings.paginateCustom) {
				settings._paginationE = $(settings.paginateCustom);
				settings._paginationE.find('a').each(function(i) {
					$(this).attr('data-sc-slide-rel',i+1).addClass('sc-action');
				});
			} 
			 
			/* Default pagination */
			else {
				var paginationE = '<ul class="sc-pagination" />';
				settings.paginate === "before" ? settings.outerE.prepend(paginationE) : settings.outerE.append(paginationE);
				settings._paginationE = settings.outerE.find('.sc-pagination');
				for (i = 1; i <= settings._slidesX; i++) {
					settings._paginationE.append('<li><a class="sc-action" data-sc-slide-rel="' + i + '" href="#">Goto slide ' + i + '</a></li>');
				} 
			} 
			
			/* Activate starting slide */
			var activePag = settings._paginationE.find('a[data-sc-slide-rel=' + settings.slideCur + ']');
			
			activePag.addClass('sc-active');
			
			if (settings.paginateAni) {
				activePag.css("padding-top","0px").find('span span span').css("padding-bottom","29px");
			} 
		} 
			
		/***** define slide navigation events *****/
	
		settings.outerE.find('.sc-action').click(function() {
			// Cancel if something else in progress
			if (settings._locked) {
				return false;
			} 
			// Define slide to jump to based on button clicked
			var cur = $(this);
			if (cur.hasClass('sc-disabled')) {
				return false;
			} 
			else if (cur.hasClass('sc-next')) {
				settings.slideCur += 1;
			} 
			else if (cur.hasClass('sc-prev')) {
				settings.slideCur -= 1;
			} 
			else {
				settings.slideCur = parseFloat(cur.attr('data-sc-slide-rel'));
			} 
			
			// Now jump to slide
			changeSlide();
			return false;
		});		
		
		/***** for specific carousel types - run initial setup *****/
	
		switch(settings.uniqueType) {
			case "super-highlights":
				// Set first active item
				settings._uniqueE = settings.outerE.find('.market-teaser:first');
				
				// Price block hover resets active item
				settings.outerE.find('.market-prices > li > a:not(.complete)').hover(
					function() {
						if (!settings._locked) {
							var cur = $(this);
							mainActions.pause();
							settings._uniqueE = cur;
							slideCurE().find('.highlight').removeClass('highlight');
							cur.addClass('highlight');		
						} 
					} ,
					function() {} 
				);
			break;
		}
	
	}());





	/* @uniqueReset - for specific carousel types - after arriving at new slide, reset other slides ( initiated by changeSlide() ) */
	var uniqueReset = function() {
		
		switch(settings.uniqueType) {
			case "super-highlights":
				// reset position of non-visible cards' elements, and set first active item in current visible card
				slideCurE().siblings('.super-highlights-item').find('.market-teaser').each(function() {
					$(this).css('left','36px').show().siblings('.market-odds').hide().css('right','-477px');
					settings._uniqueE = slideCurE().find('.market-teaser');
				});
			break;
		} 
		
	};




			
	/* @mainActions - listens for play/pause instructions */
	var nextEvTrigger;
	var mainActions = {
		pause : function() {
			if (settings.autoplay && settings._status !=='stopped') {
				settings._status = 'stopped';
				clearInterval(settings.nextEvTrigger);
			} 
		} ,
		play : function() {
			if (settings.autoplay && settings._status !=='started') {
				settings._status = 'started';
				var triggerNext = function() {
					settings.outerE.trigger('next-event');
				};
				settings.nextEvTrigger = setInterval(triggerNext, settings.autoplay);
			} 
		} ,
		genericTriggers : function() {
			/* Play on load */
			mainActions.play();

			/* Define generic play/pause triggers*/
			if (settings.autoplay) {
				settings.innerE.find('a').hover(
					function() {mainActions.pause();} ,
					function() {mainActions.play();} 
				);
				settings.innerE.find('a').focus(
					function() {mainActions.pause();} 
				);	
				settings.innerE.find('a').blur(
					function() {mainActions.play();} 
				);			
			} 		
		} 
	};
	mainActions.genericTriggers();





	/* @changeSlide - moves between slide views (initiated by nextEv() / navigation element events) */
	var changeSlide = function() {
		
		// Pause
		settings._locked = true;
		mainActions.pause();
		
		// Infinite first and last slide
		if (settings.loop) {
			if (settings.slideCur > settings._slidesX) {
				settings.slideCur = 1;
			} 
			else if (settings.slideCur < 1) {
				settings.slideCur = settings._slidesX;
			} 
		} 
		
		// Calculate new position
		settings._scrollReq = (settings.slideCur - 1) * settings._scrollDef;
		
		// For slide transition - animate, then reset other slides
		if (settings.transition === "slide-x") {
			settings.innerE.animate({left: settings._scrollReq + "px"} , settings.slideTransitionSpeed, function() {
				uniqueReset();
			});
		} 
		// For vertical cover transition - animate, then reset other slides
		else if (settings.transitionGroup === "y-cover") {
			if (settings.transition === "cover-up" || settings.transition === "cover-down"){
				slideCurE().css({'display':'block'});
				slideCurE().siblings().css({'display':'none'});			
			}
			slideCurE().siblings().css({'z-index':10});
			slideCurE().css('z-index','15').animate({top: "0"} , settings.slideTransitionSpeed, function() {
				slideCurE().siblings().css('top',settings._scrollDef);
				uniqueReset();
			});
		} 
		// For horizontal cover transition - animate, then reset other slides
		else if (settings.transition === "cover-left" || settings.transition === "cover-right") {
			slideCurE().siblings().css('z-index',10);
			slideCurE().css('z-index','15').animate({left: "0"} , settings.slideTransitionSpeed, function() {
				slideCurE().siblings().css('left',settings._scrollDef);
				uniqueReset();
			});
		} 
		// For no transition - show correct slide, then reset others
		else {
			settings.innerE.css({"left":settings._scrollReq});
			uniqueReset();
		} 

		// Pagination active state
		if (settings.paginate || settings.paginateCustom) {

			var oldActive = settings._paginationE.find('a.sc-active');
			var newActive = settings._paginationE.find('a[data-sc-slide-rel='+ settings.slideCur + ']');

			if (settings.paginateAni === true) {
				oldActive.removeClass('sc-active');
				newActive.addClass('sc-active');	
                oldActive.animate( { "paddingTop": "20px" }, settings.menuTransitionSpeed ).find('span span span').animate( {  "paddingBottom": "9px" }, settings.menuTransitionSpeed );
				newActive.animate( { "paddingTop": "0px" }, settings.menuTransitionSpeed ).find('span span span').animate( { "paddingBottom": "29px" }, settings.menuTransitionSpeed );
			} 

		} 

		// Play
		settings._locked = false;
		mainActions.play();
	
	};





	/* @nextEv - works out what should happen next (triggered by outerE's 'next-event') */
	var nextEv = function() {

		// If default carousel type
		if (!settings.uniqueType) {
			// Just move to the next slide
			settings.slideCur += 1;
			changeSlide();
			return false;
		
		} 
		
		// If specific carousel type
		settings._locked = true;
		
		switch(settings.uniqueType) {
			case "super-highlights":
			
				
				// Remove highlight from price blocks
				settings.innerE.find('.highlight').removeClass('highlight');
				
				// If we were on the first view of a slide - market-teaser
				if (settings._uniqueE.hasClass('market-teaser')) {
					
					// Slide in prices boxes, and set first non-disabled one to active
					settings._uniqueE.animate({left: "-477px"} ,1000,function() {$(this).hide();});
					settings._uniqueE.siblings('.market-odds').show().animate({right: "33px"} ,1000).find('.market-prices li:first a');
					settings._uniqueE = settings._uniqueE.siblings('.market-odds').find('.market-prices a:not(.complete):first');
					settings._uniqueE.addClass('highlight');
				} 
				
				// If we were on the second view of a slide - market-prices
				else if (settings._uniqueE.parents('.market-prices').length) {
					var nextBlock = settings._uniqueE.parent('li').next('li').children('a:not(.complete)');
	
					if (!nextBlock.length) {
						nextBlock = settings._uniqueE.parent('li').next('li').next('li').children('a:not(.complete)');
					} 
					
					// If that wasn't the last price block in this slide, highlight the next
					if (nextBlock.length) {
						settings._uniqueE = nextBlock;
						nextBlock.addClass('highlight');
					} 
					// If that was the last price block in this slide, move on
					else {
						settings.slideCur += 1;
						changeSlide();
					} 
				} 
								
			break;
		} 
		
		settings._locked = false;
		
	};
	settings.outerE.bind('next-event', function() {
		nextEv();
	});	
			
	return this;
};
