/**
 * This jquery plugin was written for jquery version 1.3.2.
 * The goal of this plugin is to allow fot a very diverse
 * html footing for marquees and also bring content in via
 * json to fix the problem of long page load times. The plugin
 * is initiated on a div and a class within the div which is a single
 * marquee item. The code then looks at the parameters passed in
 * makes a json call to the url and duplicates the html for the number
 * of json responses returned. It then puts the data from the json
 * request into each div and instantiates the marquee action. There are also listeners
 * for the maruqee navigation which when clicked halt all transitions preminantly.
 * There is listeners for hover actions as well which pause the marquee scrolling,
 * once the hoover is removed the transitions resume where they left off with a 
 * refreshed countdown.
 * 
 */

(function($){

	//global variables for the function
	//self holds the object that the marquee was instantiated upon
	var self;
	//slide is the current slide the marquee is on
	var slide;
	//marquees is an object of all the marquee slides
	var marquees;
	//int is the interval for the transitions
	var interval;
	//holds wether of not the user is hovered over a slide
	var hover = false;
	//holds bool value if the script should start the interval again this
	//is an important value because it eliminates the problem of doing a 
	//hover while a transition is occuring
	var intWait = false;
	//holds the merged config's defaults with what is passed in
	var globalOptions;
	//variable to let us know if we are done with the number of slides where looping through
	//if continuous is set this should always be false.
	var transitionComplete = false;

	var pathName = window.location.pathname;

	var urlPaths = pathName.split("/");

	var region = urlPaths[1];
	var language = urlPaths[2];

//    var of = array('en':'of');
    var of = {'en':'of', 'fr':'sur','de':'von','da':'af','nl':'van', 'es':'de', 'sv':'av', 'it':'di', 'zh':'of', 'no':'av', 'fi':'of', 'ko':'of', 'ja':'of'};
//    of['en']='of';

	//instantiate a marquee object to hold the configuration information
	$.marquee = {
		version: '1.0',
		
		//sets the default config values, all of these can be passed into the
		//plugin and be overidden
		conf: {
			// basics
			effect: 'fade',
			speed: 500,	
			totalMarquees: 4,
			
			json: {
				offset: 1,
				url: 'json.php',
				parameters:{
					library: 'bontrager',
					section: 'marquee'
				}
			},
			nav: false,
			navContainingDiv: 'marquee_preview',
			counter: true,
			counterDiv: 'marquee_counter',
			countinuous: true,
			finalMarquee: 5,
			gaAcountId: 1,
			gaToggle: false,
			marqueesToCreate: 0,
			headerClass: 'header',
			descriptionClass: 'description',
			linkTextClass: 'link_text',
			linkClass: 'button',
			imageClass: 'marquee_image',
			slideTime: 5000,
			transitionSpeed: 500,
			imagePreview: false,
			imagePreviewDiv: 'marquee_preview',
			imagePreviewClickDiv: 'grid',
			imagePreviewOverlayDiv: 'cover',
			slideCounter: true,
			slideCounterDiv: 'marquee_counter',
			nextprev: true,
			nextClass: 'next',
			prevClass: 'prev'
			
		} 
	};
	
	$.fn.marquee = function(options) {
		
		//sets the self variable to what the plugin was instantiated on
		self = $(this);  
		
		//gets the number of marquees that already exist to
		//pass as offset for json request
		var offset = $(this).length;

		//gets the default configuration variables
		var globals = $.extend({}, $.marquee.conf);
		
		//gets the configs passed in and merges them with defaults
		options = $.extend(globals, options);
		
		//sets the global variable for holding the options to the merged option values
		globalOptions = options;
		
		//checks to make sure that we have configuration variables
		if( options != null ){
			
			//check to see if we are doing json request
			if( options.json != null && options.json.url != null ){
				
				//check to see if we are using nav items
				if( options.nav == true ){
					
					//set the listeners on the marque nav items
					navListeners();
				}
				
				//creates the marquees from the existing html
				appendMarquees();

				//run the json request to get the new marquees content
				marqueeJSON();
				
			}else{
				
				//config variables needed for json request are not set
				alert('required json parameters not passed in');
				
			}
			
			
		}else{
			
			//The configuration variable creation failed
			alert('You did not pass the required params to marquee');
			
		}
	};
	
	/**
	 * This function runs a json request to get the data for the
	 * new marquees. 
	 */
	function marqueeJSON( ){
		
		//this variable holds the string of parameters pased into the function
		//to be sent with the json request
		var jsonParam = '';
		
		//counter to see if we are on the last slide
		var count = 0;
		
		//loops through the json parameters that need to be sent with the request
		$.each(globalOptions.json.parameters, function(key, value){
			
			
			if( count == 0 ){
				
				jsonParam = jsonParam + $.trim(key) + '='+ $.trim(value);
				
			}else{
				
				jsonParam = jsonParam + '&' + $.trim(key) + '='+ $.trim(value);
				
			}
			
			count++;
			
		});
		
		//add the total marquees and offset as params to be used by sql
		jsonParam = jsonParam + '&offset=' + globalOptions.json.offset;
		jsonParam = jsonParam + '&total=' + globalOptions.totalMarquees;
		
		//calls a json get request for the specefied url and the param string we just made
		$.getJSON(globalOptions.json.url, jsonParam,
			function(marqueeData){
				
				//sets the marquees to all of the matching items
				marquees = self.parent().children();
				//sets the to start at the offset
				var count = globalOptions.json.offset;
				//holds the link html to make sure we have a link around the
				//header and the marquee image
				var marqueeLink;
				
				//fix the carrage return by appending the a in the div
				var currentPrev = $('#'+globalOptions.imagePreviewDiv).html();
			
				$('#'+globalOptions.imagePreviewDiv).empty();
				
				$(currentPrev).appendTo('#'+globalOptions.imagePreviewDiv);
				
				//loops through the marquee data returned by the json request
				$.each(marqueeData, function(key, marqueeItem){
					
					//checks to see if the link passed back has a value
					if( marqueeItem.link != '' || marqueeItem.link != undefined ){
					
						marqueeLink = marqueeItem.link;
						
					}else{
					
						marqueeLink = '<a href="#"></a>';
						
					}
					
					//sets the marquees id to the article alias
					$(marquees[count]).attr('id', marqueeItem.alias);
					
					//empties the header container
					$('#'+marqueeItem.alias+' .'+globalOptions.headerClass).empty();
					//puts the header value in the header contianer
					$('#'+marqueeItem.alias+' .'+globalOptions.headerClass).html( marqueeItem.header );
					
					//empties the description container
					$('#'+marqueeItem.alias+' .'+globalOptions.descriptionClass).empty();
					//puts the description value in the description container
					$('#'+marqueeItem.alias+' .'+globalOptions.descriptionClass).html( marqueeItem.description );
					
					//empties the link text container
					$('#'+marqueeItem.alias+' .'+globalOptions.linkClass).empty();
					
					//puts the link text value into the link text container
					$('#'+marqueeItem.alias+' .'+globalOptions.linkClass).html( marqueeLink );
					
					//gets an object for the existing marquee image
					var image = $('#'+marqueeItem.alias+' .'+globalOptions.imageClass+' img');
					
					//sets the images src to the value from json
					image.attr('src', marqueeItem.imagePath);
					
					//empties the image container
					$('#'+marqueeItem.alias+' .'+globalOptions.imageClass).empty();
					//adds the link to the image container
					//$('#'+marqueeItem.alias+' .'+globalOptions.imageClass).html( marqueeLink + '</a>' );
					//adds the image into the link
					$('#'+marqueeItem.alias+' .'+globalOptions.imageClass).html(marqueeItem.imagePath);
					
					//adds the classes for the marquee text items to its container
					$('#'+marqueeItem.alias).addClass( marqueeItem.styleClass );
					
					//do the logic for the thumb images if we are using them
					if( globalOptions.imagePreview == true ){
						
						newcount = parseFloat(count)+1;
						
						$('<a class="marqueeThumb clearfix" rel="'+newcount+'"><img src="'+marqueeItem.imageThumbPath+'" /></a>').appendTo('#'+globalOptions.imagePreviewDiv);
					}
					
					count++;
					
				});
				
				//set what the total number of marquees actually is
				globalOptions.totalMarquees = count;
                
                //update the slide counter
                updateSlideCounter( 1 );
				
				var marquee_count = 1;
				
				$('#marquee #container .items').each(function(n){
				    
				    if( count < marquee_count ){
				        
				        $(this).remove();
				    }  
				    
				    marquee_count++;      
				});
                
                navListeners();
                
                if( count > 1 ){
                
    				//start the marquee transitions
    				startTransitions();
    				
    				//add the marquee hoover listeners
    				hoverListeners();
				}
				
				//check to see if we are using the marquee thumb
				if( globalOptions.imagePreview == true ){
					
					marqueeThumbListeners();
				}
				if( globalOptions.nextprev == true ){
					prevNextListeners();
				}
			}
		);
	};

	/**
	 * This function copies the existing marquee html so we can fill it with what we get from json.
	 */
	function appendMarquees(){
		
		//holds the last marquee in the container
		var lastMarq;
		//holds the cloned marquee's information
		var marq;
		
		//loops through the marquees the plugin was initialized on
		//expecting to use the last one in the list
		$(self).each(function(n){
			
			lastMarq = self[n];
			marq = $(lastMarq).clone();
			
		});
		
		//loop through adding marquees until the total marquees is reached
		for( x=1; x<=globalOptions.totalMarquees - globalOptions.json.offset; x++){
			
			//make sure there is something in the cloned marquee
			if( marq != null ){
				
				//make sure that when its added it does not show up
				$(marq).css('display', 'none');
				//remove the id so there are not multiple items with same id
				$(marq).attr('id', '');
				//remove any classes it should only have one
				$(marq).attr('class', '');
				//set the class that identifies it as a marquee
				$(marq).attr('class', 'marquee');
				//appends a clone to the parent container
				$(marq).clone().appendTo(self.parent());
				
			}
		}
	}
	
	/**
	 * This function starts the marquee transitions.
	 */
	function startTransitions(){
		
		//refreshes the marquees to make sure we have any that may have been added
		marquees = self.parent().children();
		
		//sets the current slide to 0
		slide = 1;
		
		//starts the transition for the amount of time passed in
		interval = setInterval(runTransition, globalOptions.slideTime);
		
	}
	
	/**
	 * This function stops the current transition cylcle
	 */
	function pauseTransitions(){
		
		//removes the current interval
		clearInterval(interval);
		
	}
	
	/**
	 * This function starts a new interval for the full slide time
	 */
	function resumeTransitions(){

		interval = setInterval(runTransition, globalOptions.slideTime);
		
	}
	
	/**
	 * This function handles doing the transtion from the current marquee
	 * to the next one in the list. It stops the current interval allows for
	 * the transitions to complete then starts a new interval. This has to be
	 * done otherwise you would not get the full time expected on each slide 
	 * because the transition time would take the time away fromt he slides
	 * show time.
	 * 
	 */
	function runTransition(){
		
		//clear the existing interval
		clearInterval(interval);

		//starts a fadeout on the current slide
		$(marquees[slide-1]).fadeOut(globalOptions.transitionSpeed, function() {
			
			//check to see if it is the last slide
			if( slide == globalOptions.totalMarquees ){
				
					//its the last slide so we will be going back to the first one
					navActive( 0 );
					
					//fades in the first marquee
					$(marquees[0]).fadeIn(globalOptions.transitionSpeed, function() {
						
						//checks to see if we should wait to initalize the interval
						//we do this incase the user hoverd while the transition started
						if( intWait == false ){
							
							if( globalOptions.countinuous == true ){
							
								//start the transition interval
								interval = setInterval(runTransition, globalOptions.slideTime);
								
							}else{
								
								transitionComplete = true;
								
								unbindHoverListeners();
								
							}
						
						}
				    });
					
					//set the current slide to be the first one
					slide = 1;
					
					//update the count if we are using that functionality
					if( globalOptions.slideCounter == true ){
						updateSlideCounter(slide);
					}
			}else{
				
				//sets the new actve navigation item to the slide we are transitioning to
				navActive( slide );
				
				//starts to fade in the next slide
				$(marquees[slide]).fadeIn(globalOptions.transitionSpeed, function() {
					
					//checks to see if we should wait to initalize the interval;
					//we do this incase the user hoverd while the transition started
					if( intWait == false ){
						
						//start the transition interval
						interval = setInterval(runTransition, globalOptions.slideTime);
						
					}
			    });
				
				//sets the current slide to the one we just transitioned to
				slide = slide+1;
				
				//update the count if we are using that functionality
				if( globalOptions.slideCounter == true ){
					updateSlideCounter(slide);
				}
			}
		});
		
	}
	
	/**
	 * This function controls setting the nav items to active/inactive.
	 * It searches the nav itmes in the nav container  for the one with
	 * the class active and removes it, and adds the class active to the 
	 * slide passed in.
	 * 
	 */
	function navActive( activeSlide ){
		
		//gets an array of all of the children
		var navChildren = $('#'+globalOptions.navContainingDiv).children();
		
		//gets the current nav item with class active
		var activeChild = $('#'+globalOptions.navContainingDiv).children(['class=active']);
		
		//removes the active class from the current nav item
		$(activeChild).removeClass('active');

		//adds the active class to the new active slide
		$(navChildren[activeSlide]).addClass('active');
		
	}
	
	/**
	 * This function handles initialising the click listeners
	 * for the nav items. It has built in controlls for fixing
	 * the problem where a user can click very fast and back up the
	 * transitions and break the marquee.
	 */
	function navListeners(){
	
		//loop though each of the items in the nav container
		$('#'+globalOptions.navContainingDiv).children().each(function(){
			
			//adds a click listener to each of the nav items
			$(this).click(function(){
				
				//stops the current interval
				clearInterval(interval);

				//remove the hover listeners no longer doing transistions
				unbindHoverListeners();
				
				//unbinds the nav listeners
				unbindNavListeners();
				
				//gets the postition from the nav items rel tag
				var position = $(this).attr('rel');
				
				//sets the active item to the clicked nav item
				navActive(position-1);
			    
				//handles transitioning to the slide that was clicked
				$(marquees[slide-1]).fadeOut(globalOptions.transitionSpeed, function() {
				    
					$(marquees[position-1]).fadeIn(globalOptions.transitionSpeed, function() {
						
						//set the current slide to the new position
						slide = position;
						
						//adds the click listeners back in
						navListeners();
						
					});
				});
			});
		});
	}
	
	/**
	 * This function removes the click listeners from the nav items.
	 */
	function unbindNavListeners(){
		
		//goes through each of the nav items in the nav div container
		$('.'+globalOptions.navContainingDiv).children().each(function(){
			
			//unbinds the click listener
			$(this).unbind('click');
			
		});
	}
	
	/**
	 * This function unbinds the hover listeners.
	 */
	function unbindHoverListeners(){
		
		self.parent().children().each(function(n){
			
			//have to use mouseenter mouseleave for some reason
			//unbind(hover) does not work.
			$(this).unbind('mouseenter mouseleave')
			
			$(this).children().each(function(n){
				
				$(this).unbind('mouseenter mouseleave')
				
			});
			
		});
		
	}
	
	/**
	 * This function adds hover listeners to the marquee container
	 * and the divs inside the marquee container that have a presence
	 * over the marquee. Because of those items we have to use
	 * variables with a bool value to make sure that if the user
	 * goes over an item on top of the marquee container the unhover
	 * action for the main marquee container does not fire.
	 * 
	 */
	function hoverListeners(){
		
		//loop through the marquees
		self.parent().children().each(function(n){
			
			//add a hover listener to the marquee
			$(this).hover(function(){
				
				//set that we are hovered to true
				hover = true;
				
				//pauses transitions from hapeneing because the user is hovered
				pauseTransitions();
				
				//sets the interval wait to true
				intWait = true;
				
			},
			function(){
				
				//makes sure that a hover was initialized
				if( hover == true ){
					
					//we no longer need to wait
					intWait = false;
					
					//resume the transitions
					resumeTransitions();
					
				}
			});
			$(this).children().each(function(n){
				
				//makes sure the the child item has the class details
				if( $(this).hasClass('details') ){
				
					//add the hover listener to the item
					$(this).hover(function(){
						
						//make sure transitions are paused because user is hovered
						pauseTransitions();
						
					});
				}
			});
		});
	}
	
	/**
	 * This function creates the listners for the marquee thumnail
	 * previewer. When the preview is active all transitions are paused
	 * along with the marquee hover listeners. We also show a cover over the
	 * marquee so it losses focus, and the useres attention is drawn to the marquee
	 * preview pane.
	 * 
	 * @return
	 */
	function marqueeThumbListeners(){
		
		//this listens for clicking to show the thumbnail previewer
		$('#'+globalOptions.imagePreviewClickDiv).live('click', function(){
			
			//this removes the hover listners for transitions
			unbindHoverListeners();
			
			//pause the transitions while we are viewing the thumnail
			pauseTransitions();
			
			//show the opacity div over the marquee
			//$('#'+globalOptions.imagePreviewOverlayDiv).show();
			$('#'+globalOptions.imagePreviewOverlayDiv).fadeIn(300);
			
			//fade in the thumnail preview div
			//$('#'+globalOptions.imagePreviewDiv).slideToggle(300);

			$('#'+globalOptions.imagePreviewDiv).show();			
			$('#'+globalOptions.imagePreviewDiv).animate({bottom: '50',opacity: 1},300);

			
			//set the grid to be clicked state
			$(this).removeClass( 'normal' );
			$(this).addClass( 'clicked' );
		});
		
		//this listnes for the click to close the thumnail previewer
		$( '.clicked' ).live('click', function(){
			
			hideThumbViewer();
            
			/*hide the thumnail preview div*/
			//$('#'+globalOptions.imagePreviewDiv).slideToggle(100);
            //$('#'+globalOptions.imagePreviewOverlayDiv).fadeOut(100);
			
           
            
            $('#'+globalOptions.imagePreviewDiv).animate({bottom: '0',opacity: 0},100,
				function(){
					//hide the opacity div
					$('#'+globalOptions.imagePreviewOverlayDiv).fadeOut(100);
			});
			
			
			
			//switch the state of the grid view to noraml
			$(this).removeClass( 'clicked' );
			$(this).addClass( 'normal' );

			//only resume transitions if they are not complete
			if( transitionComplete == false ){
				
				//turn the hover listeners on again
				hoverListeners();
				
				//resume the transitions
				resumeTransitions();
			}
		});
		
		//this is the listner for clicking a thumbnail item in the thumnail preview
		$(".marqueeThumb").live('click', function(){
			
			//once we click one no more transitioning regardless of where we were
			killTransistions();
			
			//go to the slide specified in the rel tag of the clicked item
			goToSlide( $(this).attr('rel') );
			
			//track the preview slide click
			_gaq.push(['_trackEvent', 'Marquee Jump To Slide', 'marquee-'+$(this).attr('rel')+'-'+region+'-'+language, 'Marquee']);

			//hide the thumnail preview viewer
			hideThumbViewer();
		});
	}
		
	function updateSlideCounter( slideCount ){
//        console.info(of[language]);
		$('#'+globalOptions.slideCounterDiv+' p').replaceWith('<p>'+slideCount+' '+of[language]+' '+globalOptions.totalMarquees);
	}
	
	/**
	 * This function handles jumping to a slide. The slide you want to jump to should be set
	 * in the rel tag of the item you are clicking.
	 * 
	 * @param slideToGoTo
	 * @return
	 */
	function goToSlide( slideToGoTo ){
		
		//see if we are on the slide we are going to
		if( slide != slideToGoTo){
			
			//handles transitioning to the slide that was clicked
			$(marquees[slide-1]).fadeOut(globalOptions.transitionSpeed, function() {
				$(marquees[slideToGoTo-1]).fadeIn(globalOptions.transitionSpeed, function() {
					
					//set the current slide to the new position
					slide = parseFloat(slideToGoTo);
					
					//only update the slide counter if we are using it
					if( globalOptions.slideCounter == true ){
						
						//update the slide counter
						updateSlideCounter(slide);
					}
					
				});
			});
		}
	}
	
	/**
	 * This function handles hiding the thumnail preview viewer
	 * and returning the marquees to there normal state.
	 * 
	 * @return
	 */
	function hideThumbViewer(){
		
		//hide the opacity div
		$('#'+globalOptions.imagePreviewOverlayDiv).hide();
		
		//set the grid back to the normal state
		$('#'+globalOptions.imagePreviewClickDiv).removeClass( 'clicked' );
		$('#'+globalOptions.imagePreviewClickDiv).addClass( 'normal' );
		
		//fade out the thumbnail preview div
			//$('#'+globalOptions.imagePreviewDiv).slideToggle(100);
            
			//$('#'+globalOptions.imagePreviewOverlayDiv).fadeOut(100);
			
            
			$('#'+globalOptions.imagePreviewDiv).animate({bottom: '0',opacity: 0},100, function(){
					
				//hide the opacity div
					
				$('#'+globalOptions.imagePreviewOverlayDiv).fadeOut(100);
			
			});

	}
	
	/**
	 * This function is for the next/prev slide buttons. There is a class to trigger
	 * the next and prev slide, the class can be defined on instantiation of the
	 * plugin.
	 * @return
	 */
	function prevNextListeners(){
		
		//listener for the next listener
		$("."+globalOptions.nextClass).live('click', function(){
			
			//this kills of the the transitions and listners for them
			killTransistions();
			
			//if the next slide is more than the total slides go back to the first one
			if( slide+1 > globalOptions.totalMarquees ){
				
				//jumping to the first slide
				goToSlide(1);
			}else{
				
				//jump to the next slide
				goToSlide( slide + 1 );
			}
			
		});
		
		//this is the listner for the prev slide button
		$("."+globalOptions.prevClass).live('click', function(){
			
			//this kills of the the transitions and listners for them
			killTransistions();
			
			//if the previous slide is 0 or less go to the final marquee
			if( slide-1 <= 0 ){
				
				//jump to the last marquee in the list
				goToSlide(globalOptions.totalMarquees );
			}else{
				
				//go to the previous slide
				goToSlide(slide - 1 );
			}
			
		});
	}
	
	/**
	 * This function handles killing all of the transitions and the listeners that stop/start
	 * transitions. All functions should now be recognising the global var for if transitions are
	 * done so they do not start unexpectidly.
	 * 
	 * @return
	 */
	function killTransistions(){
		clearInterval(interval);
		
		//remove the hover listeners no longer doing transistions
		unbindHoverListeners();
		
		//unbinds the nav listeners
		unbindNavListeners();
		
		//global variable so that we know not to start transitions
		transitionComplete = true;
	}
		
	
})(jQuery);

