/*
 * Marquee - jQuery Plugin
 *
 * Progressive Computing LLC.
 * jQuery 1.4.x
 *
 * Date: April 16, 2011
 *
 * EXAMPLE INITIALIZATION:
 * ----------------------------------------------
 * $(document).ready(function() {
 *            var callBack = function(){
 *                   // callBack scope is the Marquee DIV
 *                   alert(this.innerHTML)
 *            }
 *
 *            $(".marquee").Marquee({defaultIndex:0, callBack:callBack});    
 * });
 */
(function($) {

	$.fn.Marquee = function(options) {
		/**
		 * @options
		 * @defaultIndex {int}The tab screen to display at runtime
		 * @selectedClass {int}The container width of the acordion menu
		 * @animationIn {int}The tab width of an accordion menu
		 * @animationOut {int} Any space between the accordion menu tabs
		 * @animationTimeIn {obj} An event handler when a tab is chosen
		 * @animationTimeOut {obj} An event handler when a tab is chosen
		 * @slideTimer {obj} An event handler when a tab is chosen
		 * @callBackOut {obj} An event handler when a tab is chosen
		 * @callBackIn {obj} An event handler when a tab is chosen 
		 */
		$.fn.Marquee.defaultOptions = {
			   defaultIndex:0,
			   selectedClass:'selected',
			   animationIn:'horizontalSlide',
			   animationOut:'horizontalSlide',
			   animationTimeIn:500,
			   animationTimeOut:500,
			   slideTimer:7000,
			   callBackOut:null,
			   callBackIn:null
		}

		var m_publicObj = {};

		 // A member variable used to store the Tab container element. This will be the
		 // DIV element with the classname of 'tabControl' assigned.
		var m_controlWrapper = $(this),

			// If an options object is sent at runtime merge default options with user specified
			// options into a single options object. If none specified use default options.
			m_options = (typeof(options) == 'object') ?
			$.extend({}, $.fn.Marquee.defaultOptions, options) : $.fn.Marquee.defaultOptions,

			m_containerWidth = parseInt($(this).css('width')),
			m_containerHeight = parseInt($(this).css('height')),

			m_slideLength = $('.slide-wrap', m_controlWrapper).children().length,

			m_slideTransition,

			// Flag for animation
			m_isAnimating;

		 // Assign class to all slide DIVs which removes them from view
		 // Flag default tag by the options config and set to display		 
		$('.slide-wrap', m_controlWrapper).children().each(function(i){

			// Iterate through each slide.
			var elm = $(this);

			// Make sure we Should Not Ignore Slide Initially
			if(!elm.hasClass('ignore')){

				// Add config data to the DIV.slide element
				elm.data('index', i);

				// Add tabBody class to all tab windows
				if(m_options.animationOut == "horizontalSlide"){
					  elm.addClass('tabBodyHorizontalSlide');
				}else{
					  elm.addClass('tabBody');
				}

				if(i == m_options.defaultIndex){					
					elm.addClass(m_options.selectedClass);
					
					// Show Supporting Text
					var bannerText = $(".headTitle-wrap").children().eq(i);
					bannerText.addClass('selected');
					bannerText.fadeIn('fast')
				}
			}
		});
		
		// Loop through all subtext for each slide and position the link
		// more according to the tallest baseline between the left and right
		// columns.
		$('.headTitle-wrap').children().each(function(){
			var elm = $(this),
				
				leftCol = $('div', elm).eq(0),
				rightCol = $('div', elm).eq(1),
				anchorLink = $('div', elm).eq(1);
				
				if(leftCol.offsetHeight > rightCol.offsetHeight){
					// Left Column is Taller
						// To - DO
				}else{
					// Right Column is Taller
						// To - DO
				}
		});

		// Create Navigation Controls
		// Used to assign Index Values to direct Slide Links. Exclude < and > options in control
		var slideCounter = 0;

		// Loop Through Controls and Add Events
		$('.controls .slide span', m_controlWrapper).each(function(i, e){

			// reference the jQuery object
			var $el = $(e);

			if(!$el.hasClass('btnPausePlay')){
				// Assign the event to the anchor link
				$el.click(function(p_event){

					// ensure tab is not currently selected.
					if(this.className.indexOf(m_options.selectedClass) == -1){

						if(!m_isAnimating){
							// Setup Events based on Tab Transition
							if(m_options.slideTimer != null){
								// Stop transition for focus
								if(m_options.slideTimer){
									  stopSlideTransition();
								}
							}

							changeSlide(this);
						}
					}
				});

				// Assign Control Mouse Over Events
				$el.hover(
					function (e) {
						var $this = $(this),
							menuId = $this.parent().children().index($this);
						
						$this.css('z-index','10');
						$this.parent().prev().children().eq(menuId).animate({top:'0px'}, 'fast');
					},

					function () {
						var $this = $(this),
							menuId = $this.parent().children().index($this);
						
						$this.css('z-index','1');
						$this.parent().prev().children().eq(menuId).animate({top:'50px'}, 'fast');
					}
				)

				// Assign the tab index to the anchor link using jQuery's data method
				$el.data('index', i);

				if(i == m_options.defaultIndex){
					$el.addClass(m_options.selectedClass);
				}
			}
		});
		
		// Setup Pause/Play Button
		$('.controls .slide span.btnPausePlay', m_controlWrapper).hover(
			function () {
				if($(this).hasClass('pause')){
					this.style.backgroundPosition = 'top right';
				}else{
					this.style.backgroundPosition = 'bottom right';
				}
			},

			function () {
				if($(this).hasClass('pause')){
					this.style.backgroundPosition = 'top left';
				}else{
					this.style.backgroundPosition = 'bottom left';
				}
			}
		)
		
		$('.controls .slide span.btnPausePlay', m_controlWrapper).click(function(){
		
			if($(this).hasClass('pause')){
				stopSlideTransition();
			}else{
				setSlideTransition();
			}
			
			$(this).toggleClass('pause')
		});

		// Start Timer
		setSlideTransition();


		// ********************************************************************************
		function changeSlide(p_index, p_auto){

			// Que to Change Slide. 
			// Set animation flag
			m_isAnimating = true;

			if(m_options.slideTimer != null){
				stopSlideTransition();
			}

			// Get the chosen slide index
			var chosenSlideIndex = $(p_index).data('index'),

				// Get jQuery object of active window. Get the current displayed DIV element (i.e. tab window) 
				// and fade out. The ':first' selector ensures only one result is returned.
				activeSlide = $('.slide-wrap > div.' + m_options.selectedClass + ':first', m_controlWrapper),

				// Declare callBack event for animation end
				callBack = function(){
					// Call function if callBackOut is specified
					if(m_options.callBackOut != null){
							m_options.callBackOut.apply(m_controlWrapper, arguments);
					}

					// Animation is complete. Show selected tab
					showSlide(chosenSlideIndex);
				},
				
				navDirection = null;

			// Check if Nav Buttons Are Pressed For 'Back' and 'Next'
			if(!p_auto && chosenSlideIndex ==0){
				// Get Current Slide Index				
				var activeSlideIndex = $('.slide-wrap > div', m_controlWrapper).index(activeSlide);

				// Flag For Beginning of List					
				chosenSlideIndex = 0;

				navDirection = 'left';
			}

			switch(m_options.animationOut){
				case "slideUp":
					activeWindow.slideUp(m_options.animationTimeOut, callBack);
					break;
				case "horizontalSlide":
					var activeSlideIndex = $('.slide-wrap > div', m_controlWrapper).index(activeSlide),
						chosenSlide = $('.slide-wrap > div:eq(' + chosenSlideIndex + ')', m_controlWrapper),
						removeSlide = function(){
							$(this).css('display','none');
						}

					// Add chosenSlideIndex != 0 to move slides left to right on last slide
					if((chosenSlideIndex < activeSlideIndex) && (chosenSlideIndex != 0) || navDirection == 'left'){
						// Move Left
						chosenSlide.css('display','block').css('left', m_containerWidth).animate({left:'0px'}, 'normal', callBack);
						activeSlide.animate({left:(m_containerWidth * -1)}, 'normal', removeSlide);
					}else{

						// Move Right
						chosenSlide.css('display','block').css('left', (m_containerWidth * -1)).animate({left:'0px'}, 'normal', callBack);
						activeSlide.animate({left:m_containerWidth}, 'normal', removeSlide);
					}
					break;
				default:
						activeSlide.fadeOut(m_options.animationTimeOut, callBack);
					 break;
			}
		};

		function showSlide(p_tabIndex){

			// Remove the m_options.selectedClass class from any selected slides
			$('.slide-wrap > div.' + m_options.selectedClass, m_controlWrapper).removeClass(m_options.selectedClass);
			
			// Remove the m_options.selectedClass class from any slide controls			
			$('.controls span.' + m_options.selectedClass, m_controlWrapper).removeClass(m_options.selectedClass);

			// Add m_options.selectedClass class to new selected slide. The 'eq' selector
			// allows us to select the anchor link by the index value of the returned result.
			$('.slide-wrap > div:eq('+ p_tabIndex  +')', m_controlWrapper).addClass(m_options.selectedClass);

			// Add selected state to slide control
			$('.controls .slide span:eq('+ p_tabIndex +')', m_controlWrapper).addClass(m_options.selectedClass);

			// Add m_options.selectedClass class to new DIV element tab window
			var chosenWindow = $('.slide-wrap > div:eq('+ p_tabIndex  +')', m_controlWrapper).addClass(m_options.selectedClass),

				// callBack function for animation end event
				callBack = function(){
					// Call function if callBackIn is specified
					if(m_options.callBackIn != null){
							m_options.callBackIn.apply(m_controlWrapper, arguments);
					}

					if(m_options.slideTimer != null){
						setTabTransition();
					}

					// Update Text to go With Banner
					showBannerText(p_tabIndex);
					
					// Set animation flag
					m_isAnimating = false;
				}

			switch(m_options.animationIn){
				case "slideDown":
					chosenWindow.hide().slideDown(m_options.animationTimeIn, callBack);
					break;
				case "horizontalSlide":
					// We Do Nothing Here Since It was Already Done with Switch Tab
					// Call function if callBackIn is specified
					if(m_options.callBackIn != null){
						m_options.callBackIn.apply(m_controlWrapper, arguments);
					}

					if(m_options.slideTimer != null){
						setSlideTransition();
					}

					// Update Text to go With Banner
					showBannerText(p_tabIndex);

					// Set animation flag
					m_isAnimating = false;						
					break;
				default:
					chosenWindow.hide().fadeIn(m_options.animationTimeIn, callBack);
					break;
			}
		};
		
		function showBannerText(p_index){
		
			// Get Current Text DIV Tag
			var curText = $(".headTitle-wrap div.selected"),
			
				newText = $(".headTitle-wrap").children().eq(p_index),
				
				callBack = function(){
					// Remove state from existing text
					curText.removeClass('selected');
				
					// Show New Text
					newText.fadeIn('fast', function(){ $(this).addClass('selected') } ); 
				}
		
				curText.fadeOut('fast', callBack);
		}

		function showModalSlide(p_slide){
			
			stopSlideTransition();
			
			var activeSlide = $('.slide-wrap > div.' + m_options.selectedClass + ':first', m_controlWrapper),
				chosenSlide = $('', m_controlWrapper)
			
			activeSlide.fadeOut(m_options.animationTimeOut);
			
			chosenWindow.hide().fadeIn(m_options.animationTimeIn, callBack);
			

		}

		function closeModalSlide(p_slide){
			alert('closeModalSlide')
		}

		function setSlideTransition(){

			var intervalFunction = function(){

				// Get the current index of the tab being displayed
				var currentSlideIndex = $('.slide-wrap > div', m_controlWrapper).index($('.slide-wrap > div.' + m_options.selectedClass, m_controlWrapper));

				// Incrament slide to Next One
				currentSlideIndex++;

				// Make sure we have slide ceiling                
				if(currentSlideIndex == m_slideLength){
					 currentSlideIndex = 0;
				}

				// Switch to next slide
				changeSlide($('.slide-wrap > div:eq(' +  currentSlideIndex + ')', m_controlWrapper), true);
			}

			m_slideTransition = setTimeout(intervalFunction, m_options.slideTimer);
		}

		function stopSlideTransition(){
			clearTimeout(m_slideTransition);
		}
		
		function stopTransition(){
			
			var btnPlayPause = $('.controls .slide span.btnPausePlay', m_controlWrapper);
					
			if(btnPlayPause.hasClass('pause')){
				stopSlideTransition();
				btnPlayPause.removeClass('pause');
				btnPlayPause.css('backgroundPosition','bottom left');
			}
		}
		
		function startTransition(){
			
			var btnPlayPause = $('.controls .slide span.btnPausePlay', m_controlWrapper);
					
			if(!btnPlayPause.hasClass('pause')){
				setSlideTransition();
				btnPlayPause.addClass('pause');
				btnPlayPause.css('backgroundPosition','top left');				
			}
		}

		m_publicObj = {
			stopTransition:stopTransition,
			startTransition:startTransition,
			showModalSlide:showModalSlide,
			closeModalSlide:closeModalSlide
		}

		return m_publicObj;
	}
})(jQuery);

































