var SSO = SSO ? SSO : {};

SSO.csrf = {
	cont: {},
	used: false,
	CSRFQueueObj: {
		running: false,
		callbacks: []
	},

	init: function() {
		SSO.csrf.setCSRFObj();
	},

	setCSRFObj: function() {
		var header = $("meta[name='_csrf_header']").attr("content");
		if(header)
			SSO.csrf.cont[header] = $("meta[name='_csrf']").attr("content");
	},

	getCSRFObj: function() {
		return SSO.csrf.cont;
	}
};

SSO.utility = {
	
	ie8shiv: function () {
		document.createElement('section');
	},
	
	getDomain: function () {
		var hostname = window.location.hostname,
			hostParts = hostname.split('.'),
			numParts = hostParts.length;

		return numParts > 1 ? hostParts[numParts - 2] + '.' + hostParts[numParts - 1] : hostname;
	},

	getCookie: function (cookieName) {
		var i = 0,
			cookies = document.cookie.split(";"),
			length = cookies.length,
			trimRegex = /^\s+|\s+$/g,
			cookiePair;

		for (; i < length; i++) {
			cookiePair = cookies[i].split('=');

			if (cookiePair[0].replace(trimRegex, '') === cookieName) return unescape(cookiePair[1]);
		}
	},

	setCookie: function (cookieName, cookieValue, days) {
		if (!(cookieName && cookieValue)) return;

		var domain = '; domain=' + this.getDomain(),
			path = '; path=/',
			expires = '',
			today;

		if (days) {
			today = new Date();
			today.setTime(today.getTime() + (days * 24 * 60 * 60 * 1000));
			expires = "; expires=" + today.toGMTString();
		}

		document.cookie = cookieName + "=" + cookieValue + expires + path + domain;
	},
	
	deleteCookie: function(cookieName) {
		if(!cookieName) return;
		
		document.cookie = cookieName + "=;path=/;domain=" + this.getDomain() + ";expires=Thu, 01 Jan 1970 00:00:01 GMT";
	},
	
	deleteQuery: function(query) {
		var url = window.location.href.split("?")[0];
		var queryString = window.location.href.split("?")[1];
		var tempQueries = queryString.split("&");
		var queries = "";
		
		for(var i = 0; i < tempQueries.length; i++) {
			var queryKey = tempQueries[i].split("=")[0];
			if(queryKey != query)
				queries += tempQueries[i] + "&";
		}
		
		history.pushState(history.state, '', url + "?" + queries);		
	},
	
	renderTemplate: function(template, fieldData) {
		var ret = template;
		for(var field in fieldData) {
			ret = ret.replace(new RegExp("{{" + field + "}}", "g"), fieldData[field]);
		}
		return ret;
	},

	// Log messages to console. If console is not supported by the browser,
	// optionally alert the messages.
	log: function (msg) {
		//SSO.enableLogging = true;
		
		// Switch on alert logging for browsers not supporting console logging
		var alertFallback = false;

		// Switch on logging by setting SSO.enableLogging to true
		if (!SSO.enableLogging) return;

		if (!window.console) {
			console = {log: function() {}};
			if (alertFallback) alert(msg);
		}
		
		console.log(msg);
	},

	// Helper function to load in extra scripts in a cross-browser fashion.

	loadScript: function (url, callback) {
		var script = document.createElement('script');
		script.type = 'text/javascript';

		if (script.readyState) { //IE
			script.onreadystatechange = function () {
				if (script.readyState == 'loaded' || script.readyState == 'complete') {
					script.onreadystatechange = null;
					callback();
				}
			};
		} else { //Others
			script.onload = function () {
				callback();
			};
		}

		script.src = url;
		document.getElementsByTagName('head')[0].appendChild(script);
	},

	urlParameters: (function () {
		var href = window.location.href,
			hashIndex = href.indexOf('#'),
			params = href.slice(href.indexOf('?') + 1, hashIndex > -1 ? hashIndex : href.length).split('&'),
			numParams = params.length,
			urlParams = {},
			i = 0;
		var paramPair;

		// parse URL parameters
		for (; i < numParams; ++i) {
			paramPair = params[i].split('=');
			urlParams[paramPair[0]] = paramPair[1];
		}

		return urlParams;
	})(),
	
	getResourceUrl: function() {
		var scriptTag = document.getElementById('sso-bar-script');
		var scriptUrl = scriptTag.src;
		var resourceUrl = scriptUrl.substr(0, scriptUrl.indexOf('/scripts/sso.bar.js'));
		SSO.utility.log("**** ResourceUrl: "+ resourceUrl +"****");
		return resourceUrl;
	},
	
	getApiUrl: function() {
		var baseUrl = SSO.utility.getBaseUrl();
		if(baseUrl[baseUrl.length -1] !== "/")
			baseUrl += "/";
		var contextPath = baseUrl + config.communityId;
		return contextPath;
	},
	
	getBaseUrl: function() {
		var resourceUrl = SSO.utility.getResourceUrl();
		var baseUrl = resourceUrl.substr(0, resourceUrl.indexOf('/resources/common'));
		SSO.utility.log("**** BaseUrl: "+ baseUrl + "****")	;
		return baseUrl;
	},

	getLayoutType: function (config) {
		if (config.layout && config.layout.type) {
			if (config.layout.type == "mobile")
				return "mobile";
			else if (config.layout.type == "hybrid")
				return "hybrid";
		}	

		return "desktop";
	}
	
};

SSO.Bar = function (siteConfig) { 
	/* Private */
	var self = this,
		apiUrl = SSO.utility.getResourceUrl(),
		aUrl = SSO.utility.getApiUrl(),
		accountAlertCount = 0,
		$container, $,
		dictionaryLoaded = false, userInfoLoaded = false,
		personalizeBarCalled = false;

	SSO.utility.ie8shiv();
	SSO.utility.log("*** BAR.construct() ***");

	function attachBarToDom() {
		
		SSO.utility.log("** SSO.attachBarToDom() **");
		SSO.utility.log(self.config.containerId);
		// if the containerId is a string
		if (typeof self.config.containerId === "string") {
			// if DOM element exists, use that.
			if (document.getElementById(config.containerId)) {
				var container = document.getElementById(config.containerId);
				container.id = config.containerId;
				$container = $(container);
			}
			// else create it
			else {
				var container = document.createElement('div');
				container.id = config.containerId;
				$("body").append(container);
				$container = $(container);
			}
		}
		
		for (s in config.initBarStyles) {
			if(config.initBarStyles.hasOwnProperty(s)) {
				$container.style[s] = config.initBarStyles[s];
			}
		}
		if (config.fixed === true) {
			$container.style.display = "fixed";
		}
		$($container).addClass('SSO-BAR').addClass('cf');
		$container.hide();
		
	};

	function initCSS() {
		SSO.utility.log("** SSO.initCSS() **");

		var config = self.config,
			i = 0,
			loadedScripts = 0,
			numScripts = config.css.length,
			link, img;

		for (; i < numScripts; ++i) {
			link = document.createElement("link");
			
			link.href = apiUrl + '/' + config.css[i].replace(/%SITE%/, config.communityId);
			link.rel = 'stylesheet';
			link.type = 'text/css';
			
			if($('body').hasClass('sso') || $('body').hasClass('redemptionPage')) {
				$('head').append(link);
			}
			
			// piggy back on image onerror event to use
			// as an onload event for stylesheets since
			// there are no crossbrowser load events for
			// link elements
			img = document.createElement('img');
			img.onerror = function() {
				loadedScripts++;
				
				if (loadedScripts === numScripts) {
					self.allStylesLoaded = SSO.Bar.allStylesLoaded = true;
					displaySSOBar();
				}
			};
			img.src = link.href;
		}
	}
	
	var getBarHtml = function() {
		
		var htmlUrl, successFunc;
		
		SSO.utility.log("** SSO.getBarHtml **");
		
		var oldBarHtmlCall = function (htmlUrl, successFunc) {
			$.ajax({
				url: htmlUrl,
				dataType: 'jsonp',
				cache: true,
				jsonpCallback: 'returnSSOHTML',
				context: self,
				success: successFunc,
				error: function (d) {
					SSO.utility.log("ERROR GETTING BAR HTML");
				}
			});
		}

		var hybridGetBarHtml = function (htmlUrl, layoutType) {
			$.ajax({
				url: SSO.utility.getApiUrl() + '/script/html/' + (self.locale ? "loc_" + self.locale : "default"), 
				jsonpCallback: "returnHtmlObj",
				dataType: "jsonp"
			}).done(function (d) {
				modularRender(d, layoutType);
			});
		}

		// decide if desktop or mobile layout
		var layout = self.config.layout;
		var layoutType = SSO.utility.getLayoutType(self.config);

		if (layoutType == "mobile") {
			htmlUrl = apiUrl + '/scripts/html-mobile.js';
			successFunc = function (returnObject, status) {
				modularRender(returnObject, layout);
			};
			oldBarHtmlCall(htmlUrl, successFunc);
		} else if (layoutType == "hybrid") {
			htmlUrl = SSO.utility.getApiUrl() + '/script/html/';
			hybridGetBarHtml(htmlUrl, layoutType);
		} else if (layoutType == "desktop") {
			htmlUrl = apiUrl + '/scripts/html.js';
			successFunc = function (returnObject, status) {
				render(returnObject);
			};
			oldBarHtmlCall(htmlUrl, successFunc);
		}
		
				
	};

	var displaySSOBar = function() {
		var layoutType = SSO.utility.getLayoutType(self.config);

		if (self.allStylesLoaded && self.isContentLoaded && 
				(layoutType == "desktop" || layoutType == "hybrid")) {
			$container[0].style.display = "block";
		}
	};

	function initScripts() {
		// Removed head.js and replaced all head.js calls with loadScript (it's a grand total of one - the simpleModal loading
		// procedure)
		SSO.utility.log("** SSO.initScripts() **");
		initJQuery();
	}

	function initJQuery() {
		SSO.utility.log("** SSO.initJQuery() **");
		var prevJQuery, prev$;

		function jQueryInitHandler() {
			$ = self.jQuery = window.jQuery;

			if (prevJQuery) {
				window.jQuery = prevJQuery;
				window.$ = prev$;
			}

			self.processConfig();
		}

		if (window.jQuery && window.jQuery.fn.jquery < '1.4.1') {
			SSO.utility.log("loading newer version of JQuery");
			prevJQuery = window.jQuery;
			prev$ = window.$;

			SSO.utility.loadScript(self.config.jQuery, jQueryInitHandler);
		} else if (!window.jQuery) {
			SSO.utility.log("sso.bar - loading jQuery");

			SSO.utility.loadScript(self.config.jQuery, jQueryInitHandler);
		} else {
			SSO.utility.log("jQuery exists");
			jQueryInitHandler();
		}
	}
	
	function menuCtaListeners() {
		SSO.utility.log("*** SSO.menuCtaListeners() ***");
		var $doc = $(document);
		if($doc.on) $doc.on("click", ".menu-close-button", null, menuCloseHandler);
		else $doc.delegate(".menu-close-button", "click", null, menuCloseHandler);
		
		$('.sso-menu-cta').bind('click', menuCtaHandler);
	}

	function menuCloseHandler(e) {
		SSO.utility.log("*** SSO.menuCloseHandler ***");
		$(self.menuOpen).removeClass('is-active');
		self.hideOverlay();
		$("#sso-modal").unbind('click.ssoMenu');
		self.menuOpen = null;
		return false;
	}

	function menuCtaHandler(e) {
		SSO.utility.log("*** SSO.menuCtaHandler() ***");
		var m = $('#sso-modal'),
			$this = $(this),
			$menuItem = $this.closest('li');
		
		var hasActiveClass = $menuItem.hasClass('is-active');
		
		if (hasActiveClass) {
			// remove active
			$menuItem.removeClass('is-active');
			$(m).addClass('off').removeClass('on');
		} else {
			$('#sso-bar-menu').find('.is-active').removeClass('is-active');
		
			$menuItem.addClass('is-active');
			
			if ($this.attr('rel')) {
				self.showOverlay();
				
				$('.SSO-BAR').bind('click.ssoMenu', function (e) {
					var target = $(e.target);
					if (target.hasClass('SSO-BAR') || target.attr('id') === 'sso-bar-wrapper') {
						menuCloseHandler(e);
					}
				});

				self.menuOpen = this.parentNode;
				$(this).blur();
				return false;
				
			}
		}
	}

	var SSOBarReady = function(personalizeFunc) {
		SSO.utility.log("** BAR COMPLETELY INITTED **");

		modularAuthenticateUser(personalizeFunc);
		modularLoadDictionary(self.locale, modularDictionaryLoaded);

		// put the right flag on the menu
		modularSetLocales();

		$('.ssoLogout, .sso-account-action-logout').attr("href", self.getLogoutUrl()).click(function() {
			$.ajax({
				url: SSO.dictionary["jive-logout-url"],
				complete: function () {
					window.location = self.getLogoutUrl() + "?redirectUrl=" + encodeURIComponent(SSO.dictionary['logout-url']);
				}
			});
			return false;
		});
		
		if( self.config.layout == null ) { 
			defaultSSOBarReady();
		} else {
			$('.register-complete-changeemailorresend').attr('href', self.getChangeOrResendEmailUrl());
			$('.complete-profile-alert-link').attr('href', self.getCompleteProfileUrl());
			$('.sso-account-action-profile').attr("href", self.doProfilePath());
		}

		renderLocales();

		var layoutType = SSO.utility.getLayoutType(self.config);

		$('body').addClass('with-sso-bar').addClass(layoutType);

		if (self.config.exploreUrl) {
			$exploreLinksLoc = (layoutType == 'hybrid') ? $(".sso-explore-list") : $("#sso-site-links");
			renderExploreLinks($exploreLinksLoc);
		}
		if (self.config.supportUrl) {
			renderSupportUrl();
		}
	};

	var defaultSSOBarReady = function () {
		menuCtaListeners();	

		if (self.config.siteFlow == 'child')
			configureChildSSO();

		$('#sso-account-action-profile').attr("href", self.doProfilePath());

		$('#signup-solo').attr('href', self.getSignupUrl());
		$('#login-solo').attr('href', self.getLoginUrl());
		$('#register-complete-changeemailorresend').attr('href', self.getChangeOrResendEmailUrl());
		$('#complete-profile-alert-link').attr('href', self.getCompleteProfileUrl());
	};

	var defaultPersonalizeFunction = function () { tryPersonalize(personalizeBar); };

	function configureChildSSO() {
		/*
		 * DOLOGIN fired on Login Form submit to build the action to send off to.
		 * Uses the current page to redirect back after the login attempt.
		 * 
		 * http://apiserver/process_login?redirectUrl=http://currsntserver/currentpage
		 */
		var doLoginUrl = function() {
			return self.getSecureUrl(aUrl).replace("/" + self.config.communityId, "") + '/do_login?' + self.getRedirectUrl();
		};
		
		function getRegistrationUrl() {
			var url = aUrl;

			if (self.config.siteFlow === 'child') {
				url = url + '/register';
			} else {
				url = url + '/register/dob.act';
			}

			$(this).unbind('submit').attr('action', url);

			return true;
		}

		// bind the login and register
		$('#ssoFormLogin').attr("action", doLoginUrl());
		$('#sso-register-button').attr("href", SSO.utility.getApiUrl() + "/register");
	
		// has to be fired after the bar is initted and wired up. (session)
		$('#frmAgeGate').bind("submit", getRegistrationUrl);
		$('#sso-facebook-login-img').attr('href', self.getFacebookPath());
		$('#sso-forgot-password').attr('href', self.getForgotPasswordUrl());
	}
	
	function mastheadLinkSet() {
		var mastheadLink = self.config.mastheadLink;
		$('.sso-masthead-link').attr('href', mastheadLink);
	}
	
	function buildLoginDiv(returnObject) {
		if(!self.config.communityId) SSO.utility.log("### Community Id not set in SSO Config ###");
		
		if(!SSO.utility.getCookie("comid"))
			SSO.utility.setCookie("comid", self.config.communityId, "");
		
		if(!SSO.utility.getCookie("new_SiteId")) 
			SSO.utility.setCookie("new_SiteId", self.config.communityId , "");
		
		var loginDivContainer = self.config.loginDivContainer,
			fbLoginRedirect = self.config.fbLoginRedirect ? "?redirectUrl=" + encodeURIComponent(self.config.fbLoginRedirect) : "";
		var redirectUrl = "";
		
		$(loginDivContainer).html(returnObject.loginFragment);
		
		$("#sso-placed-login #fbLogin").attr("action", SSO.utility.getApiUrl() + "/facebookLoginUrl" + fbLoginRedirect);
		
		$("#sso-login-facebook-button-menu-label").click(function(d){
			d.preventDefault();
			$("#fbLogin").submit();
		});
			
		if(self.config.redirectUrl)
			redirectUrl = "?redirectUrl=" + encodeURIComponent(self.config.redirectUrl);

		
		$("#sso-placed-login #frmLogin").attr("action", SSO.utility.getBaseUrl() + "/do_login" + redirectUrl );
		
		$("#sso-placed-login #sso-login-forgot-password-menu-label").attr("href", SSO.utility.getApiUrl() + "/forgotPassword" + redirectUrl);
		$("#sso-placed-login #sso-login-need-account-menu-label").attr("href", SSO.utility.getApiUrl() + "/register" + redirectUrl);
	}
	
	var render = function(htmlData) {
		SSO.utility.log("*** SSO.BAR.render()***");
		
		$container.html(generateDesktopBarHtml(htmlData));
		
		renderOverlay();

		//TODO: ADD THIS BACK IN FOR USE WITH MOBILE
		//setupEventHandlersMobile(".sso-mobile-navigation-button", false);

		SSOBarReady(defaultPersonalizeFunction);
		
		self.isContentLoaded = SSO.Bar.isContentLoaded = true;
		
		if(self.config.loginDivContainer)
			buildLoginDiv(htmlData);
	};
	
	var generateDesktopBarHtml = function(htmlData) {
		var html = htmlData.htmlStart;
		// conditionally use login/register dropdown vs. buttons based on where SSO bar is running
		html += (self.config.siteFlow !== 'child' ? htmlData.menuRegisterLoginButtons : htmlData.menuRegisterLoginDropdown);
		html += htmlData.menuIdentity + htmlData.masthead + htmlData.menuCommon + htmlData.htmlEnd;

		//TODO: Add this back in for use with mobile
		// add mobile html for use later with using media queries instead of backend verification of useragents.
		
		//html += htmlData.mobileSSOButton + htmlData.mobileSSOModalStart + htmlData.mobileRegisterLoginButtons + htmlData.mobileMenuCommon + htmlData.mobileSSOModalEnd;

		return html;
	};
	
	var modularRender = function(htmlData, layout) {
		SSO.utility.log("*** SSO.Bar.modularRender() ***");
		switch(layout) {
			case "hybrid":
				renderHybrid(htmlData, layout || {});
				break;
			case "mobile":
			default:
				renderMobile(htmlData, layout || {});
		}
		
		self.isContentLoaded = self.isContentLoaded = true;

		SSOBarReady(modularAuthenticationDone);
		
	};

	var layoutGeneration = function(layoutItems) {
		/**
			{device}[i] : will place i element in the position related to it's number within the device;

			layoutItems.desktop == ['desktopStart', 'masthead', 'explore', 'support', 'locale', 'accounts', 'notifications', 'loginRegisterButtons', 'desktopEnd']
			layoutItems.mobile == ['mobileStart', 'mobileButton', 'masthead', 'mobileEnd', 'modalStart', 'explore', 'support', 'locale', 'accounts', 'notifications', 'mobileLoginRegister', 'modalEnd']
		**/

		var defaultSSOElements = {
			//desktop: ['desktopStart', 'masthead', 'siteLinks', 'support',  'accountsNew',  'siteLinksRight', 'loginRegisterButtons', 'locale', 'desktopEnd'],
			//mobile: ['mobileStart', 'mobileButton', 'masthead', 'mobilePurchase', 'mobileLoginRegister', 'mobileEnd', 'modalStart', 'locale', 'siteLinks', 'support', 'accountsNew', 'modalEnd']

			desktop: ['desktopStart', 'masthead', 'siteLinks', 'support',  'accountsNew', 'rightSideStart', 'loginRegisterButtons', 'locale',  'siteLinksRight', 'rightSideEnd', 'desktopEnd'],
			mobile: ['mobileStart', 'masthead', 'mobilePurchase', 'mobileButton', 'mobileLoginRegister', 'mobileEnd', 'modalStart', 'siteLinks', 'support', 'accountsNew', 'locale', 'modalEnd']
		};
		
		if (SSO.utility.getDomain() == "callofduty.com") {
			//defaultSSOElements.desktop = ['desktopStart', 'mobileButton', 'masthead', 'siteLinks', 'support',  'accountsNew', 'rightSideStart', 'loginRegisterButtons', 'locale',  'siteLinksRight', 'rightSideEnd', 'desktopEnd'];
			//defaultSSOElements.mobile = ['mobileStart', 'mobileButton', 'masthead', 'rightSideStart','mobileLoginRegister', 'mobilePurchase', 'rightSideEnd', 'mobileEnd', 'modalStart', 'siteLinks', 'accountsNew', 'locale', 'modalEnd'];
			defaultSSOElements.mobile = ['mobileStart', 'mobileButton', 'masthead', 'siteLinks', 'rightSideStart','mobileLoginRegister', 'mobilePurchase', 'rightSideEnd', 'mobileEnd', 'modalStart', 'siteLinks', 'accountsNew', 'locale', 'modalEnd'];
		}

		var userDefinedElements = {};

		var generateItems = function (device) {
			userDefinedElements.device = [];
			for(var i = 0; i < layoutItems.device.length; i++) {
				userDefinedElements[device].push(layoutItems.device[i]);
			}
		}

		if(!layoutItems)
			return defaultSSOElements;

		var userDefinedElements = {};

		if(layoutItems.desktop && layoutItems.desktop.length) {
			generateItems("desktop");
			userDefinedElements.desktop.shift("desktopStart").push("desktopEnd")
		}	

		if(layoutItems.mobile && layoutItems.mobile.length) {
			generateItems("mobile");
			userDefinedElements.mobile.shift("modalStart").push("modalEnd");
		}

		return userDefinedElements;

	};

	var hybridEventHandlers = function () {
		$(".mobile-navigation-button, .mobile.sso-modal").click(function(e) {
			if($(e.target).attr("href") == "" || !$(e.target).attr("href")) {
				e.preventDefault();

				$(".mobile.sso-modal").toggleClass("active");

				$(".mobile.sso-modal").find(".active").toggleClass("active");
				
				if($(".mobile.sso-modal").hasClass("active")) {
					$(".mobile-navigation-button").attr("aria-expanded", true);
					$(".mobile.sso-modal").attr("aria-expanded", true);
					
					if (SSO.utility.getDomain() == "callofduty.com") {
						$(".mobile.sso-modal").parent().siblings().css("pointer-events", "none");
						$("body").css("position", "fixed");
						
						//Close any and all open submenus when opening hamburger menu
						$('.sso-bar-wrapper.mobile .has-menu').removeClass('active');
						$('.sso-bar-wrapper.mobile .has-menu').find("> a").attr("aria-expanded", false);
					
						//Temporarily disable other header nav links from being focusable
						$(".sso-bar-wrapper.mobile .sso-masthead-wrapper a.sso-masthead-link").attr("tabindex","-1");
						$(".sso-bar-wrapper.mobile .sso-menu-element a").attr("tabindex","-1");
						$(".sso-bar-wrapper.mobile .right-side-container a").attr("tabindex","-1");
					}
					
				} else {
					$(".mobile-navigation-button").attr("aria-expanded", false);
					$(".mobile.sso-modal").attr("aria-expanded", false);

					if (SSO.utility.getDomain() == "callofduty.com") {
						$(".mobile.sso-modal").parent().siblings().css("pointer-events", "auto");
						$("body").css("position", "relative");
					
						//Remove temporary disablement of other header nav links from being focusable
						$(".sso-bar-wrapper.mobile .sso-masthead-wrapper a.sso-masthead-link").removeAttr("tabindex");
						$(".sso-bar-wrapper.mobile .sso-menu-element a").removeAttr("tabindex");
						$(".sso-bar-wrapper.mobile .right-side-container a").removeAttr("tabindex");
					}
				}

				return false;
			}
		});
		
		//Close and reset mobile menu if resized to desktop
		if (SSO.utility.getDomain() == "callofduty.com") {
	        $(window).resize(function() {
	            if((window.innerWidth > 1100) && ($(".mobile.sso-modal").attr("aria-expanded") == "true")) {
	            	$(".mobile-navigation-button").trigger("click");
	            }
	        });
	    }

		// Stop clicks for drop down menu items that are not links
		$(".sso-menu-element").on("click", "div *", function(e) {
			if(!$(e.target).is("a")) {
				e.stopPropagation();
				e.preventDefault();

				return false;
			}
		});

		// Close other active dropdowns if a new one is selected
		$(".mobile.sso-modal .mobile-modal-wrapper > div a").add(".desktop.sso-bar-wrapper .sso-bar-menu > div a").click(function(e) {
			e.stopPropagation();

			if(($(this).siblings().length > 0) && ($(this).attr("href") == "")) {
				e.preventDefault();
				var $activateElem = $(this).parent();
				var $otherOpenMenuItems = $(".mobile-modal-wrapper, .sso-bar-wrapper.desktop").find(".active").not($activateElem);
				
				$otherOpenMenuItems.removeClass("active");
				$($activateElem).toggleClass("active");
				
				if($($activateElem).hasClass("active")) {
					$(this).attr("aria-expanded", true);
				} else {
					$(this).attr("aria-expanded", false);
				}

				return false;
			}
		});
		
		//<=====================================================================================
		//Event Handler Grouping for COD header nav Hamburger menu's keyboard accessibility
		if (SSO.utility.getDomain() == "callofduty.com") {			
			//Extra event handler for keydown while on the hamburger icon button.
			$('.sso-bar-wrapper.mobile .mobile-navigation-button').keydown(function(e) {
				//If keydown is the SHIFT+TAB key	
				if(e.shiftKey && e.keyCode === 9) {					
					//If the hamburger flyout is open/expanded.
					if($('.mobile.sso-modal').hasClass("active")) {
						e.preventDefault();
						//Move focus backwards to last menu item (FLAG ICON) in the hamburger flyout.
						$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').focus();
					}
				}
			});	

			//Extra event handler for keydown while on locale chooser flag icon button inside hamburger flyout.
			$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').keydown(function(e) {				
				//If keydown is the TAB key, but not SHIFT+TAB	
				if(!e.shiftKey && e.keyCode === 9) {
					e.preventDefault();
					//Move focus back to the top of the hamburger flyout - the hamburger close/X icon.
					$('.sso-bar-wrapper.mobile .mobile-navigation-button').focus();
				}
								
				//If keydown is the ENTER key
				if(e.keyCode === 13 || e.keyCode === 1) {
					setTimeout(function() {
						//Move focus to first country in the locale chooser list in the hamburger flyout
						$('.mobile.sso-modal .sso-locale-list-container a.sso-locale').first().focus();
						
						//Extra event handler for keydown while on the close button (X) for the locale chooser list inside hamburger flyout
						$('.mobile.sso-modal .sso-locale-list-container a.sso-locale-close').keydown(function(ev) {							
							//If keydown is the SHIFT+TAB key	
							if(ev.shiftKey && ev.keyCode === 9) {
								ev.preventDefault();
								//Move focus back to last country in the locale chooser list in the hamburger flyout
								$('.mobile.sso-modal .sso-locale-list-container a.sso-locale').last().focus();
							}
							
							//If keydown is the ENTER key	
							if(ev.keyCode === 13) {
								ev.preventDefault();
								//Close the locale chooser menu list							
								$('.mobile.sso-modal .sso-menu-element.sso-locale').removeClass('active');
								$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').attr("aria-expanded", false);
								//and move focus back to the current locale flag icon button it in the hamburger flyout	
								$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').focus();
							}
						});
						
						//Extra event handler for keydown while on the last country in the locale chooser menu list inside the hamburger flyout
						$('.mobile.sso-modal .sso-locale-list-container a.sso-locale').last().keydown(function(ev) {
							//If keydown is the TAB key, but not SHIFT+TAB
							if(!ev.shiftKey && ev.keyCode === 9) {
								ev.preventDefault();
								//Move focus back to first country in the locale chooser list in the hamburger flyout
								$('.mobile.sso-modal .sso-locale-list-container a.sso-locale-close').focus();
							}
						});							
					}, 200); //END setTimeout
				}
			});	
			
			//Duplicate of keydown handler directly above to handle MS Narrator's scan mode intercepting the ENTER keydown and executing a synthetic mouse click event instead.
			$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').click(function(e) {
					setTimeout(function() {
						//Move focus to first country in the locale chooser list in the hamburger flyout
						$('.mobile.sso-modal .sso-locale-list-container a.sso-locale').first().focus();
						
						//Extra event handler for keydown while on the close button (X) for the locale chooser list inside hamburger flyout
						$('.mobile.sso-modal .sso-locale-list-container a.sso-locale-close').keydown(function(ev) {							
							//If keydown is the SHIFT+TAB key	
							if(ev.shiftKey && ev.keyCode === 9) {
								ev.preventDefault();
								//Move focus back to last country in the locale chooser list in the hamburger flyout
								$('.mobile.sso-modal .sso-locale-list-container a.sso-locale').last().focus();
							}
							
							//If keydown is the ENTER key	
							if(ev.keyCode === 13) {
								ev.preventDefault();
								//Close the locale chooser menu list							
								$('.mobile.sso-modal .sso-menu-element.sso-locale').removeClass('active');
								$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').attr("aria-expanded", false);
								//and move focus back to the current locale flag icon button it in the hamburger flyout	
								$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').focus();
							}
						});
						
						//Extra event handler for keydown while on the last country in the locale chooser menu list inside the hamburger flyout
						$('.mobile.sso-modal .sso-locale-list-container a.sso-locale').last().keydown(function(ev) {
							//If keydown is the TAB key, but not SHIFT+TAB
							if(!ev.shiftKey && ev.keyCode === 9) {
								ev.preventDefault();
								//Move focus back to first country in the locale chooser list in the hamburger flyout
								$('.mobile.sso-modal .sso-locale-list-container a.sso-locale-close').focus();
							}
						});							
					}, 200); //END setTimeout
			});	
			
			//Extra CLICK handler for locale menu close button
			$('.mobile.sso-modal .sso-locale-list-container a.sso-locale-close').click(function(ev) {
				ev.preventDefault();
				$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').trigger("click").focus();
			});	
			
			//Extra event handler for ESCAPE keydown while hamburger flyout is expanded and focus is inside it.
			$('.mobile.sso-modal').keydown(function(e) {				
				//If keydown is the ESC key	
				if(e.keyCode === 27) {
					//Click the hamburger close icon to close the flyout and move focus back to hamburger icon button
					$('.sso-bar-wrapper.mobile .mobile-navigation-button').trigger("click").focus();	
				}
			});	
		} //END - Event Handler Grouping for COD header nav Hamburger menu's keyboard accessibility		
		//========================================================================================>
		
		if (SSO.utility.getDomain() == "callofduty.com") {		
			//COD ONLY - Desktop Nav - Hover
			//COD DESKTOP NAV is currently hidden
			if($('.sso-bar-wrapper.desktop .has-menu').length) {
				$('.sso-bar-wrapper.desktop .has-menu').hover(function(e) { 
					$(this).toggleClass('active');
				});
			}
		
			//COD ONLY - Mobile Nav - Hover
			if($('.sso-bar-wrapper.mobile .has-menu').length) {
				$('.sso-bar-wrapper.mobile .has-menu').hover(function(e) {
					//Close any and all open submenus
					$(this).siblings().removeClass('active');
					$(this).siblings().removeClass('hovering');
					$(this).siblings().find("> a").attr("aria-expanded", false);
					
					//Expand and open this submenu
					$(this).toggleClass('active');
					$(this).toggleClass('hovering');					
					var expandedValue = $(this).find("a").first().attr("aria-expanded");
					var newExpandedValue = (expandedValue === "true") ? "false" : "true";
					$(this).find("a").first().attr("aria-expanded", newExpandedValue);					
					
					//Collapse and close the hamburger menu
					$('.sso-modal.mobile').removeClass('active').attr("aria-expanded", false);
					$("body").css("position", "relative");
					$('.mobile-navigation-button').attr("aria-expanded", false);
					$(".mobile.sso-modal").parent().siblings().css("pointer-events", "auto");
					
					//Remove temporary disablement of other header nav links from being focusable
					$(".sso-bar-wrapper.mobile .sso-masthead-wrapper a.sso-masthead-link").removeAttr("tabindex");
					$(".sso-bar-wrapper.mobile .sso-menu-element a").removeAttr("tabindex");
					$(".sso-bar-wrapper.mobile .right-side-container a.mobile-purchase").removeAttr("tabindex");
				});
			}
			
			//COD ONLY - Desktop Nav - Click
			//COD DESKTOP NAV is currently hidden
			if($('.sso-bar-wrapper.desktop .has-menu > a').length) {
				$('.sso-bar-wrapper.desktop .has-menu > a').click(function(e) { 
					e.preventDefault();
				});
			}
			
			//COD ONLY - Mobile Nav - Click
			if($('.sso-bar-wrapper.mobile .has-menu > a').length) {
				$('.sso-bar-wrapper.mobile .has-menu > a').click(function(e) { 
					e.preventDefault();
					var key = e.which;	
					
					//If keydown is a not undefined (keyboard or mouse click) AND the mouse is not hovering over the link
					if(key > -1 && !$(this).parent().hasClass('hovering')) {
						//Close any and all open submenus
						$(this).parent().siblings().removeClass('active');
						$(this).parent().siblings().find("> a").attr("aria-expanded", false);
						
						//Expand and open this submenu
						$(this).parent().toggleClass('active');
						var expandedValue = $(this).attr("aria-expanded");
						var newExpandedValue = (expandedValue === "true") ? "false" : "true";
						$(this).attr("aria-expanded", newExpandedValue);

						//Collapse and close the hamburger menu
						$('.sso-modal.mobile').removeClass('active').attr("aria-expanded", false);
						$("body").css("position", "relative");
						$('.mobile-navigation-button').attr("aria-expanded", false);
						$(".mobile.sso-modal").parent().siblings().css("pointer-events", "auto");
						
						//Remove temporary disablement of other header nav links from being focusable
						$(".sso-bar-wrapper.mobile .sso-masthead-wrapper a.sso-masthead-link").removeAttr("tabindex");
						$(".sso-bar-wrapper.mobile .sso-menu-element a").removeAttr("tabindex");
						$(".sso-bar-wrapper.mobile .right-side-container a.mobile-purchase").removeAttr("tabindex");
						
						//Extra event handler for keydown while on the last menu item in the has-menu list
						$(this).parent().find("ul li a").last().keydown(function(ev) {
							//If keydown is the TAB key, but not SHIFT+TAB
							if(!ev.shiftKey && ev.keyCode === 9) {
								ev.preventDefault();
								//Move focus back to first menu item in the has-menu list
								$(this).parents(".has-menu.active").find("ul li a").first().focus();
							}
						});
						
						//Extra event handler for keydown while on the first menu item in the has-menu list
						$(this).parent().find("ul li a").first().keydown(function(ev) {						
							//If keydown is the SHIFT+TAB key	
							if(ev.shiftKey && ev.keyCode === 9) {
								ev.preventDefault();
								//Move focus back to last menu item in the has-menu list
								$(this).parents(".has-menu.active").find("ul li a").last().focus();
							}
						});
						
						//Extra event handler for ESCAPE keydown while on any menu item in the has-menu list
						$(this).parent().find("ul li a").keydown(function(e) {				
							//If keydown is the ESC key	
							if(e.keyCode === 27) {
								//Click the active submenu button to close the submenu and move focus back to submenu button
								$(this).parents(".has-menu.active").find("> a").trigger("click").focus();	
								$(this).parents(".has-menu.active").removeClass('active');
								$(this).parents(".has-menu.active").find("> a").attr("aria-expanded", false);
							}
						});	
					}
				});
			}
			
			//COD ONLY - Desktop Nav - Tabbing
			//COD DESKTOP NAV is currently hidden
			if($('.sso-bar-wrapper.desktop .has-menu > a').length) {
				$('.sso-bar-wrapper.desktop .has-menu > a').keydown(function(e) {					
					var key = e.which;	
					
					//If keydown is the ENTER key				
					if(key == 13) {
						//DO NOTHING CUSTOM.  LET IT GET HANDLED NATIVELY as a SYNTHETIC CLICK EVENT for the <a>.
					}
				});
			}
			
			//COD ONLY - Mobile Nav - Tabbing
			if($('.sso-bar-wrapper.mobile .has-menu > a').length) {
				$('.sso-bar-wrapper.mobile .has-menu > a').keydown(function(e) {
					var key = e.which;
					
					//If keydown is the ENTER key	
					if(key == 13) {
						//DO NOTHING CUSTOM.  LET IT GET HANDLED NATIVELY as a SYNTHETIC CLICK EVENT for the <a>.
						/*
						$(this).parent().siblings().removeClass('active');
						$(this).parent().siblings().find("> a").attr("aria-expanded", false);
						
						//Expand and open this submenu
						$(this).parent().toggleClass('active');						
						var expandedValue = $(this).attr("aria-expanded");
						var newExpandedValue = (expandedValue === "true") ? "false" : "true";
						$(this).attr("aria-expanded", newExpandedValue);

						$('.sso-modal.mobile').removeClass('active').attr("aria-expanded", false);
						*/						
					}
				});
			}
			
			//COD ONLY - Mobile Modal Nav - Tabbing
			if($('.mobile-modal-wrapper .has-menu > a').length) {
				$('.mobile-modal-wrapper .has-menu > a').click(function(e) { 
					$(this).parent().toggleClass('active');
					e.preventDefault();
				});
			}
			
			//COD ONLY - Header Nav - Scroll Fade in/out
	        var $header = $("#cdo-bar");	
	        var lastScrollTop = 0;
	
	        $(window).scroll(function(e) {		
                var st = $(this).scrollTop();

                if(st > 300) {
                    if(st > lastScrollTop) {
                        // downscroll 
                        $header.fadeOut();	
                    } else {
                        // upscroll
                        $header.fadeIn();
                    }
                } else {
                    $header.fadeIn();
                }

                lastScrollTop = st;
	        });			
		}
		

		//<========================================================================================
		//Event Handler Grouping for Activision header nav Hamburger menu's keyboard accessibility		
		if (SSO.utility.getDomain() == "activision.com") {
			
			//Extra event handler for keydown while on the last menu item in the hamburger flyout nav menu
			$(".mobile.sso-modal").find(".sso-menu-element > a, .site-link a").last().keydown(function(ev) {
				//If keydown is the TAB key, but not SHIFT+TAB
				if(!ev.shiftKey && ev.keyCode === 9) {
					ev.preventDefault();
					//Move focus back to first menu item in the has-menu list
					$(".mobile-navigation-button").focus();
				}
			});
			
			//Extra event handler for keydown while on the first menu item (hamburger button) in the hamburger flyout nav menu
			$(".mobile-navigation-button").keydown(function(ev) {
				//If keydown is the SHIFT+TAB key	
				if(ev.shiftKey && ev.keyCode === 9) {
					if ($(this).attr("aria-expanded") == "true") {
						ev.preventDefault();
						//Move focus back to last menu item in the has-menu list
						$(".mobile.sso-modal").find(".sso-menu-element > a, .site-link a").last().focus();
					}
				}
			});
		
			//Event handler for ESCAPE keydown while on any menu item in the hamburger flyout menu nav menu
			$(".mobile.sso-modal").find("a").keydown(function(e) {
				//If keydown is the ESC key	
				if(e.keyCode === 27) {
					//Click the hamburger button to close the hamburger flyout menu and move focus back to hamburger button
					$(".mobile-navigation-button").trigger("click").focus();
				}
			});	

			//Extra event handler for keydown while on locale chooser flag icon button inside hamburger flyout.
			$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').keydown(function(e) {		
								
				//If keydown is the ENTER key
				if(e.keyCode === 13 || e.keyCode === 1) {
					setTimeout(function() {
						//Move focus to first country in the locale chooser list in the hamburger flyout
						$('.mobile.sso-modal .sso-locale-list-container a.sso-locale').first().focus();
						
						//Extra event handler for keydown while on the close button (X) for the locale chooser list inside hamburger flyout
						$('.mobile.sso-modal .sso-locale-list-container a.sso-locale-close').keydown(function(ev) {							
							//If keydown is the SHIFT+TAB key	
							if(ev.shiftKey && ev.keyCode === 9) {
								ev.preventDefault();
								//Move focus back to last country in the locale chooser list in the hamburger flyout
								$('.mobile.sso-modal .sso-locale-list-container a.sso-locale').last().focus();
							}
							
							//If keydown is the ENTER key	
							if(ev.keyCode === 13) {
								ev.preventDefault();
								//Close the locale chooser menu list							
								$('.mobile.sso-modal .sso-menu-element.sso-locale').removeClass('active');
								$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').attr("aria-expanded", false);
								//and move focus back to the current locale flag icon button it in the hamburger flyout	
								$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').focus();
							}
						});
						
						//Extra event handler for keydown while on the last country in the locale chooser menu list inside the hamburger flyout
						$('.mobile.sso-modal .sso-locale-list-container a.sso-locale').last().keydown(function(ev) {
							//If keydown is the TAB key, but not SHIFT+TAB
							if(!ev.shiftKey && ev.keyCode === 9) {
								ev.preventDefault();
								//Move focus back to first country in the locale chooser list in the hamburger flyout
								$('.mobile.sso-modal .sso-locale-list-container a.sso-locale-close').focus();
							}
						});							
					}, 200); //END setTimeout
				}
			});	
			
			//Duplicate of keydown handler directly above to handle MS Narrator's scan mode intercepting the ENTER keydown and executing a synthetic mouse click event instead.
			$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').click(function(e) {
					setTimeout(function() {
						
						//Extra event handler for keydown while on the close button (X) for the locale chooser list inside hamburger flyout
						$('.mobile.sso-modal .sso-locale-list-container a.sso-locale-close').keydown(function(ev) {							
							//If keydown is the SHIFT+TAB key	
							if(ev.shiftKey && ev.keyCode === 9) {
								ev.preventDefault();
								//Move focus back to last country in the locale chooser list in the hamburger flyout
								$('.mobile.sso-modal .sso-locale-list-container a.sso-locale').last().focus();
							}
							
							//If keydown is the ENTER key	
							if(ev.keyCode === 13) {
								ev.preventDefault();
								//Close the locale chooser menu list							
								$('.mobile.sso-modal .sso-menu-element.sso-locale').removeClass('active');
								$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').attr("aria-expanded", false);
								//and move focus back to the current locale flag icon button it in the hamburger flyout	
								$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').focus();
							}
						});
						
						//Extra event handler for keydown while on the last country in the locale chooser menu list inside the hamburger flyout
						$('.mobile.sso-modal .sso-locale-list-container a.sso-locale').last().keydown(function(ev) {
							//If keydown is the TAB key, but not SHIFT+TAB
							if(!ev.shiftKey && ev.keyCode === 9) {
								ev.preventDefault();
								//Move focus back to first country in the locale chooser list in the hamburger flyout
								$('.mobile.sso-modal .sso-locale-list-container a.sso-locale-close').focus();
							}
						});							
					}, 200); //END setTimeout
			});	
			
			//Extra CLICK handler for locale menu close button
			$('.mobile.sso-modal .sso-locale-list-container a.sso-locale-close').click(function(ev) {
				ev.preventDefault();
				$('.mobile.sso-modal .sso-menu-element.sso-locale a.sso-locale-chooser').trigger("click").focus();
			});	

		}
		//Event Handler Grouping for Activision header nav Hamburger menu's keyboard accessibility
		//========================================================================================>
	};

	// hybrid SSO that contains both desktop and mobile versions for use with media queries
	var renderHybrid = function (htmlData, layout) {
		if(layout.items && layout.items.length)
			items = layout.items;

		var genLayout = layoutGeneration(layout.items);
		$container.html(generateHybridHtml(htmlData, genLayout));

		hybridEventHandlers();

		initOverlay();
	};

	var generateHybridHtml = function (htmlData, genLayout) {
		var html = "";
		for(var device in genLayout) {
			for(var i = 0; i < genLayout[device].length; i++)
				html = html + (htmlData.hybrid[genLayout[device][i]]);
		}

		return html;
	}
	
	var renderMobile = function(htmlData, layout) {
		var items = mobileGetLayoutBodyItems(layout.body || []);
		var html = generateMobileHtml(htmlData, items);
		$container.html(html).addClass("SSO-MOBILE");
		$container.hide();
		
		$(layout.button).append(htmlData.mobileButtonWrapper).addClass("SSO-BAR SSO-MOBILE sso-mobile-navigation-button");
		
		initOverlay();
		
		setupEventHandlersMobile(layout.button, layout.syncedHeight || 68);
	};
	
	var mobileGetLayoutBodyItems = function(layoutItems) {
		var types = {};
		var items = [];
		for(var i = 0; i < layoutItems.length || 0; i++) {
			var li = layoutItems[i];
			switch(li.type) {
			case "link":
			case "explore":
			case "account":
			case "locales":
			case "support":
				types[li.type] = 1;
				items.push(li);
				// add separators if necessary?
				break;
			}
		}
		// add defaults
		if(!types["support"])
			items.push({type: "support"});
		if(!types["locales"])
			items.push({type: "locales"});
		if(!types["account"])
			items.push({type: "account"});
		
		return items;
	};
	
	var generateMobileHtml = function(htmlData, items) {
		var rendered = [], o;
		for(var i = 0; i < items.length; i++) {
			var item = items[i];
			switch(item.type) {
			case "link":
				// defaults
				item.cssClass = item.cssClass || "";
				item.text = item.text || "";
				item.title = item.title || item.text;
				rendered.push(SSO.utility.renderTemplate(htmlData.mobileBarLink, item));
				break;
			case "account":
				// These values 
				o = {
					profileHref: self.doProfilePath(),
					profileText: item.profileText || "",
					logoutHref: self.getLogoutUrl(),
					logoutText: item.logoutText || "",
					loginHref: self.getLoginUrl(),
					loginText: item.loginText || "",
					registerHref: self.getSignupUrl(),
					registerText: item.registerText || ""
				};
				o.profileTitle = o.profileText;
				o.logoutTitle = o.logoutText;
				o.loginTitle = o.loginText;
				o.registerTitle = o.registerText;
				rendered.push(SSO.utility.renderTemplate(htmlData.mobileBarSSOAccount, o)); 
				break;
			case "locales":
				break;
			case "support":
				item.text = item.text || "";
				item.title = item.title || item.text;
				item.cssClass = item.cssClass || "";
				rendered.push(SSO.utility.renderTemplate(htmlData.mobileBarSupport, item));
				break;
			}
		}
		var html = SSO.utility.renderTemplate(htmlData.mobileBarWrapper, { listContents: rendered.join("") }); 
		return html;
	};
	
	var modularSetLocales = function() {
		// TODO is this needed? alert("modularSetLocales!!!?!?!?!");
		if (self.config.constants.OLD_LOCALES[self.locale]) {
			newLocaleCode = self.config.constants.OLD_LOCALES[self.locale].newCode;
			countryCode = self.getLocaleCountry(newLocaleCode);
			$('#sso-locale-menu-label').addClass(countryCode);
			$(".sso-menu-element.sso-locale").addClass(countryCode);
		} else {
			$('#sso-locale-menu-label').addClass(self.getLocaleCountry(self.locale));
			$(".sso-menu-element.sso-locale").addClass(self.getLocaleCountry(self.locale));
			
			var localeCode = self.getLocaleCountry(self.locale);
			var localeLabel = "";
			if (self.config.locales[self.locale]) {
				localeLabel = self.config.locales[self.locale].title;
			}
			if (localeCode == "TW" || localeCode == "CN") {
				var labelCont = $('<span class="sso-current-locale-label">' + localeLabel +'</span>');
				$(".sso-menu-element.sso-locale." + localeCode+ " span.sso-current-locale").after(labelCont);
			}			
		}
	};
	
	var setupEventHandlersMobile = function(button, syncedHeight) {
		var $overlay = $('<div class="mobile-sso-overlay off"></div>');
		var $navigation = $(".mobile-bar-wrapper .bar-list");

		$("body").append($overlay);

		var showNavigation = function() { 
			$navigation.addClass("on").removeClass("off"); 
			$overlay.addClass("on").removeClass("off");
			$container.addClass("mobile-open");
			if(!$container.find("#nav-button").length) 
				$container.show();
		};
		
		var hideNavigation = function() { 
			$navigation.addClass("off").removeClass("on"); 
			$overlay.addClass("off").removeClass("on");
			$container.removeClass("mobile-open");
			if(!$container.find("#nav-button").length)
				$container.hide();
		};
   
		$(button).click(function(){
			showNavigation();
			if(syncedHeight)
				cssFixes(syncedHeight);
		});
   
		$overlay.click(function(){
			hideNavigation();
		});
		
		var cssFixes = function(syncedHeight) {
			// standardHeightMinusBorder = 68;
			
			var $liElems = $(".bar-list li");
			for(var i = 0; i < $liElems.length; i++){
				var $linkContainers = $($liElems[i]); 
				var $linkContainer, paddingNeeded;
				
				if($($liElems[i]).has("div").size() > 0)
					$linkContainers = $($liElems[i]).find("div");

				for(var j = 0; j < $linkContainers.length; j++) {
					$linkContainer = $($linkContainers[j]);
					paddingNeeded = (syncedHeight - $linkContainer.find("a").height()) / 2;
			      
					if($linkContainer.height() != syncedHeight ) {
						$linkContainer.find("a")
							.css("padding-top", paddingNeeded + "px")
							.css("padding-bottom", paddingNeeded + "px");
					}
				}
			}
		};
	};
	
	var modularReady = function(layoutType) {
		SSO.utility.log("** BAR COMPLETELY INITTED **");

		$('body').addClass('with-sso-bar');
		
		modularAuthenticateUser(modularAuthenticationDone);
		modularLoadDictionary(self.locale, modularDictionaryLoaded);

		// TODO for locales: put the right flag on the menu
		modularSetLocales();
		
		// TODO switch these out for classes
		$container.find('.logout-link').click(function () {
			$.ajax({
				url: SSO.dictionary["jive-logout-url"],
				complete: function () {
					window.location = self.getLogoutUrl() + "?redirectUrl=" + encodeURIComponent(SSO.dictionary['logout-url']);
				}
			});
			return false;
		});

		if (self.config.exploreUrl) {
			renderExploreLinks($(".sso-explore-list"));
		}
		if (self.config.supportUrl) {
			renderSupportUrl();
		}
	};

	var modularAuthenticationDone = function() {
		// insert support url
		$container.find(".mobile-support a").attr("href", self.getSupportUrl());
		$(".sso-support a").attr("href", self.getSupportUrl());
		
		// setup account portion appropriately
		if(self.user.isLoggedIn) {
			$container.find(".mobile-account-loggedout").remove();
		} else {
			$container.find(".mobile-account-loggedin").remove();
		}
		
		tryPersonalize(modularPersonalizeBar);
	};
	
	var modularLoadDictionary = function(locale, successFunc) {
		SSO.utility.log("*** SSO.Bar.loadLocaleDictionary() ***  ");
		var url = SSO.utility.getApiUrl() + '/script/ssoProperties/' + (self.locale ? "loc_" + self.locale : "default");
		$.ajax({
			cache: true,
			url: url,
			dataType: 'script',
			context: self,
			success: successFunc,
			error: function (d) {
				SSO.utility.log("Error getting dictionary");
				SSO.utility.log(d);
				//this is end of the line
				ssoFinish();
			}
		});
	};
	
	var modularDictionaryLoaded = function(d) {
		dictionaryLoaded = true;
		SSO.utility.log("Language pack loaded");

		var layoutType = SSO.utility.getLayoutType(self.config);

		if(layoutType == "desktop") {
			mastheadLinkSet();
			dictionarySwap();
		} else if (layoutType == "mobile") {
			modularDictionarySwap();
		} else if (layoutType == "hybrid") {
			mastheadLinkSet();
			hybridDictionarySwap();
		}

		tryPersonalize(modularPersonalizeBar);
		ssoFinish();
	};

	var modularDictionarySwap = function() {
		
		var dictionary = SSO.dictionary;
		var domClass, element, value;
		self.config.dictionary = SSO.dictionary;
		
		for (domClass in dictionary) {
			var val = dictionary[domClass];
			if(dictionary.hasOwnProperty(domClass) && val) {
				SSO.utility.log("Swapping on class " + domClass);
				$el = $container.find("." + domClass);
				// only replace if there's nothing there
				if(!$el.html()) {
					$el.html(val);
					if(!$el.attr("title"))
						$el.attr("title", val);
				}
			}
		}
		
		if (dictionary) {
			// Replace Tooltips
			var keys = ["support", "explore"];
			for (var key in keys) {
				var elementClass = 'sso-' + keys[key] + '-menu-label';
				var dictionaryKey = elementClass + '-title';

				var $el = $container.find("." + elementClass);
				var title = dictionary[dictionaryKey];

				if ($el.length && title) {
					$el.attr("title", title);
				}
			}
		}
	};

	var hybridDictionarySwap = function () {
		var dictionary = SSO.dictionary,
			domId, element, value;
		self.config.dictionary = SSO.dictionary;

		var elems = ["explore-bar-sites", "explore-bar-more"];

		for (var elem in elems) {
			if(dictionary[elems[elem]] == null) 
				break;

			var $elem = $("." + elems[elem]);
			$elem.text(dictionary[elems[elem]]);
		}
	}
	
	var renderOverlay = function() {
		initOverlay();
		// click on overlay to close menu
		$("#sso-modal").bind('click', menuCloseHandler);
	};
	
	var initOverlay = function() {
		var $overlay = $('<div id="sso-modal" class="off"></div>');

		self.hideOverlay = function () {
			$overlay.addClass('off').removeClass('on');
		}, self.showOverlay = function () {
			$overlay.addClass('on').removeClass('off');
		};
		
	};

	function dictionarySwap() {
		
		var dictionary = SSO.dictionary,
			domId, element, value;
		self.config.dictionary = SSO.dictionary;
		
		for (domId in dictionary) {
			if(dictionary.hasOwnProperty(domId)) {
				value = dictionary[domId];
				SSO.utility.log("Swapping on id " + domId);
				if (value) {
					element = document.getElementById(domId);
					if (element) {
						element.innerHTML = value;
					}
				}
			}
		}
		
		if (dictionary) {
			// Replace Tooltips
			var keys = ["country", "support", "explore", "login-register", "identities", "login-need-account", "login-forgot-password", "login-facebook-button"];
			for (var key in keys) {
				var elementID = 'sso-' + keys[key] + '-menu-label';
				var dictionaryKey = elementID + '-title';

				var elemExplore = document.getElementById(elementID);
				var toolTip = SSO.dictionary[dictionaryKey];

				if (elemExplore && toolTip) {
					elemExplore.setAttribute('title', toolTip);
				}
			}
		}
	}

	function renderLocales() {
		// loop over the langs and deal with them
		SSO.utility.log("*** SSO.BAR.renderLocales()***");
		var l, li,
			numLocales = 0;
		var $flagContainer = ($('#sso-locale-items').length) ? $('#sso-locale-items') :  $(".sso-locale-list-container");
		
		function buildLocaleMarkup (l) {
			var li = document.createElement("li"),
				aflag = document.createElement("a"),
				anchore = document.createElement("a"),
				oldLocale = self.config.constants.OLD_LOCALES[l],
				locale = self.config.locales[l],
				localeHref;
			
			if (oldLocale) {
				aflag.className = "sprite flag " + self.getLocaleCountry(oldLocale.newCode);
				aflag.title = oldLocale.label;
				aflag.href = locale;
				anchore.title = oldLocale.label;
				anchore.innerHTML = oldLocale.label;
				anchore.href = locale;
			} else {
				localeHref = locale.href + window.location.search;
			
				if (!locale.href) {
					localeHref = window.location.pathname + window.location.search;
					//remove "lang" qparam
					localeHref = localeHref.replace(new RegExp('^([^#]*\?)(([^#]*)&)?lang(\=[^&#]*)?(&|#|$)' ), '$1$3$5').replace(/^([^#]*)((\?)&|\?(#|$))/,'$1$3$4');

					if (self.config.cms) {
						for(var localeCheck in self.config.locales) {
							var path = window.location.pathname;
							if(self.config.locales.hasOwnProperty(localeCheck)) {
								var cms = self.config.locales[localeCheck].cms;
								if(path.indexOf(cms + "/") === 1 || path == "/" + cms) {
									var replaceRegExp = new RegExp("\/" + cms);
									localeHref = localeHref.replace(replaceRegExp, "") || "/";
									break;
								}
							}
						}
						
						if(self.config.locales[l].cms) {
							var oldLocaleHref = localeHref;
							localeHref = window.location.protocol +"//"+ window.location.host +"/"+ self.config.locales[l].cms;
							localeHref += oldLocaleHref;
						}
					}
				}
				locale.title = $('<textarea/>').html(locale.title).val();
				aflag.className = "sprite flag " + self.getLocaleCountry(l);
				aflag.title = aflag.innerHTML = anchore.title = anchore.innerHTML = locale.title;
				aflag.href = anchore.href = localeHref;
			}

			aflag.setAttribute("tabindex", "-1");
			aflag.setAttribute("aria-hidden", "true");
			aflag.setAttribute("role", "img");
			aflag.rel = l;
			aflag.id = "sso-locale-flag-" + l + "-label";

			anchore.rel = l;
			anchore.id = "sso-locale-" + l + "-label";
			anchore.className = "sso-locale sso-locale-text";
			anchore.innerHTML += ' <span class="sr-only-selected">' + anchore.innerText +  ' selected</span>';

			li.appendChild(aflag);
			li.appendChild(anchore);
			return li;
		}
		
		for (l in self.config.locales) {
			if(self.config.locales.hasOwnProperty(l)){
				li = buildLocaleMarkup(l);
				if (li) {
					$flagContainer.append(li);
					numLocales++;
				}
			}
		}

		$($flagContainer.find("li")[numLocales - 1]).addClass("last-line");
		if(numLocales%2 != 1 && numLocales > 3) 
			$($flagContainer.find("li")[numLocales - 2]).addClass("last-line");

		
		if(!SSO.utility.getCookie('ACT_SSO_LOCALE')) SSO.utility.setCookie('ACT_SSO_LOCALE', "en_US");
		$('menu#sso-locale-items li a[rel="' + SSO.utility.getCookie('ACT_SSO_LOCALE') + '"]').addClass('is-selected');
		$('.sso-locale-list-container li a[rel="' + SSO.utility.getCookie('ACT_SSO_LOCALE') + '"]').addClass('is-selected');
		
		var currentLocaleText = $('.desktop .sso-locale-list-container .sprite.flag.is-selected').attr("title");
		$('.sso-current-locale').attr("aria-label", currentLocaleText);
		$('.sso-current-locale-title').html(currentLocaleText);
		
		$(".sso-bar-wrapper.desktop .sso-locale-list-container li a").each( function() {
			var thisId = $(this).attr("id");
			$(this).attr("id", thisId + "-desktop");
		});
		
		var flagLength = $('#sso-locale-items').find('li').length;
		var $localeli = $('#sso-locale-items').find('li');

		$localeli = $localeli.not($('#sso-locale-items').find('li').last());
		if(flagLength%2 != 1 && flagLength > 8)
			$localeli = $localeli.not($('#sso-locale-items').find('li').last().prev()); 
		$localeli.append('<hr />');
		
		//break into two columns on 8 or more locales
		if (numLocales > 8) $('#sso-locale-chooser').addClass('two-col');

		$('.sso-locale, .sprite.flag').bind('click', function (event) {
			SSO.utility.log("Setting cookie " + $(this).attr('rel'));
			SSO.utility.setCookie('ACT_SSO_LOCALE', $(this).attr('rel'));
		});

		if(numLocales < 2) {
			$(".sso-locale").hide();
		}
	}

	function renderExploreLinks($linksCont) {
		SSO.utility.log("*** SSO.BAR.renderExploreLinks()***");
		var i = 0,
			len = self.config.exploreUrl.length,
			className = "",
			idAttr = "",
			exploreUrls = self.config.exploreUrl,
			exploreItem, exploreMenuIndex, textLinks;

		$linksCont.empty();
		


		for (; i < len; ++i) {
			exploreItem = exploreUrls[i],
			exploreMenuIndex = i + 1;

			if (exploreItem.className) className = exploreItem.className;

			textLinks = $("<li>").append(
							$("<a>", {
								"href": exploreItem.href, 
								"id": "sso-exploreurl-text-" + exploreMenuIndex, 
								"class": className, 
								"text": exploreItem.title
							}));

			if(i == 0)
				textLinks = $("<h3>", {"id": "explore-bar-sites", "class": "explore-bar-sites"}).add(textLinks);
			if(i == 3)
				textLinks = $("<hr>").add($("<h3>", {"id": "explore-bar-more", "class": "explore-bar-more"})).add(textLinks);

			$linksCont.append(textLinks);
		}
	}

	var renderSupportUrl = function() {
		var bar = $(".SSO-BAR");
		var supportUrl = self.getSupportUrl(); 
		$("#sso-support-menu-label", bar).attr("href", supportUrl);
	};

	var checkAuthentication = function() {
		var authCookie = SSO.utility.getCookie('ACT_SSO_COOKIE');
		
		var user = self.user = self.user || {};
		
		if(authCookie) {
			authCookie = authCookie.replace(/\"/g,"");
			user.isLoggedIn = true;
			SSO.utility.log("*** User is authenticated *** ");
		} else {
			SSO.utility.log("*** User is not authenticated *** ");
		}
		
		return authCookie;
	};
	
	var getUserInfoUrl = function(authCookie) {
		return aUrl + "/userInfo/" + authCookie;
	};
	
	var modularAuthenticateUser = function(callback) {
		SSO.utility.log("*** SSO.Bar.modularAuthenticateUser() *** ");  
		var authCookie = checkAuthentication();
		var user = self.user;
		var url = getUserInfoUrl(authCookie);

		var defaultUserInit = function() {
			user.identities = [];
			callback();
		};

		if (!authCookie) {
			defaultUserInit();
			processAuthenticationCallbacks();
		} else {
			var successFunc = function (data) {
				setUserInfo(data);
				callback();
				//processAuthenticationCallbacks();
			};
			var errorFunc = function(data) {
				defaultUserInit();
				processAuthenticationCallbacks();
			};
			retrieveUserInfo(url, successFunc, errorFunc);
		}		
	};
	
	var retrieveUserInfo = function(url, successFunc, errorFunc) {
		$.ajax({
			url: url,
			headers: SSO.csrf.getCSRFObj(),
			dataType: 'jsonp',
			jsonp: false,
			jsonpCallback: 'userInfo',
			cache: true,
			success: successFunc,
			error: errorFunc
		});
	};
	
	var setUserInfo = function(data) {
		var response = data;
		
		userInfoLoaded = true;
		SSO.utility.log(response.userInfo);

		var user = self.user;
		user.isAuthenticated = response.userInfo.isAuthenticated;
		user.userInfo = response.userInfo;
		user.identities = response.identities;
		user.userInfo.percentageComplete = response.accountPercentageCompletion;
		user.userInfo.facebookLinked = response.facebookLinked;
		user.userInfo.emailValidated = response.emailValidated;
		user.userInfo.gamerAccountLinked = response.gamerAccountLinked;
		
		self.config.userLoaded();
	};

	var personalizeBar = function() {
		personalizeBarCalled = true;
		SSO.utility.log("*** SSO.Bar.personalizeBar() ***");
		SSO.utility.log(self.user);

		var user = self.user,
			userInfo = user ? user.userInfo : null,
			userName = userInfo ? userInfo.userName : null,
			graceLogins = 5;

		if (user.isLoggedIn) {
			renderPersonalizedBarContent(userInfo);
		} else {
			// user is not logged in
			$('#menu-login-register').addClass('on').removeClass('off');
			$('#menu-identity').addClass('off').removeClass('on').removeClass("with-img");
			$("#sso-identity, .sso-identity-dropdown-wrapper, .sso-notifications").hide();
		}
	}

	var modularPersonalizeBar = function() {
		personalizeBarCalled = true;
		SSO.utility.log("*** SSO.Bar.personalizeBar() ***");
		SSO.utility.log(self.user);	

		var user = self.user,
			userInfo = user ? user.userInfo : null,
			userName = userInfo ? userInfo.userName : null,
			graceLogins = 5;

		if (user.isLoggedIn) {
			$(".mobile-menu-login").add(".mobile-menu-register").hide();
			$(".mobile-login").add(".mobile-signup").hide();
			if (SSO.utility.getDomain() == "callofduty.com") {
				$(".sso-identities, #menu-identity").css("display", "inline-block");
			} else {
				$(".sso-identities, #menu-identity").show();
			}
			$(".sso-notifications").show();

			$("#menu-identity, #menu-notification").removeClass("off").addClass("on");


			renderPersonalizedBarContent(userInfo);
		} else {
			if (SSO.utility.getDomain() == "callofduty.com") {
				$(".sso-login-register-container").css("display", "inline-block");
			} else {
				$(".sso-login-register-container").show();
			}
			$("#menu-identity, .sso-identities, .sso-notifications").hide();

			$("#menu-login-register").removeClass("off").addClass("on");
		}

		// this is the end of the line
		ssoFinish();
	}
	
	/* TODO Cleanup the refs to DOM NOdes directly */

	var renderPersonalizedBarContent = function (userInfo) {
		$('#menu-notification').removeClass('off');
		if (userInfo.isGraceLogin) {
			// using grace period on email verification
			self.showNotification(userInfo.percentageComplete);
		} else {
			self.hideNotification(userInfo.percentageComplete);
		}

		var layoutType = SSO.utility.getLayoutType(self.config);
		fillNotifications(layoutType, userInfo);
		showAccounts(userInfo);
		pgacctHandler();

	}

	var fillNotifications = function(layoutType, userInfo) {
		var notificationElementList = {
			percentage: "profile-completion-percentage",
			facebook: "profile-complete-list-facebook",
			gamerAccount: "profile-complete-list-gamer-account",
			verifyEmail: "profile-complete-list-verify-email",
			emailAlert: "sso-notification-email-alert"
		}

		var attrType = "#";

		if(layoutType == "hybrid") 
			attrType = ".";

		if(userInfo.percentageComplete < 100)
			$(attrType + notificationElementList["percentage"]).text(" " + userInfo.percentageComplete + " ");
		
		if (userInfo.facebookLinked == true || self.config.facebookEnabled == false)
			$(attrType + notificationElementList["facebook"]).hide();
		if (userInfo.gamerAccountLinked == true)
			$(attrType + notificationElementList["gamerAccount"]).hide();
		if (userInfo.emailValidated == true)
			$(attrType + notificationElementList["verifyEmail"]).hide();
		if (userInfo.emailValidated == false)
			$(attrType + notificationElementList["emailAlert"]).show();
	}

	var showAccounts = function() {
		var user = self.user;
		$ssoIdentityWrapper = $("#sso-identity, .sso-identity-dropdown-wrapper"); 

		// show our gamer accounts
		if (user.identities) {
			var pgacct = (SSO.utility.getCookie('pgacct') || "").replace(/^\"(.*)\"$/, "$1");
			
			pgacctExists = false;
			
			$.each(user.identities, function (index, value) {
				if(value.provider == pgacct) pgacctExists = true;
			});
			
			//if user's pgacct does not exist but they have gaming accounts link, link to one of them.
			if(!pgacctExists || pgacct == "") {
				var pgacctFound = false;
				
				$.each(user.identities, function (index, value) {
					if(pgacctFound == true) return;
		
					switch (value.provider) {
						case "xbl": 
							pgacct = "xbl";
							pgacctFound = true;
							break;
						case "psn":
							pgacct = "psn";
							pgacctFound = true;
							break;
						case "steam":
							pgacct = "steam";
							pgacctFound = true;
							break;
						case "nintendo":
							pgacct = "nintendo";
							pgacctFound = true;
							break;
						default: 
							pgacct = "nopgacct";
					}
				});
				SSO.utility.setCookie('pgacct', pgacct, 30);

				$.ajax(SSO.utility.getApiUrl() + '/refreshToken?callback=?', {"dataType": "json", complete: processAuthenticationCallbacks});
			} else {
				processAuthenticationCallbacks();
			}
			
			var numPlatforms = 0;
			$.each(user.identities, function (index, value) {
				var friendlyPlatformName;

				if(value.provider == "xbl") friendlyPlatformName = "Xbox&reg; LIVE";
				else if(value.provider == "psn") friendlyPlatformName = "PlayStation&reg;Network";
				else if (value.provider == "steam") friendlyPlatformName = "PC Account";
				else if (value.provider == "nintendo") friendlyPlatformName = "Nintendo Account";
				
				if(!friendlyPlatformName) return;
				
				numPlatforms++;
				
				var className = (pgacct == value.provider) ? 'on' : 'off',
				identityOption = $('<li class="' + className + ' ' + value.provider + '" rel="' + value.provider + '">' +
					'<a href="#" rel="' + value.provider + '">' +
					'<span>' + friendlyPlatformName + '</span>' + '</a>' + '</li>');

				// platform == xbl || psn || pc || nintendo
				$("#user-identities, .sso-user-identities").append(identityOption);

				// add the identity image
				if (value.imageUrl && value.imageUrl.length) {
					identityOption.addClass('with-img');
					identityOption.prepend('<img src="' + value.imageUrl + '" class="identity-avatar"/>');
				}
			});
			
			if (numPlatforms == 1) {
				$ssoIdentityWrapper.addClass('single-identity');
				$(".sso-identities-icon").hide();
			}

			if (numPlatforms == 0) {
				$ssoIdentityWrapper.addClass('account-only');
				$(".sso-identities-icon").hide();
			}
			
			if (numPlatforms > 1) {
				$ssoIdentityWrapper.prepend('<h3 id=platform-user-name>' + user.userInfo.userName + '</h3>');
			}
		} else {
			$ssoIdentityWrapper.addClass('account-only');
			$(".sso-identities-icon").hide();
		}	
	}

	var pgacctHandler = function() {
		// change primary account
		var $doc = $(document);
		var handler = function(e) { 
			e.preventDefault();
			var userVersion;

			$("#user-identities li, .sso-user-identities li").removeClass('on').addClass('off');
			$(this).removeClass('off').addClass('on');
			
			SSO.utility.setCookie('pgacct', $(this).attr('rel'), 30);
			$.getJSON(SSO.utility.getApiUrl() + '/refreshToken?callback=?', function(d) {
				location.reload();
			});
		};

		$doc.on("click", "#user-identities .off, .sso-user-identities .off", null, handler);

		$('#menu-login-register').addClass('off').removeClass('on');
		$('#menu-identity').addClass('on').removeClass('off');
	}

	var toggleNotification = function(show, percentage) {
		var $menuItem = $('#menu-notification'),
			$count = $menuItem.find('#sso-notification-count'),
			$alert = $menuItem.find('#sso-notification-email-alert'),
			$percent = $menuItem.find('#sso-notification-profile-pecentage-alert'),
			$noAlert = $menuItem.find('#sso-notification-no-alert');
		if (show) {
			self.jQuery('#sso-notifications-dropdown').addClass('has-alerts');
			
			accountAlertCount = 1;
			$alert.show();
			$noAlert.hide();
			
			if (percentage < 100)
				$percent.show();
			else $percent.hide();
			
			//setNotificationCount(accountAlertCount);
			
		} else if (percentage < 100){
			$percent.show();
			$count.hide();
			$alert.hide();
			$noAlert.hide();
			
		} else {
			$percent.hide();
			$count.hide();
			$alert.hide();
			$noAlert.show();
		}
	}
	
	var gtmEvents = function() {
		/* START Google Tag Manager - Header Nav sign in, sign up links */
		$(document).ready(function(){
			$("#cdo-bar .sso-login-button").click(function(e) {				
	            dataLayer.push({
	                event: "event",
	                category: "navigation",
	                action: "main nav",
	                label: "Sign In"
	            });
			});
			$("#cdo-bar .sso-register-button").click(function(e) {				
	            dataLayer.push({
	                event: "event",
	                category: "navigation",
	                action: "main nav",
	                label: "Sign Up"
	            });
			});
			$("#cdo-bar .mobile-login, #cdo-bar .mobile-login a").click(function(e) {
	            dataLayer.push({
	                event: "event",
	                category: "navigation",
	                action: "main nav",
	                label: "Mobile Sign In"
	            });
			});
			$("#cdo-bar .mobile-signup, #cdo-bar .mobile-signup a").click(function(e) {
	            dataLayer.push({
	                event: "event",
	                category: "navigation",
	                action: "main nav",
	                label: "Mobile Sign Up"
	            });
			});
			$("#cdo-bar .sso-account-action-profile").click(function(e) {
	            dataLayer.push({
	                event: "event",
	                category: "navigation",
	                action: "main nav",
	                label: "Profile"
	            });
			});
			$("#cdo-bar .sso-account-action-logout").click(function(e) {
	            dataLayer.push({
	                event: "event",
	                category: "navigation",
	                action: "main nav",
	                label: "Logout"
	            });
			});
		});
		/* END Google Tag Manager - Header Nav sign in, sign up links */
	}
	
	// var setNotificationCount = function(c) {
	// 	$count = $container.find('#sso-notification-count');
	// 	if(c > 0) {
	// 		$count.html("" + c);
	// 		$count.show();
	// 	} else {
	// 		$count.html("0");
	// 		$count.hide();
	// 	}
	// };
	
	// self.setClientNotificationCount = function(c) {
	// 	setNotificationCount(accountAlertCount + c);
	// };

	/* Public */
	// TODO: Audit the rest of the public functions to see what actually needs to be public
	self.initialize = function () {
		SSO.utility.log("** SSO.initialize() **");
		// check for css load
		SSO.csrf.init();
		initCSS();
		attachBarToDom();
		getBarHtml();
		gtmEvents();
	};
	
	self.verifyAccountLinked = function (accountName) {
		var hasAccount = false;
		
		if(self && self.user && self.user.identities.length > 0) {
			$.each(self.user.identities, function () {
				if (this.provider == accountName && this.authorized == true)
					hasAccount = true;
			});
		}
		
		return hasAccount;
	};

	self.showNotification = function (percentage) {
		toggleNotification(true, percentage);
	};
	self.hideNotification = function (percentage) {
		toggleNotification(false, percentage);
	};

	// Determine the locale of this page
	self.getLocale = function () {
		SSO.utility.log("*** SSO.Bar.getLocale() ***");
		var locale;

		locale = siteConfig.locale || SSO.utility.getCookie('ACT_SSO_LOCALE') || 'en_US';
		
		SSO.utility.log("**** Locale is: " + locale);
		return locale;
	};
	
	self.getLocaleCountry = function (localeCode) {
		if (localeCode) {
			localeCodeArray = localeCode.split("_");
			if (localeCodeArray.length > 1) {
				return localeCodeArray[1];
			}
		}
		return "US";
	};

	self.doProfilePath = function () {
		if(self.config.profileUrlBase) return SSO.utility.getBaseUrl() + self.config.profileUrlBase + '/profile' + self.buildQueryString(false);
		return aUrl + '/profile' + self.buildQueryString(false);
	};

	self.getFacebookPath = function () {
		return apiUrl + '/facebookconnect.act?redirectUrl=login';
	};

	self.getForgotPasswordUrl = function () {
		if (self.config.siteFlow == 'child') {
			return SSO.utility.getApiUrl() + '/childForgotPassword';
		} else {
			return 'forgotPassword';
		}
	};

	self.getChangeOrResendEmailUrl = function() {
		return aUrl + '/emailHelp';
	};
	
	self.getCompleteProfileUrl = function() {
		if(self.config.profileUrlBase) return SSO.utility.getBaseUrl() + self.config.profileUrlBase + '/profile';
		return aUrl + '/profile';
	};

	self.getSignupUrl = function() {
		return aUrl + '/register' + self.buildQueryString(true);
	};

	self.getLoginUrl = function() {
		return aUrl + '/login' + self.buildQueryString(true);
	};
	
	self.getLogoutUrl = function() {
		return SSO.utility.getApiUrl().replace("/" + self.config.communityId, "") + "/do_logout?" + new Date().getTime();
	};
	
	self.getSupportUrl = function() {
		var supportUrl = self.config.supportUrl;
		if(self.config.customSupportPath) {
			supportUrl = (self.config.supportUrlBase + self.config.customSupportPath).replace(/([^:]\/)\//, "$1");
		}
		if(self.config.enableDynamicSupportLinks == "enable") {
			supportUrl += (supportUrl.indexOf("?") < 0 ? "?" : "&") + "uil=" + self.locale;
			if(self.user.isLoggedIn) {
				var supportUrlBase = self.config.supportUrlBase || "";
				var index = supportUrl.indexOf(supportUrlBase); 
				if(index >= 0) supportUrl = supportUrl.substr(index + supportUrlBase.length);
				else supportUrl = "/?uil=" + self.locale;
				supportUrl = aUrl + "/supportAuthentication?RelayState=" + escape(supportUrl);
			}
		}
		return supportUrl;
	};

	self.isCommunityPage = function () {
		var currentUrl = window.location.href;
		if (currentUrl.indexOf("community") > -1 && currentUrl.indexOf("callofduty.com") > -1) {
			return true;
		} else {
			return false;
		}
	};

	self.buildQueryString = function (redir) {
		var newParams = [],
			str = '';

		redir = typeof redir == 'undefined' ? true : redir; //add redirect by default
		if (redir) {
			var redirectUrl = self.getRedirectUrl();
			if(redirectUrl.length)
				newParams.push(redirectUrl);
		}

		if (newParams.length) {
			str = '?';
			for (var i = 0; i < newParams.length; i++) {
				str += i > 0 ? '&' + newParams[i] : newParams[i];
			}
		}

		return str;
	};
	
	self.getRedirectUrl = function () {
		
		var redirectAllowed = false;
		
		if(SSO.utility.urlParameters['redirectUrl']) {
			return "redirectUrl="+SSO.utility.urlParameters['redirectUrl'];
		}
		
		if(self.config.validRedirects) {
			for (var h=0; h < self.config.validRedirects.length; h++) {	
				if((window.location.hostname).match(self.config.validRedirects[h]))
					redirectAllowed = true;
			}
		}
		
		if(!redirectAllowed) {
			SSO.utility.log("Hostname not present in redirect list");
			return "";
		}
		
		SSO.utility.log("Hostname present in redirect list");
		
		if(self.config.isSSOPage) {
			
			SSO.utility.log("Redirects suppressed for SSO-served pages");
			return "";
		}
	
		var redirectUrl = "redirectUrl=" + encodeURIComponent(window.location.href);
		
		return redirectUrl;
	};

	self.getSecureUrl = function (url) {
		var hostname = location.hostname;
		if (hostname.indexOf('localhost') === 0 || hostname === '127.0.0.1') {
			return url;
		} else {
			return url.replace("http://", "https://").replace("8080", "8443");
		}
	};

	self.getUrlWithCurrentProtocol = function (url) {
		if (window.location.href.indexOf('https') > -1) {
			if (!SSO.utility.urlParameters["forceHttp"]) {
				return url.replace('http', 'https');
			}
		}
		return url;
	};

	self.processConfig = function () {
		self.config = $.extend(self.config, self.siteConfig);

		if (!self.siteConfig)
			self.siteConfig = {};
		
		if(!SSO.utility.getCookie("new_SiteId")) 
			SSO.utility.setCookie("new_SiteId", self.config.communityId , "");
		
		if (!self.siteConfig.siteId)
			self.siteConfig.siteId = SSO.utility.getCookie("new_SiteId");
		
		SSO.utility.setCookie("new_SiteId", self.siteConfig.siteId);
		$.ajax({
			url: aUrl + '/script/siteConfig/' + (self.locale ? "loc_" + self.locale : "default"),
			async: false,
			cache: true,
			dataType: 'jsonp',
			jsonp: false,
			jsonpCallback: 'siteConfig',
		
			success: function (returnObject) {
				// We're no longer sending pure JSON across, so we need to rebuild a couple of objects
				
				if(!self.config.overwriteLocaleList)
					returnObject.locales = self.splitLocales(returnObject.supportedLocales);
				else
					returnObject.locales = self.splitLocales(self.config.overwriteLocaleList);

				returnObject.exploreUrl = self.splitExploreLinks(returnObject.links);
		
				self.config = $.extend(self.config, returnObject);
				self.config = $.extend(self.config, self.siteConfig);
		
				SSO.utility.log(self.config);
				
				self.initialize();
			},
			error: function (d) {
				SSO.utility.log("ERROR GETTING config.js");
				SSO.utility.log(d);
				self.initialize();
			}
		});
	};
	
	self.splitLocales = function (jsonString) {
		
		var entries = jsonString.split(/\|/);
		var returnObject = {};
		
		for(var i =0; i< entries.length; i++) {
			var attributes = entries[i].split(/\%/);
			 if(attributes.length >= 2) {
				returnObject[attributes[0]] = {};
				returnObject[attributes[0]].title = (attributes[1]);
				if(attributes[2])
					returnObject[attributes[0]].cms = (attributes[2]);
			 }
		}
		
		return returnObject;
	};

	self.splitExploreLinks = function (jsonString) {
		
		var entries = jsonString.split(/\|/);
		var returnObject = [];
		
		for(var i =0; i< entries.length; i++) {
			var attributes = entries[i].split(/\%/);
			var linkProperties = {};
			linkProperties.title = attributes[0];
			linkProperties.href =  attributes[1];
			returnObject.push(linkProperties);
		}	
		
		return returnObject;
	};
	
	// TODO: Make this object private & rename so it's no longer
	// 		 extended with the user defined config object
	self.config = {
		debug: false,
		fixed: false,
		modal: true,
		autoRender: true,
		containerId: 'SSO-BAR',
		menuType:'buttons',
		initBarStyles: {
			'display': 'none',
			'height': '40px'
		},
		jQuery: 'https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js',
		headjs: 'scripts/head.js',
		css: ['styles/sso-bar.css', 'styles/sso-bar-base.css', '../%SITE%/styles/sso-bar-custom.css'],
		locales: {
			'en': {
				'url': '?lang=en'
			}
		},
		userLoaded: function() {},
		constants: {
			// Old locales: For backward compatibility
			OLD_LOCALES: {
				'au': {
					'label': 'Australia',
					'newCode': 'en_AU'
				},
				'ca-en': {
					'label': 'Canadian English',
					'newCode': 'en_CA'
				},
				'ca-fr': {
					'label': 'Canadian French',
					'newCode': 'fr_CA'
				},
				'de': {
					'label': 'Germany',
					'newCode': 'de_DE'
				},
				'en': {
					'label': 'United States',
					'newCode': 'en_US'
				},
				'es': {
					'label': 'Spain',
					'newCode': 'es_ES'
				},
				'fr': {
					'label': 'France',
					'newCode': 'fr_FR'
				},
				'it': {
					'label': 'Italy',
					'newCode': 'it_IT'
				},
				'uk': {
					'label': 'United Kingdom',
					'newCode': 'en_GB'
				}
			}
		}
	};
	
	var tryPersonalize = function(personalizeFunction) {
		if(self.user && self.user.isLoggedIn) {
			if(userInfoLoaded && dictionaryLoaded && !personalizeBarCalled) {
				personalizeFunction();
			}
		} else {
			if(dictionaryLoaded && !personalizeBarCalled) 
				personalizeFunction();
		}
	};
	
	var ssoFinish = function() {
		ssoIsReady = true;
		displaySSOBar();
		processReadyCallbacks();
	};
	
	var readyCallbacks = []; 
	var authenticationCallbacks = [];  
	var ssoIsReady = false;
	var authDetermined = false;
	
	var processReadyCallbacks = function() {
		while(readyCallbacks.length) {
			(readyCallbacks.shift())();
		}
	};
	self.onReady = function(callback) {
		if(ssoIsReady) callback();
		else readyCallbacks.push(callback);
	};
	
	var processAuthenticationCallbacks = function() {
		authDetermined = true;
		while(authenticationCallbacks.length) {
			(authenticationCallbacks.shift())(self.user);
		}
	};
	
	self.onAuthentication = function(callback) {
		if(authDetermined) callback();
		else authenticationCallbacks.push(callback);
	}; 
	
	self.menuOpen = null;

	self.siteConfig = siteConfig;
	// self.config = SSO.utility.merge(self.config, self.siteConfig, true);
	self.locale = self.getLocale();
	// make sure dependancies are in place
	initScripts();

	var promotionCode = SSO.utility.urlParameters['pc'];
	if (promotionCode != "") {
		SSO.utility.setCookie("pc", promotionCode);
	}
};

