/*
	name : globalHeader
	file : jquery.globalheader.js
	owner : Dave Artz
	(c) Copyright 2009 AOL LLC
	$LastChangedDate: 2010-01-14 11:24:00 -0500 (Thu, 14 Jan 2010) $
	$Rev: 134091 $
	///////////////////////////		
	dependencies : jQuery 1.3.2, jquery.globalsearchbox.js
	///////////////////////////
	description: 
	Build global header.
*/

(function($) {
$.fn.globalHeader = function( customOptions ) {
	/** 
	*	default options 
	*		These can be overridden by passing in an updates customOptions object
	*		
	*		==== Using options ====
	*		Example to change the moreText below: 
	*			jQuery('#myElemId').globalHeader( { moreText : "I can change this value:" } );
	*		
	*
	*       ==== Override Functions (if needed) ====	
	*		You can also override the functions in the core Object. 
	*		To do this, just add your method to the fn Object. 
	*		An example to change the buildAuth method:
	*		
	*		jQuery('#myElemId').globalHeader( { fn : { buildAuth : function(){ 
	*					alert('I am changing the buildAuth!');
	*					// ... do stuff
	*				} 
	*			} 
	*		});
	*		
	*		
	*		==== Showing user as logged in (auth) ====
	*		To show the header in a signed in state, alter the value of the auth Object.
	*		A simple example:
	*		jQuery('#myElemId').globalHeader( { auth : { authenticated : true } } );
	*	
	*/
	var defaultOptions = {
			activeTab : null,
			dualSearchBox : true,
			moreLinks : [],
			morePromoCount : 2,
			moreText: 'You might also like:',
			moreAnd: 'and',
			moreMore: 'More',
			moreTextHeadline: 'More Sites You Might Like', 
			webBaseUrl : 'http://search.aol.com/aol/',
			webInv : 'hdt-spinner',
			uiHat : '#GH_hat',
			uiWebForm : '#web-search-form',
			uiWebInput : '#web-search-input',
			uiWebButton : '#web-search-button',
			uiHatLinks : '#GH_hat_links',
			uiHatTools : '#GH_hat_tools',
			uiNavLi : 'li.GH_nav_LI',
			uiNavADd : '.GH_nav_dd_A',
			auth : {
				doAuth: false,
				authenticated: false,
				authState: null,
				unauthState: null
			}, // search params
			search : {
				uiSearch: '#GH_search',
				params : {}
			}, // options passed on to globalSearchBox
			fn : {} // functions to be overridden
		},

		/* merged options */
		options = {},
		
		/** 
		*	target jQuery collection 
		*		Cache 'this' into the variable $this for later reference.
		*/
		$this = this,
	
		/* ui model*/
		ui = {},
	
		/* local data store */
		local = {
			activeTab : null,
			moreLinksBuilt : false
		},

		/* private functions, can be overriden, cannot be called directly */
		core = {
			/** 
			*	This method is automatically fired as soon as the plugin is called 
			*		It *CAN* be overriden following the above steps.
			*/			
			init : function(container) {
				ui.$d = $(document);
				ui.$c = $(container);
				ui.hat = $(options.uiHat)[0];	
				ui.hatLinks = $(options.uiHatLinks)[0];
				ui.$hatTools = $(options.uiHatTools);
				ui.$webSearchForm = $(options.uiWebForm);
				ui.$webSearchInput = $(options.uiWebInput);
				ui.$webSearchButton = $(options.uiWebButton);
				ui.$search = $(options.search.uiSearch);
				ui.$searchInput = ui.$search.find('input:first');
				ui.$searchSubmit = ui.$search.find('input:last');
				ui.$navLi = ui.$c.find(options.uiNavLi);
				ui.$navADd = ui.$c.find(options.uiNavADd);
				
				core.setActiveTab(null, options.activeTab);
				if (options.auth.doAuth) { core.buildAuth(); }
				if (options.dualSearchBox) { activateDualSearch(); }
				core.buildMoreLinks();
				core.buildDropDowns();

				ui.$c.bind('setActiveTab', function(e,data) { core.setActiveTab(e,data); });
				ui.$c.bind('setAuthState', function(e,data) { core.buildAuth(e,data); });
				
				// focus on input field on init
				if (options.search.params.initFocus !== undefined && options.search.params.initFocus) {
					/**
					 * This immediately builds the autocomplete box.
					 */
					ui.$search.globalSearchBox(options.search.params);
				}
				else {
					/**
					* This event offloads the element building of the autocomplete box to user action
					*  This technique helps speed up the render of the header. It doesn't penalize users who aren't searching.
					*/					
					ui.$searchInput.bind('focus.GH', function(e) { core.buildSearch(e); }).attr('autocomplete','off');
					ui.$searchSubmit.bind('mouseover.GH', function(e) { core.buildSearch(e); });
					
					// preset search text
					if (options.search.params.searchText !== undefined && options.search.params.searchText !== '') {
						ui.$searchInput.val(options.search.params.searchText);
					}
				}		
			},
			
			/** 
			*	helper function to return private variables to extended functions 
			*		This method let's the code be minified, but still work with function overrides.
			*/
			getVars : function() {
				return {
					options : options,
					ui : ui,
					local : local							
				};					
			},
			
			/** 
			*	initialize global search box 
			*		This function has a dependency on an external file. jquery.globalSearchBox.js
			*		The globalSearchBox is for autocomplete. The autocomplete is not auto-magic. You will need to set up a channel dictionary
			*/		
			buildSearch : function(e) {
				ui.$searchInput.unbind('focus.GH');
				ui.$searchSubmit.unbind('mouseover.GH');
				if (e.target === ui.$searchInput[0]) {
					ui.$searchInput.addClass('GH_search_active').attr('value','');	
				}								
				ui.$search.globalSearchBox(options.search.params);
			},				
			
			/* build auth and unauth states 
			 * user can sent auth params on globalheader init or trigger a 'setAuthState' event with necessary auth params
			 * 
			 * eg. $("#GH_").trigger('setAuthState',{authenticated:false})
			 */
			buildAuth : function(e, authObject) {
				if (authObject !== undefined) {
					$.extend(true, options.auth, authObject);
				} 

				ui.$hatTools.empty().append((options.auth.authenticated) ? options.auth.authState : options.auth.unauthState);
			},

			/** 
			*	build more links drop down 
			*		This is not the 'nav' items drop down, it's for the 'other sites' links in the top hat
			*/
			buildMoreLinks : function() {
				
				var ml = options.moreLinks, 
					i = 0, 
					l = ml.length;
				
				if (l >= options.morePromoCount) {
					
					// Build 'More' Line
					var $hatMore = $('#GH_hat_more'),
						hatMore, 
						hatLi;

					if (!$hatMore.length) {
						
							hatLi = $('<li />').addClass('GH_hat_LI').append(
									hatMore = $('<ul />').attr('id','GH_hat_more').addClass('GH_hat_UL').append(
											$('<li />').addClass('GH_hat_LI').text(options.moreText + '\xa0 ')));
					
						for (; i < options.morePromoCount; i++) { 
							hatMore.append(
								$('<li />').addClass('GH_hat_LI').append(
									$('<a />').attr({ href : ml[i][1], target : (ml[i][2] !== undefined) ? ml[i][2] : '_self' }).addClass('GH_hat_A GH_hat_more_A').text(ml[i][0])).append((i < options.morePromoCount-1) ? ',\xa0' : ''));
						}
						
						// Build 'More' Call To Action
						if (l > options.morePromoCount) {
							hatMore.append(
								ui.$hatLIMore = $('<li />').addClass('GH_hat_LI GH_hat_LI_more').append('\xa0'+options.moreAnd+'\xa0').append(
									ui.$hatMoreLink = $('<a />').attr({ id : 'GH_hat_more_link', href : '#' }).addClass('GH_hat_A GH_hat_more_A').text(options.moreMore)));
						}
						hatLi.appendTo(ui.hatLinks);
					
					} else {
						
						ui.$hatMoreLink = $('#GH_hat_more_link');
						ui.$hatLIMore = ui.$hatMoreLink.parent();
						
					}
					
					ui.$hatMoreLink.bind('mouseover.GH', function(e) { core.showMoreLinks(e); });
				}
			},			
			
			/* build 'More' box 
			 * fade in/out more links drop-down when clicked */
			showMoreLinks : function(e) {
				e.preventDefault();
								
				if (local.moreLinksBuilt === false) {
					var ml = options.moreLinks.slice(options.morePromoCount),
						i = 0, l = ml.length,
						bp = Math.ceil(l/3), bp2 = Math.ceil(l/3*2),
						hatMoreList_1, hatMoreList_2, hatMoreList_3,hatMoreListLi;
					
					ui.$hatMoreList = $('<div />').attr('id','GH_more_list').append(
						$('<b />').attr('id','GH_more_list_lab').text(options.moreTextHeadline)).append(
						hatMoreList_1 = $('<ul />').addClass('GH_more_list_UL')).append(
						hatMoreList_2 = $('<ul />').addClass('GH_more_list_UL')).append(
						hatMoreList_3 = $('<ul />').addClass('GH_more_list_UL'));

					for (; i < l; i++) {
						hatMoreListLi = $('<li />').append(
							$('<a />').attr({ href : ml[i][1], target : (ml[i][2] !== undefined) ? ml[i][2] : '_self' }).text(ml[i][0]));
						if (i < bp) { hatMoreListLi.appendTo(hatMoreList_1); }
						else if (i < bp2) { hatMoreListLi.appendTo(hatMoreList_2); }
						else { hatMoreListLi.appendTo(hatMoreList_3); }
					}
					
					ui.$hatMoreList.css('left',ui.$hatLIMore.offset().left-ui.$c.offset().left+14).appendTo(ui.hat);
					local.moreLinksBuilt = true;	
				}
				
				if (ui.$hatMoreList.css('display') === 'none') {
					ui.$d.bind('mousemove.GHTEMP', function(e) { core.kill(e); });
					ui.$hatMoreList.fadeIn('fast');
					
				}
			},
			
			kill : function(e) {
				var $target = $(e.target);
				
				if ($target.closest('#GH_hat_more_link').length === 0 && $target.closest('#GH_more_list').length === 0) {
					ui.$d.unbind('mousemove.GHTEMP');
					ui.$hatMoreList.fadeOut('fast');
				}
			},			
			
			/* set a navigation tab as active */
			setActiveTab : function(e, activeTab) {				
				if(activeTab !== undefined && activeTab !== null) {
					if (local.activeTab !== null) { 
						local.activeTab.removeAttr('id'); 
						// If menu item has dropdowns
						if(local.activeTab.hasClass('GH_nav_list')) { 
							$('#GH_nav_act_B').removeAttr('id'); 
						} 
					}
					local.activeTab = ui.$navLi.eq(activeTab).attr('id', 'GH_nav_act');
					local.activeTab.children().eq(0).css('clear','both');
					// If menu item has dropdowns
					if(local.activeTab.hasClass('GH_nav_list')) {  
						local.activeTab.children().eq(0).wrapInner('<b id="GH_nav_act_B"></b>'); 
					}
				}
			},
			
			/* attach drop down functionality to navigation tab */
			buildDropDowns : function() {
				ui.$navLi.each(function() {
					var li = $(this);
					if(li.hasClass('GH_nav_list')){
						li.mouseover(function(){
							if(li.showtimer){
								clearInterval(li.showtimer);
								li.showtimer = null;
							}
							li.addClass('GH_nav_list_open').find('ul').fadeIn('fast');
						}).mouseout(function(){
							li.showtimer=setTimeout(function(){
								if(li.showtimer){
									clearInterval(li.showtimer);
									li.showtimer=null;
								}
								li.removeClass('GH_nav_list_open').find('ul').fadeOut('fast');
							},250);
						});
					}
				});	
			}
		};//end core	
		
		function activateDualSearch () {			
			ui.$webSearchInput.bind('focus', function(){ 
				if($(this).val() == 'Search the Web') {
					$(this).val(''); 
					$(this).css("color","#2e2e2e");
				};
			});
			ui.$webSearchInput.bind('blur', function () {			
				if($(this).val() == '') {
					$(this).val('Search the Web') ;
					$(this).css("color","#A6A6A6");
				};
			});
			ui.$webSearchInput.bind('keypress', function(event){
				var keyCode = event.charCode || event.keyCode;				
				if(keyCode && keyCode == 13) {
  					event.preventDefault();
  					submitWebSearch();
				};				
			});	
			ui.$webSearchButton.bind('click', submitWebSearch);		
		};
			
		function submitWebSearch (e) {
			var webQuery = $(options.uiWebInput).val();
			if(webQuery == '' || webQuery == 'Search the Web') {
				var searchUrl = options.webBaseUrl+'webhome?s_it='+options.webInv;
			} else {
				webQuery = webQuery.replace(/^\s+|\s+$/g,"").replace( /\+/, " ");
				var searchUrl = options.webBaseUrl+'search?q='+webQuery+'&s_it='+options.webInv; 
			}							
	    	window.location = searchUrl;				
			return false;							
		};	

		/* extend default options to include user's custom options */
		$.extend( true, options, defaultOptions, customOptions );	
				
		/* apply any overrides to core */
		$.extend( true, core, options.fn );
	
		/* begin */
		core.init($this);
		
		/* jQuery default behavior, return jQuery object */
		return $this;
	};
})(jQuery);