/*
	name : globalHeader
	file : jquery.globalheader.js
	author : Ali Hasan
	(c) Copyright 2009 AOL LLC
	$LastChangedDate: 2009-11-06 09:10:40 -0500 (Fri, 06 Nov 2009) $
	$Rev: 53379 $
	///////////////////////////		
	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,
				moreLinks : [],
				morePromoCount : 2,
				moreText: 'You might also like:',
				moreAnd: 'and',
				moreMore: 'More',
				moreTextHeadline: 'More Sites You Might Like', 
				uiHat : '#GH_hat',
				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
			},

			/* local copy of function overrides */		
			fn = options.fn || {},

			/* 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.$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(); }
					core.buildMoreLinks();
					core.buildDropDowns();

					ui.$c.bind('setActiveTab', core.setActiveTab);
					ui.$c.bind('setAuthState', core.buildAuth);
					/**
					* 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', core.buildSearch).attr('autocomplete','off');
					ui.$searchSubmit.bind('mouseover.GH', core.buildSearch);
				},
				
				/** 
				*	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]) {
						options.search.params.ghostText = ui.$searchInput.attr('value'); 
						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, 
							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_more_A wpImgs').text(options.moreMore).bind('mouseover.GH', core.showMoreLinks)));
						}
						hatLi.appendTo(ui.hatLinks);
					}
				},
				
				/* 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('mouseover.GHTEMP',core.kill);
						ui.$hatMoreLink.bind('mouseover.GHTEMP',core.preventKill);
						ui.$hatMoreList.bind('mouseover.GHTEMP',core.preventKill);
						ui.$hatMoreList.fadeIn('fast');
					}
					return false;
				},
				
				preventKill : function(e) {
					e.stopPropagation();
				},
				
				kill : function(e) {
					ui.$d.unbind('mouseover.GHTEMP');
					ui.$hatMoreLink.unbind('mouseover.GHTEMP');
					ui.$hatMoreList.unbind('mouseover.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			
		
		/* apply any overrides to core */
		$.extend( true, core, fn);
			
		/* extend default options to include user's custom options */
		$.extend( true, options, defaultOptions, customOptions );	
	
		/* begin */
		core.init($this);
		
		/* jQuery default behavior, return jQuery object */
		return $this;
	};
})(jQuery);