// Set to true to see debugging information in FireBug console
var DEBUG = false;
var HOSTS = {
				production: 'tigerwoodsonline.ea.com'
            };


//Major version of Flash required
var requiredMajorVersion = 9;
//Minor version of Flash required
var requiredMinorVersion = 0;
//Minor version of Flash required
var requiredRevision = 124;

var msie6;

var warnActive = false;

// common reused xml
var coursesXml = null; // common global data used elsewhere

// flag to have us only check if the guy is a new user once per page
var firstTimeUserChecked = false;

// player session data
var characterProgressionTableXML = '';
var myPlayerCardXML = '';
var playerLevel   = 0;
var playerCutLine = 0;
var playerCashBalance = 0;
var userMoney = 0;

// active game data for this session
var activeGameId = -1;
var activeTournamentRoundId = -1;
var activeTournamentId = -1;
var isActiveGameMultiplayer = -1;
var isActiveGameTournament = -1;

// Constants
var MAX_LARGE_PERSONA_CHAR_COUNT = 14;

//Should try and have as few ready functions as possible
//Checks cookie for authentication then calls the appropriate pageReady function
$(document).ready( function() {
	msie6 = $.browser.msie && parseInt($.browser.version) == 6 && !window["XMLHttpRequest"];
    //Warns if not compatible, only once
    checkBrowserCompatibility();
    setupScrollToTop();
    playbtn_setup ();
	setupProfileAccordion();
    setupTabs();
    checkAuthentication();
    setupNav();
	setupSubNav();
	
	setupModalWindow(); // in modals.js -> ! please deprecate
	modal_setup(); // in modals.js -> ! please deprecate
	
	setupPageFTUF();
	
	//setupSlider();
	
    setupNotifyListener();
    
    // Function: $.find
    //  Overrides jQuery's find method to log an error if
    //  the selector returns no results. The logging requires a
    //  FireBug console.
    if ((DEBUG === true) && (location.host !== HOSTS.production)) {
        (function ($) {
            var oldfind = $.fn.find;

            $.fn.find = function(sel){
                var ret = oldfind.call(this,sel);

                if (ret.length === 0) {
                    if (window.console) {
                        if (window.console.warn) {
                            console.warn('jQuery Selector \'' + sel.toString() + '\' found nothing.');
                        }
                    }
                }

                return ret;
            }

        }) (jQuery);
    }
});

// ======================================================================
// Push Notifications
// TODO: put in more common js since game window doesn't include globals.js, maybe notifications.js?
//======================================================================

/**
 * This handles push notifications for the site coming from the push notification system
 */
function setupNotifyListener( )
{	
	startListeningForNotifications(50, // poll every 50 seconds 
        (function(data) 
        {
        	var appName = $("appName", data).text();
        	var service = $("service", data).text();
        	var serviceType = $("servicetype", data).text();

        	var sourceName = $("sourceName", data).text();
        	var sourceId = $("sourceId", data).text();
        	var destName = $("destName", data).text();
        	var destId = $("destId", data).text();
        	
        	if (service == 'presence')
        	{
        		if (serviceType == 'update')
        		{	
        			// if the message is empty, fill something in.
        			// i don't want to hard code the franchise name here, but i may have to
        		    if ($("payload message", data).text() == '')
        		    {
        		    	$("payload message", data).text('Logged in');
        		    }
        			
        			$(document).trigger('presence.update', {
        					personaId : parseInt( $("payload personaid", data).text() ),
        					persona : $("payload persona", data).text(),
        					franchise : $("payload franchise", data).text(),
        					message : $("payload message", data),
        					webStatus : parseInt( $("payload webstatus", data).text() ),
        					gameStatus : parseInt( $("payload gamestatus", data).text() ),
							venueId : $("payload venueid", data).text() 
        			});
        		}
        	}
        	else if (service == 'invitation')
        	{
        		// new invite!
        		if (serviceType == 'invite')
        		{
        			// add a new row dynamically to the top
        			var inviteId = parseInt($("payload id", data).text());
        			
        			// view/decline
					var gameId = parseInt($("gameId", data).text());
					var slotNum = parseInt($("slot", data).text());
					var viewDetailsFunction = 'odbHandleViewDetails(' + inviteId + ')';
					var declineFunction = 'odbHandleDeclineInvite(' + inviteId + ',' + gameId + ',' + slotNum + ')';
					
					var holesStr = getHoleSelectionDisplay(parseInt($("holestoplay", data).text()));
					var courseName = $("coursename", data).text();
					var gameDesc = '<div class="odbBoxMessage"><a class="profileName" href="/profiles/' + sourceName + '">' + sourceName + '</a> has invited you to play ' + holesStr + ' on ' + courseName + '</div>';
					
					$('#odbGameInvitesPanel .newBoxItem').removeClass('newBoxItem');
					if ($('#odbGameInviteListItem'+inviteId).length == 0)
					{
						var row =
							'<li id="odbGameInviteListItem' + inviteId + '" class="newBoxItem">\
							<div class="profileThumb"><a href="/profiles/' + sourceName + '"><img src="/players/avatarsbyid/' + sourceId + '"/></a></div>' + gameDesc + '\
								<div class="itemActions">\
									<a class="gradient_button" onclick="' + viewDetailsFunction + '"><span class="text">View Details</span></a>\
									<a class="gradient_button" onclick="' + declineFunction + '"><span class="text">Decline</span></a>\
									</div>\
							</li>';
						$('#odbGameInvitesList').prepend(row);
					}
					
					// remove any empty box row, and show the read all button
					$('#odbGameInvitesNub .emptyBoxItem').remove();
					$('#odbGameInvitesNub .odbBoxReadAll').show();
					
					// update the count
					var total = parseInt($("#game-invite-count").text()) + 1;
					$("#game-invite-count").addClass('showCounter').html(total).show();
					$('#odbGameInvitesNub .odbBoxReadAll').show();
					
					// pop open messages tab in bar
	    			$("#odbGameInvitesPanel").fadeIn('slow');
        		}
        		// inviter notification of invitee accepted/declined
        		else if ((serviceType == 'accept' || serviceType == 'decline') && sourceId != destId)
   				{
        			/*var text = "Unknown";
        			switch (serviceType)
        			{
        			case 'accept':
       					text = '<a class="profileName" href="/profiles/' + sourceName + '">' + sourceName + '</a>\ accepted your invite.';
        				break;	
        			case 'decline':
       					text = '<a class="profileName" href="/profiles/' + sourceName + '">' + sourceName + '</a>\ declined your invite.';
        				break;	
        			}
        			
        			var inviteId = parseInt($("payload id", data).text());
        			if ($('#odbGameInviteListItem'+inviteId).length == 0)
					{
	        			var row =
							'<li id="odbGameInviteListItem' + inviteId + '" class="emptyBoxItem">\
	        					<div class="profileThumb"><a href="/profiles/' + sourceName + '"><img src="/players/avatarsbyid/' + sourceId + '"/></a></div>\
	       					 	<div class="odbBoxMessage">' + text + '</div>\
	       					 </li>';
	        			$('#odbGameInvitesList').prepend(row);
					}
        			
					// set for the notification to disappear in a few sec
					setTimeout('hideODBItem("' + '#odbGameInviteListItem'+inviteId + '")', 5000);
					
        			// pop open messages tab in bar
        			$("#odbGameInvitesPanel").fadeIn('slow');*/
        			
   				}        			
        		// invite going away (or notification we accepted/declined to ourselves e.g. in unity)
        		else if (serviceType == 'cancel' || serviceType == 'expire' || serviceType == 'accept' || serviceType == 'decline')
        		{
        			var text = "Unknown";
        			switch (serviceType)
        			{
        			case 'cancel':
        				text = '<a class="profileName" href="/profiles/' + sourceName + '">' + sourceName + '</a> has removed you from the round.';
        				break;
        			case 'expire':
        				text = '<a class="profileName" href="/profiles/' + sourceName + '">' + sourceName + '</a>\'s invite has expired.';
        				break;
        			case 'accept':
        				var inviterName = $("payload inviteePersona", data).text();
       					text = 'You\'ve accepted <a class="profileName" href="/profiles/' + inviterName + '">' + inviterName + '</a>\'s invite.';
        				break;	
        			case 'decline':
        				var inviterName = $("payload inviterPersona", data).text();
       					text = 'You\'ve declined <a class="profileName" href="/profiles/' + inviterName + '">' + inviterName + '</a>\'s invite.';
        				break;	
        			}
        			
        			var inviteId = parseInt($("payload id", data).text());
        			$('#odbGameInviteListItem'+inviteId).attr('class', 'emptyBoxItem inviteCanceled'); 
        			$('#odbGameInviteListItem'+inviteId).html(
        					'<div class="profileThumb"><a href="/profiles/' + sourceName + '"><img src="/players/avatarsbyid/' + sourceId + '"/></a></div>\
       					 	<div class="odbBoxMessage">' + text + '</div>'
        					);
        			
        			// update the count
        			var total = parseInt($("#game-invite-count").text());
        			if (serviceType == 'cancel' || serviceType == 'expire' || sourceId == destId) // cancel, expire, or an echo back take our count down
        			{
        				total--;
        			}

					if( total > 0 )
					{
						$("#game-invite-count").addClass('showCounter').html(total).show();
						$('#odbGameInvitesNub .odbBoxReadAll').show();
					} 
					else  
					{
						$("#game-invite-count").html(total).hide().removeClass('showCounter');
						
						// if empty row isn't there already, add it
						if ($('odbGameInvitesList li.emptyBoxItem').length == 0)
						{
							var emptyRow = '<li class="emptyBoxItem"><p>You have no game invites</p><a href="/play/playRedirect/0/multiplayer/1/" class="gradient_button"><span class="text">Create a Game</span></a></li>';
							$('#odbGameInvitesList').append(emptyRow);
						}
						else
						{
							$('odbGameInvitesList li.emptyBoxItem').show();
						}
						$('#odbGameInvitesNub .odbBoxReadAll').hide();
					}
					
					// set for the notification to disappear in a few sec
					setTimeout('hideODBItem("' + '#odbGameInviteListItem'+inviteId + '")', 5000);
					
        			// pop open messages tab in bar
        			$("#odbGameInvitesPanel").fadeIn('slow');
        		}
        	}
        })
    );

}

function hideODBItem(rowId)
{
	$(rowId).fadeOut('slow', function() { $(this).hide(); });
}


var notifyTimeout ;
var notifySuccessFunc ;
var notifyFailureCount = 0;
var notifyMaxFailures = 6;
var notifyFirstTime = true;
function startListeningForNotifications( timeout, success)
{
    notifySuccessFunc = success;
    notifyTimeout = timeout;
    if( notifyFirstTime ){
        // wait some time before kicking this off
        notifyFirstTime = false;
        setTimeout( "startListeningForNotifications( notifyTimeout, notifySuccessFunc)", 10 * 1000 );
        return;
    }
    if( personaId != undefined ){
        var urlString = "/webservices/notification_ext/getNotification/" + personaId + "/" + timeout ;
        $.ajax({ 
                type: "GET",
                    url: urlString,
                    error: function(XMLHttpRequest, textStatus, errorThrown) 
                    {
        				// just keep going
                    	notifyFailureCount++;
                    	if( notifyFailureCount < notifyMaxFailures )
                    	{
                    		setTimeout( "startListeningForNotifications( notifyTimeout, notifySuccessFunc)", timeout );
                    	}
                    },
                    success: function(data, textStatus)
                    {
	                    if( $(data).find("timeout").length != 0 )
	                    {
	                        // no result found do it again
	                        
	                    	// either way - we need to check for more notifications
	                        setTimeout( "startListeningForNotifications( notifyTimeout, notifySuccessFunc)", 1 );
	                    }
	                    else if ($(data).find("notification").length != 0 )
	                    {
	                        // got it, pass to success function
	                        success( data );
	                        
	                        // either way - we need to check for more notifications
	                        setTimeout( "startListeningForNotifications( notifyTimeout, notifySuccessFunc)", 1 );
	                    }
	        			// no notification data, possibly some bad error (404 e.g.), stop processing entirely & alert
	        			else
	        			{
	        				// FIXME: find another way to indicate that system is down.
	        				// eaAlert('The website is currently undergoing issues with the notification system.', 'Failed to retrieve push notifications');
	        			}
	        		}
        });
    }
    
}

//======================================================================

//Function: Setup the Play Now Button
function playbtn_setup () {
	
	/*
	var criticalflow = window.location.href;

	if(criticalflow.match('/play') || criticalflow.match('/tournaments')) {
		$('#PlayNow').removeClass().addClass('status_setup');
		$('#PlayNow a').attr('href','#');
	}
	if(criticalflow.match('/play/resumeGame')) {
		$("#PlayNow").removeClass().addClass("status_resume");
		$('#PlayNow a').attr('href','#');
	}
	if(criticalflow.match('/play/ingame')) {
		$("#PlayNow").removeClass().addClass("status_ingame");
		$('#PlayNow a').attr('href','#');
	}	
	
	//If you are on a course's detail page and select "play now", preselect that course
	try
	{
		if(courseId != undefined && (criticalflow.match('/courses') || criticalflow.match('/myProfile/objectives')))
		{
			$("#PlayNow a").attr("href", "/play/playRedirect/" + courseId);
		}
	}catch(err){}
	*/

    $("#PlayNow a").click(function(){
		teeOff();		
	});
	
}

function showForfeitRoundModal (callback, callbackParameters) {
	showGameModal({
		icon: '/img/placeholder/empty_points.png', 
		title: "Forfeit Round and Tee Off", 
		prompt: "You currently have a round in progress. If you purchased this round with points, it will be lost. Do you want to forfeit your current round?",
		actionTitle: "Forfeit and Tee Off",
		actionCallback: callback,
		actionCallbackOptions: callbackParameters
	});	
}

function showGameModal (options) {
	var deIcon = "";
	var deTitle = "";
	var dePrompt = "";
	var deActionTitle = "";
	var deActionCallbackOptions = null;
	
	if (typeof(options) === 'object') {
		deIcon = options.icon;
		deTitle = options.title;
		dePrompt = options.prompt;
		deActionTitle = options.actionTitle;
		deActionCallback = options.actionCallback;
		deActionCallbackOptions = options.actionCallbackOptions;
	}
	
	//set display to block and opacity to 0 so we can use fadeTo
	$('#mask').css({ 
		'display' 	: 'block',
		'position'	: 'fixed',
		opacity 		: 0
	});
	
	//fade in the mask to opacity 0.8
	$('#mask').fadeTo(500,0.6);
		
	$('#groupModal').appendTo(document.body);
	
	$("#groupModalIcon > img").attr("src", deIcon);
	$('#groupModalTitle').text(deTitle);
	$('#groupModalPrompt').text(dePrompt);
	$('#groupModalAction .text').text(deActionTitle);
	
	$('#groupModalAction').unbind();
    $('#groupModalAction').click( function () {
        if(deActionCallback != null) {
        	if (deActionCallbackOptions != null) {
        		deActionCallback.apply(this, deActionCallbackOptions);
        	} else {
        		deActionCallback.apply(this);
        	}
        }
    	close_modal();
    });
	
	//show the modal window
	$('#groupModal').fadeIn(500);
}

function teeOff() {
	callPlayGameOptions('normal');
}

// Function: UnityLog
//  This is here to bypass UnityLog related error messages
//  that are called from the Unity IDE. Without this empty function,
//  a JS error will be generated evey time UnityLog is called (which is dozens
//  of times per action in Unity. LEAVE THIS! :)
function UnityLog (str) { return false; }


/* Function: show
 *  Modified the jquery show() method, allowing you to pass CSS
 *  argument as either strings, or a map.
 *
 *  Parametes:
 *      optional - 2 strings specifying a key/value CSS pair,
 *                 or a Hash of one or more key/value pairs for the
 *                 resulting CSS.
*/
//(function($){
//	var oldShow = $.fn.show;
//
//	$.fn.show = function () {
//		oldShow.call(this);

//        if (arguments.length === 2) {
//            $(this).css(arguments[0], arguments[1]);
//        } else if (arguments.length === 1 && typeof(arguments[0]) === 'object') {
//            $(this).css(arguments[0]);
//        }
//	}
//})(jQuery);


/*====Authentication=========================*/
/* Function: submitLogin
 *  Submits the login form.
 */
function submitLogin()
{
    document.loginForm.submit();
}

/* Detect enter key on login form and call submitLogin if it is pressed: */
$('#loginForm').keyup(function (e) {
    if ( (e.which === 13) || (e.keyCode && e.keyCode === 13)) {
        submitLogin();
    }
});

$('#passwordField_decoy').focus(function () {
     $(this).remove();
     $('#passwordField').show();
     $('#passwordField').focus();
});

function checkAuthentication()
{
    //Check for authentication and session and persona
    var authCookie    = getCookie("CEM-login");
    var objEmailField = $('#emailField');

    if(authCookie==null || authCookie=="")
    {
        $(".state_guest").show();
        $(".state_subscriber").hide();

        // fill in remembered data if data is set...
	    var rememberedEmail = getCookie("TWOCookie[REMEMBER]");
	    if (rememberedEmail != null) {
	        $("#emailField").attr("value", unescape(rememberedEmail));
	        $("#rememberMeCheckBox").attr("checked", true);
	    } else {
            // Do not change email field for alt login page:
            if (!location.toString().match(/.*viewAltLogin.*/)) {

               objEmailField.focus();

               if (objEmailField.select) {
                   objEmailField.select();
               }

               $("#passwordField_decoy").attr("value", "Password");
            }
            $("#rememberMeCheckBox").attr("checked", false);
	    }

        try
        {
            pageReadyGuest();
        }
        catch(er)
        {
        	// expected for pages that don't override pageReadyGuest
        }
    }
    else
    {
    	// need to also check for persona before showing user data
    	loadPersonaCookie(); // sets global var for name/id

    	// persona info is missing, redirect to persona creation flow if not already there (do not showed logged in data yet)
    	if (personaId == undefined || personaId == null || personaId == "")
    	{
    		// if not already on the no persona flow, go there
    		var onPersonaPage = (location.pathname == '/newuser/nopersona');
    		if (!onPersonaPage)
    		{
    			document.location = '/newuser/nopersona';
    		}
    		else
    		{
    			// on persona page, how guest view
    			$(".state_guest").show();
    	        $(".state_subscriber").hide();
    		}
    	}
    	else
    	{
	    	//TODO: need more validation than this - Can we check a webservice against this cookie?
	        $(".state_guest").hide();
	        $(".state_subscriber").show();

	        $(".needsSubNav").addClass("hasSubNav");

	        // load courses for dropdown when logged in only
	        setCourseMenuItems();

			 // async load player card like walllet balance
		    loadPlayerCard();
			
			// Top-bar drop downs
			setupTopNav();
			
			// Entitlement Banners
			entitlementBanners();

	        //setup the event fire everytime the game window receives focus
	        $(window).bind("focus", function(){
	            if(canRefreshData){
	                updateCanRefreshData(false);
	                try  {
	                	// common layout refreshes
	                    refreshLayoutData();
	                } catch(ex){}
	                try{
	                    // page specific refreshes
	                    refreshPageData();
	                } catch(ex){}
	                setTimeout("updateCanRefreshData(true)", 5000);
	            }
	        });
    	}

    	try
    	{
            pageReadyUser(); // tell the web page we are ready
        }
    	catch(er)
    	{
        	// expected for pages that don't have a custom pageReadyUser handler (e.g. nounity)
        }
    	
    	setupToolTips();
    	
    	// allow refer a friend functionality on every page
    	$(".refer_a_friend").unbind();
		$(".refer_a_friend").click(popupInviteFriendsByEmail);
    	
    	try
    	{
			pageReadyBar(); // tell ODB we are ready too
        }
    	catch(er)
    	{
        	// expected for pages that don't have the ODB (e.g. membershipOffer)
        }
    }
}

function popupInviteFriendsByEmail()
{
	window.open('/referrals/sendEmail', 'referAFriendWindow','toolbar=0,menubar=0,statusbar=1,resizable=1,scrollbars=1,width=625,height=400');
	return false;

}
var canRefreshData = true;
function updateCanRefreshData(newFlag){
    canRefreshData = newFlag;
}

function logoutOfSite(){
    var url = location.protocol + '//' + location.host + "/users/logout?surl=" + document.location;
	document.location = url;
}

/*====Compatability========================*/
function checkBrowserCompatibility() {
    var msgIE6  = "Using Internet Explorer 6 or earlier may cause adverse effects on gameplay and is not fully supported by Tiger Woods PGA TOUR&reg; Online";
    var msgChrome = "Using Chrome may cause adverse effects on gameplay and is not fully supported by Tiger Woods PGA TOUR&reg; Online";
    var msgOpera  = "Using Opera may cause adverse effects on gameplay and is not fully supported by Tiger Woods PGA TOUR&reg; Online";
    var msgff2 = "Using Firefox version 2 or lower may cause adverse effects on gameplay and is not fully supported by Tiger Woods PGA TOUR&reg; Online. Please upgrade to the latest version of <a href=\"http://www.mozilla.com/en-US/\"  target=\"_blank\">Firefox</a>";

    if(getCookie("TWOCookie[warning]") == null) {
        if (msie6)	
        {
            setCookie('TWOCookie[warning]','true','Fri, 1 Jan 2100 20:00:00 UTC');
            eaAlert(msgIE6);
        } 
        else if($.browser.chrome) 	
        {
            setCookie('TWOCookie[warning]','true','Fri, 1 Jan 2100 20:00:00 UTC');
            eaAlert(msgChrome);
        } 
        else if($.browser.opera) 	
        {
            setCookie('TWOCookie[warning]','true','Fri, 1 Jan 2100 20:00:00 UTC');
            eaAlert(msgOpera);
        } 
        else if ($.browser.mozilla && $.browser.version.indexOf('1.8.') > -1) 
        {
            setCookie('TWOCookie[warning]','true','Fri, 1 Jan 2100 20:00:00 UTC');
            eaAlert(msgff2);
        }
    }
}

/*====Setups===============================*/


function setupDirectedExperience(options)
 {
	var deIcon = "";
	var deTitle = "";
	var deDescription = "";
	
	if (typeof(options) === 'object') {
		deIcon = options.icon;
		deTitle = options.title;
		deDescription = options.description;
	}
	
	$("#userMasthead .page_image .icon").addClass(deIcon);
	$("#userMasthead .page_title h1").html(deTitle);
	$("#userMasthead .page_title h5").html(deDescription);
}


function setupToolTips() 
{

    var toolTip = $("a.tooltip");

    toolTip.hover(

        function() {

            toolTipInfo = this.rel;

            $("body").append("<div class='tooltip-wrapper'><div class='tooltip-copy'>" + toolTipInfo + "</div><div class='arrow'></div></div>");

            $(".tooltip-wrapper").width((toolTipInfo.length * 6)+30);

            var x_toolTip = ($(this).offset().left);
            var w_toolTip = ($(this).width());
            var w_wrapper = ($('.tooltip-wrapper').width());

            var xOffset = ((x_toolTip+w_toolTip)-((w_toolTip + w_wrapper)/2));
            var yOffset = ($(this).offset().top - 35);

            $(".tooltip-wrapper").hide();
            $(".tooltip-wrapper").show();
            $(".tooltip-wrapper").css({
                'position' : 'absolute',
                'left' : '' + xOffset + 'px',
                'top' : '' + yOffset + 'px',
                'z-index' : '9990'
            });

        },
        function() {
            $(".tooltip-wrapper").remove();
        }
        );


}

function setupNav()
{
	try
	{
		$("#main_nav li a").removeClass("selected");
		switch(pageTitle)
		{
			case "Home":
				$("#main_nav .home a").addClass("selected");
				break;
			case "Profile Overview":
			case "Achievements":
			case "Profile Statistics":
			case "Prestige":
				$("#main_nav .my_golfer a").addClass("selected");
				break;
			case "Friends":
			case "Find New Friends":
			case "The Cut":
			case "Sponsorships":
				$("#main_nav .friends a").addClass("selected");
				break;
			case "Groups":
			case "Edit Group":
			case "Create a Group":
			case "Group Profile Overview":
			case "Group Profile Members":
			case "Group Profile Leaderboards":
			case "Group Current Tournament":
			case "Group Previous Tournament":
			case "Create Group Tournament":
			case "Create Group Season":
				$("#main_nav .groups a").addClass("selected");
				break;
			case "Leaderboards":
			case "Group Leaderboards":
			case "Leaderboards Course":
			case "Leaderboards Friends":
				$("#main_nav .leaderboards a").addClass("selected");
				break;
			case "Courses":
				$("#main_nav .courses a").addClass("selected");
				break;
			case "Game Guide":
				$("#main_nav .gameguide a").addClass("selected");
				break;
		}
	}catch(err){}
}

function setupSubNav()
{
	var timer;

	$('.hasSubNav').parent().hover(
		function() {
			hideUnity();
		},
		function() {
			showUnity();
		});

	$('#main_nav li').hover(
		function() {
			var subNav = $(".wrapper", this);
			if(timer) {
				clearTimeout(timer);
				timer = null
			}
			timer = setTimeout(function() {
				subNav.show();
			}, 200);
		},
		function() {
			if(timer) {
				clearTimeout(timer);
				timer = null
			}
			$(".wrapper", this).hide();
		}
	);
}

function setupTopNav() {
	$('.top-bar li.toggle').hover(
	function() {
		$(this).find('ul').show();
		$(this).addClass('over');
	},function() {
		$(this).find('ul').hide();
		$(this).removeClass('over');
	});
	
	var subscriptionCookie = unescape(getCookie("TWOCookie[SUBSCRIPTION]"));
	//setup Accountmanagement Link
	var returnUrl = URLEncode( document.location.toString() );
	
	if(!ignoreSubscriptions)
	{		
		if(subscriptionCookie.indexOf("freetoplay") >= 0)
		{
			$('#OnDemandBar .user_account_standing').text('Free Account');
			if (typeof(lockBoxSubsPath) !== 'undefined')  
			{
				$("a.lockboxAccountManagementLink").unbind();
				$("a.lockboxAccountManagementLink").click(function()
				{
					//document.location = "/users/membershipOffer?returnUrl=" + returnUrl;
					var newWindow = window.open("/users/membershipOffer?returnUrl=" + returnUrl, '_blank');
					newWindow.focus();
				});
		    }
		}
		else 
		{
			if(subscriptionCookie.indexOf("tigerUnlimited") >= 0)
			{
				$('#OnDemandBar .user_account_standing').text('Employee');	
			}
			else
			{
				$('#OnDemandBar .user_account_standing').text('Member');
			}
			
			if (typeof(lockBoxBillingPath) !== 'undefined')  
			{
				$("a.lockboxAccountManagementLink").unbind();
		        $("a.lockboxAccountManagementLink").click(function()
		        {
		        	//document.location = "/users/manageSubscriptionRedirect?surl=" + returnUrl;
		        	var newWindow = window.open("/users/manageSubscriptionRedirect?surl=" + returnUrl, '_blank');
					newWindow.focus();
		        });
			}
		}		
	}
	// sub checking disabled
	else
	{
		$('#OnDemandBar .user_account_standing').text('Member');
		
		$(".i_accountmanagement").hide();
		$(".card_actions .round_count").hide();
	}
	

    
}

function directedExperienceBar () {
	$('#directed_experience li a').hover(
	function() {
		$(this).parent('li').addClass('hover');
	}, function() {
		$(this).parent('li').removeClass('hover');
	});

}


// Function: setupSlider()
// Global slider component for featured items and banners 
function setupSlider()
{
	
	if($("#Slider").length > 0) {
		
		// Setting up sizes and other variables
		var slider_width 	= $("#Slider").width();
		var panels			= $("#Slider .panels > li");
		var panels_total 	= $("#Slider .panels .panel_count").length;
		var pages_nav 		= $("#Slider .panels_nav .pages");
		var slide_wrapper	= $("#Slider .panels");
		var btn_prev		= $("#slideLeft .slide_left");
		var btn_next		= $("#slideRight .slide_right");
		var current_panel 	= 1;
		var slide_speed 	= 600;
		var slide_timer		= 8500;
		var timer_id        = null;
		
		var resetTimer = function()
		{
			if (timer_id != null)
			{
				clearInterval(timer_id);
			}
			
			timer_id = setInterval(function() {
				if(current_panel < panels_total-1) {
					slide_wrapper.animate({
						left	: "-=" + slider_width + "px"
					}, slide_speed);
					current_panel += 1;
					setSelectedSlider(current_panel, pages_nav);
				} else {
					slide_wrapper.animate({
						left	: "-=" + slider_width + "px"
					}, slide_speed, function() {
						slide_wrapper.css('left','0px');
						current_panel = 1;
						setSelectedSlider(current_panel, pages_nav);
					});		
				}
				
				if(current_panel == 1) {
					btn_prev.addClass('disabled');
				}
				if(current_panel > 1) {
					btn_prev.removeClass('disabled');
				}
				if(current_panel == panels_total) {
					btn_next.addClass('disabled');
				}
				if(current_panel < panels_total) {
					btn_next.removeClass('disabled');
				}
			}, slide_timer);
		};
		
		// Setup sizes 
		slide_wrapper.width(slider_width*panels_total);
		panels.width(slide_wrapper.width()/panels_total);
		
		// Setup buttons
		btn_prev.click(function() {
			if(current_panel > 1) {
				slide_wrapper.animate({
					left	: "+=" + slider_width + "px"
				}, slide_speed)
				current_panel -= 1;
				setSelectedSlider(current_panel, pages_nav);
				btn_next.removeClass('disabled');
				resetTimer();
			} else {
				return false;
			}
			if(current_panel == 1) {
				btn_prev.addClass('disabled');
			}
		});
		btn_next.click(function() {
			if(current_panel < panels_total) {
				slide_wrapper.animate({
					left	: "-=" + slider_width + "px"
				}, slide_speed)
				current_panel += 1;
				setSelectedSlider(current_panel, pages_nav);
				btn_prev.removeClass('disabled');
				resetTimer();
			} else {
				return false;
			}
			if(current_panel == panels_total) {
				btn_next.addClass('disabled');
			}
		});

		// Setup Pagination 
		$(panels).each(function(i) {
			
			i++ // Start count at 1
			
			// Build pagination buttons
			var page_buttons = "<a id='btn_" + i + "'></a>";		
			$(pages_nav).append(page_buttons);

			setSelectedSlider(1, pages_nav);
			
			// Setup page button functionality
			$(pages_nav).find("#btn_" + i).click(function() {
				if(current_panel == i) {
					return false;
				}
				
				resetTimer();
				
				if(current_panel < i) {
					slide_wrapper.animate({
						left	: "-" + ((i*slider_width)-slider_width) + "px"
					}, slide_speed)
					current_panel = i;
					setSelectedSlider(i, pages_nav);
				}
				if(current_panel > i) {
					slide_wrapper.animate({
						left	: "-" + ((i*slider_width)-slider_width) + "px"
					}, slide_speed)
					current_panel = i;
					setSelectedSlider(i, pages_nav);
				}
				if(current_panel == 1) {
					btn_prev.addClass('disabled');
				}
				if(current_panel > 1) {
					btn_prev.removeClass('disabled');
				}
				if(current_panel == panels_total) {
					btn_next.addClass('disabled');
				}
				if(current_panel < panels_total) {
					btn_next.removeClass('disabled');
				}
				
			});
			
		});	
		
		$(pages_nav).find("a:last-child").hide();
		
		resetTimer();
	}
	
};

function setSelectedSlider(num, pages)
{
	$(pages).find("a").removeClass('selected');
	$(pages).find("#btn_" + num).addClass('selected');
}

function setupScrollToTop(){
    // Footer Scroll to Top
    $('.top_scroll').click(function() {
        $('html, body').animate({
            scrollTop:0
        }, 'slow');
        return false;
    });
}

var unityHide;

function hideUnity() {
	clearTimeout(unityHide);
	$('#UnityWrapper').addClass('tiny');
}

function showUnity() {
	unityHide = setTimeout(function() {
		$('#UnityWrapper').removeClass('tiny');
	}, 200);
}

function setupProfileAccordion() {
	// Profile Accordions

    if ($('.profile_overview_stats') !== null) {

		var accordionToggle = $('.profile_overview_stats h3');
		var accordionContent = $('.profile_overview_stats .statSegment');

		accordionToggle.filter(':first').addClass('open');
		accordionContent.hide().filter(':first').show();

		accordionToggle.click( function () {
			$(this).next().toggle();
			$(this).toggleClass('open');
		});
	};
}

function setupTabs(){
	//Tabs
	var miniTabLinks = $('.section_nav ul.tabs li a');
	var miniTabContent = $('#tabbed_content > div');

	//miniTabLinks.filter(':first').addClass('selected');
	miniTabContent.hide().filter(':first').show();

/*
* Commented out because we are using separate pages instead of tabbed content:
*  - MJB
*/

//	miniTabLinks.click(function() {
//		miniTabLinks.removeClass('selected');
//		$(this).addClass('selected');
//		$('div#tabbed_content').children().each(function () {
//			$(this).hide();
//		});
//		$(($(this).attr("href"))).show();
//
//		return false;
//	});
}

/*====Critical flow=========================*/
function checkForCharacter()
{
	if($("errorName", myPlayerCardXML).length > 0)
    {
        var errorName = $("getCharacter errorName", myPlayerCardXML).text();
        if (errorName == "CHARACTER_ERR_NOT_DEFINED")
        {
            var sex = 0; // MALE
            var imageIdx = 0; // default

            callPostWS(false, "/blaze/createcharacter/" + sex + "/" + imageIdx,
                WSRequestTimeout, "",
                null,
                function(xml, textStatus)
                {
                    // this resets the cash, so update wallet
                    loadPlayerCardCash();
                    // show new user tutorial flow
                    addNewUserScreen();
                    
                    // call functions that are dependent of this check being done, like new user activity
                    try
                    {
                    	characterCheckFinished();
                    }
                    catch(err)
                    {
                    	// expected for pages that don't need to do special handling (most pages)
                    }
                },
                function(XMLHttpRequest, textStatus)
                {
                	// call functions that are dependent of this check being done, like new user activity
                    try
                    {
                    	characterCheckFinished();
                    }
                    catch(err)
                    {
                    	// expected for pages that don't need to do special handling (most pages)
                    }
                },
                null);
        }
        // character already created
        else
        {
        	// call functions that are dependent of this check being done, like new user activity
            try
            {
            	characterCheckFinished();
            }
            catch(err)
            {
            	// expected for pages that don't need to do special handling (most pages)
            }
        }
    }
    // character already created
    else
    {
    	// call functions that are dependent of this check being done, like new user activity
        try
        {
        	characterCheckFinished();
        }
        catch(err)
        {
        	// expected for pages that don't need to do special handling (most pages)
        }
    }
}

function addNewUserScreen()
{
	// TODO: use new modal system
   spawnModalWindow('/users/newuser');
}
/*
function removeNewUserScreen()
{
    $('html, body').css({
        'overflow' : 'visible'
    });
    $('#newUserWrapper').remove();
}
*/
/*====Player card =========================*/

//
//Update the inbox private message count tally in the player card
//
function setInboxCount()
{
	var total = 0;
	
	if (personaId != undefined)
	{
       total += parseInt($("myplayercard privatemessages getmessages messages servermessage", myPlayerCardXML).length);
	}
	
	// update any on page counters showing the group count (i.e. home page message widget)
	$(".pendingInboxCount").text(total);
	if(total > 0 )
	{
		$("#messages-count").addClass('showCounter').html(total).show();
	}
	else 
	{
		
		$("#messages-count").html(total).hide().removeClass('showCounter');
	}
	
	// update the list in the bar too
	try
    {
		displayMessagesList($("myplayercard privatemessages getmessages", myPlayerCardXML));
    }
    catch(err)
    {
    	// expected for pages that don't have the ODB
    }
}

//
// Update the notification count tally in the player card
//
function setNotificationCount()
{
	var total = 0;
	
	if (personaId != undefined)
	{
		// group requests from Blaze
       var groupTotal = parseInt($("myplayercard getpetitions clubpetitionslist clubmessage", myPlayerCardXML).length);
       // update any on page counters showing the group count (i.e. home page message widget)
  	   $(".pendingGroupRequests").text(groupTotal);
       total += groupTotal;
	   
       // friend requests from EASW
       var friendTotal = parseInt($("myplayercard friend_request_list-full friend_request", myPlayerCardXML).length);
       // update any on page counters showing the group count (i.e. home page message widget)
       $(".pendingFriendRequests").text(friendTotal);
   	   total += friendTotal;
	}
	$(".pendingNotifications").text(total);
	
	
	if( total > 0 )
	{
		$("#notifications-count").addClass('showCounter').html(total).show();
		
	} 
	else  
	{
		$("#notifications-count").html(total).hide().removeClass('showCounter');
	}
	
	// update the list in the bar too
	try
    {
		displayNotificationsList($("myplayercard", myPlayerCardXML));
    }
    catch(err)
    {
    	// expected for pages that don't have the ODB
	}
    
    // handle any page usage of these invites
	try
    {
		renderPageNotificationData($('myplayercard friend_request_list-full', myPlayerCardXML), $('myplayercard getpetitions', myPlayerCardXML) );
    }
    catch(err)
    {
    	// expected for pages that don't have do anything special with notifications (all but message notifications page)
	}    
}

//
//Update the game invite count tally in the player card
//
function setGameInviteCount()
{
	var total = 0;
	
	if (personaId != undefined)
	{
		total += parseInt($("myplayercard invitations receivedInvitations invitation", myPlayerCardXML).length);
	}
	
	if( total > 0 )
	{
		$("#game-invite-count").addClass('showCounter').html(total).show();
		
	} 
	else  
	{
		$("#game-invite-count").html(total).hide().removeClass('showCounter');
	}

	// update the list in the bar too
	try
    {
		displayGameInvitesList($("myplayercard invitations", myPlayerCardXML));
    }
    catch(err)
    {
    	// expected for pages that don't have the ODB
    }
}

//
// Calls character progression to set the level in the player card
//
function updateLevelInPlayerCard () {
    var level = '0';

    if (typeof(playerPersonaId) === 'undefined') {
        return -1;
    }

    DAL_Request(false, "/blaze/characterprogression/" + playerPersonaId,
        WSRequestTimeout,
        null,
        function(xml, textStatus)
        {
            level = $('level', xml).text();
            $('#de_page_header .level-icon-s').html(level);
        },
        function(xml, textStatus)
        {
        },
        null);

        return true;
}

// Function: loadPlayerCard
//  Populates global variable myPlayerCardXML with
//  XML from a Blaze-batch call. This global variable is then used
//  in subsequent functions that require this XML.
function loadPlayerCard () 
{
    if (personaId !== undefined) 
    {
    	// update nucleus wallet data
    	loadPlayerCardCash();
    	
		// now with the table, we can get the playercard and use it to build player xp data using playercard data...
    	DAL_Request(false, '/players_service/myPlayerCard',
            WSRequestTimeout,
            null,
	        function(xml, textStatus)
            {
                if (textStatus !== 'error') 
                {
                    myPlayerCardXML = xml;
                    
                    loadPlayerInfo();
                    loadPlayerHandicap();
            	    setInboxCount();
            	    setNotificationCount();
            	    setGameInviteCount();
            	    
                    loadMyCutLine();
                    loadPlayerOpenGames();
					
            		// need to grab static progression table, its needed for showing player exp/level data
                	DAL_Request(true, '/players_service/characterProgressionTable',
                			WSRequestTimeout,
                            null,
                	        function(xml, textStatus)
                            {
                				characterProgressionTableXML = xml;
                				loadPlayerExp();
                				
                				try
                                {
                					renderPageProgressionData();
                                }
                                catch(err)
                                {
                                	// expected for pages not doing page specific things with the xp progrssion data data
                                }
            			    },
            			    function(XMLHttpRequest, textStatus)
            			    {
            			    	// 404 or request interrupted by user
            			    },
            			    null);
					
					//Wait Until Everything is Loaded and then Load the bar
                    try
                	{
                    	setupDockLoader();
                    }
                	catch(er)
                	{
                    	// expected for pages that don't have the ODB (e.g. membershipOffer)
                    }
                    
                    // first time log in check
                    if (!firstTimeUserChecked)
                    {
                    	firstTimeUserChecked = true;
                    	checkForCharacter();
                    }
					$(".imagePlayerCardAvatar").attr("src", '/players/avatarsbyid/' + personaId + "/transparent?_=" + Math.random()); // refresh with non-cached version of the avatar
                    try
                    {						
                    	renderPagePlayerCardData();						
                    }
                    catch(err)
                    {}		
					try {
						parent.$(".imagePlayerCardAvatar").attr("src", '/players/avatarsbyid/' + personaId + "/transparent?_=" + Math.random()); // refresh with non-cached version of the avatar
					}catch(err){
						document.parent.$(".imagePlayerCardAvatar").attr("src", '/players/avatarsbyid/' + personaId + "/transparent?_=" + Math.random()); // refresh with non-cached version of the avatar
					}
                }
	    		else
	    		{
	    			// TODO: dash out all the fields set above to show server error
	    		}
            },
            function(XMLHttpRequest, textStatus)
            {
            	// 404 or request interrupted by user
            },
            null);
    	
    }
}

function loadPlayerInfo()
{
	// Look for a large count in M or W's as 15 of these characters will go beyone the play
	// button.
	var largeChars = personaName.match(/[MW]/g);
	var largeCharCount = 0;
	
	// If largeChars is not null, count how many large chars we have
	if(largeChars != null)
	{
		largeCharCount = largeChars.length;
	}

	if(largeCharCount > MAX_LARGE_PERSONA_CHAR_COUNT)
	{
		personaName = personaName.substring(0,MAX_LARGE_PERSONA_CHAR_COUNT-1) + "...";
	}
	
	$('.my_persona').html(personaName);
	
	$(".imagePlayerCardAvatar").attr("src", '/players/avatarsbyid/' + personaId + "/transparent?_=" + Math.random()); // refresh with non-cached version of the avatar
}


//define global character progression variables
var characterprogress = Array();
characterprogress['currenttitle'] = Array();
characterprogress['nexttitle'] = Array();
characterprogress['currentlevel'] = Array();
characterprogress['nextlevel'] = Array();
characterprogress['xplevels'] = Array();
characterprogress['cashlevels'] = Array();



function getLevelInfo(level){
	var thisTitleId = -1;
	var nextTitleId = -1;
	var titleInfo = [];
	
	//get the titleid for the current numeric level
	$('getcharacterprogressiontable characterprogressionlevels characterprogressionlevel', characterProgressionTableXML).each(function(i, val){
		
		if(level == $('level', val).text() ){
			titleInfo['LevelExp'] = parseInt( $('experiencepoints', val).text() );	
			titleInfo['TitleId'] = parseInt( $('titleid', val).text() );
			titleInfo['CareerEarnings'] = parseInt( $('careerearnings', val).text() );					
		}
		
		if( parseInt(level) + 1 == $('level', val).text() ){			
			titleInfo['NextLevelExp'] = $('experiencepoints', val).text();
			titleInfo['NextLevelCareerEarnings'] = $('careerearnings', val).text();				
			return false;	
		}		
	});
	
	//get title info
	$('getcharacterprogressiontable characterprogressionlevels characterprogressionlevel', characterProgressionTableXML).each(function(i, val){
		if(titleInfo['TitleId'] == $('titleid', val).text() ){
			titleInfo['TitleExp'] = $('experiencepoints', val).text();
			titleInfo['CareerEarnings'] = $('careerearnings', val).text();		
			return false;
		}
	});
		
	//get next title info
	$('getcharacterprogressiontable characterprogressionlevels characterprogressionlevel', characterProgressionTableXML).each(function(i, val){	
		if( titleInfo['TitleId'] + 1 == $('titleid', val).text() ){			
			titleInfo['NextTitleId'] = parseInt( $('titleid', val).text() );
			titleInfo['NextTitleExp'] = $('experiencepoints', val).text();
			titleInfo['NextTitleCareerEarnings'] = $('careerearnings', val).text();		
			return false;	
		}
	});
	
	$('getcharacterprogressiontable titlelevels enumeration', characterProgressionTableXML).each(function(){		
		if ($("enumerationid", this).text() == titleInfo['TitleId'] ) {
			titleInfo['TitleName'] = $('enumerationdescription', this).text();
		}
		
		if ($("enumerationid", this).text() == titleInfo['NextTitleId']) {
			titleInfo['NextTitleName'] = $('enumerationdescription', this).text();
			return false; //Based on the assupmtion that these titles always come back in order
		}
	});		
	
	return titleInfo;
}


function loadPlayerExp()
{
	//get the current numeric level
    characterprogress['currentlevel']['level'] = $('getcharacterprogression', myPlayerCardXML).find('level', myPlayerCardXML).text();
    characterprogress['currentlevel']['xp'] = $('getcharacterprogression experiencepoints', myPlayerCardXML).text();
	characterprogress['currentlevel']['careerearnings'] = $('getcharacterprogression careerearnings', myPlayerCardXML).text();
    characterprogress['currentlevel']['coursemasteryid'] = $('getcharacterprogression', myPlayerCardXML).find("coursemasterylevelid").text();
    characterprogress['currentlevel']['coursemasterycount'] = $('getcharacterprogression', myPlayerCardXML).find("coursemasterynumbercourses").text();

	//get the titleid for the current numeric level
	$('getcharacterprogressiontable characterprogressionlevels characterprogressionlevel', characterProgressionTableXML).each(function(i, val)
    {
		if(characterprogress['currentlevel']['level'] == $('level', val).text())
		{
			characterprogress['currentlevel']['titleid'] = $('titleid', val).text();
			return false;
		}
	});

	//get the current title level
    $('getcharacterprogressiontable characterprogressionlevels characterprogressionlevel', characterProgressionTableXML).each(function(i, val)
    {
		var titleid = $('titleid', val).text();
		if(titleid == characterprogress['currentlevel']['titleid'])
        {
			characterprogress['currenttitle']['level'] = $('level', val).text();
			characterprogress['currenttitle']['titleid'] = $('titleid', val).text();
			characterprogress['currenttitle']['xp'] = $('experiencepoints', val).text();
			characterprogress['currenttitle']['careerearnings'] = $('careerearnings', val).text();
			characterprogress['currenttitle']['coursemasteryid'] = $('coursemasterylevelid', val).text();
			characterprogress['currenttitle']['coursemasterycount'] = $('coursemasterynumbercourses', val).text();
            return false;
    	}
	});
           
	//get the next numeric level
	$('getcharacterprogressiontable characterprogressionlevels characterprogressionlevel', characterProgressionTableXML).each(function(i, val)
	{
		var level = $('level', val).text();
		if(parseInt(level) == parseInt(characterprogress['currentlevel']['level']) + 1)
        {
			characterprogress['nextlevel']['level'] = $('level', val).text();
			characterprogress['nextlevel']['xp'] = $('experiencepoints', val).text();
			characterprogress['nextlevel']['careerearnings'] = $('careerearnings', val).text();
			characterprogress['nextlevel']['coursemasteryid'] = $('coursemasterylevelid', val).text();
			characterprogress['nextlevel']['coursemasterycount'] = $('coursemasterynumbercourses', val).text();
			return false;
        }
	});

	//get the next title level
	$('getcharacterprogressiontable characterprogressionlevels characterprogressionlevel', characterProgressionTableXML).each(function(i, val)
    {
		var titleid = $('titleid', val).text();
		if(parseInt(titleid) == parseInt(characterprogress['currentlevel']['titleid']) + 1)
		{
			characterprogress['nexttitle']['level'] = $('level', val).text();
			characterprogress['nexttitle']['titleid'] = $('titleid', val).text();
			characterprogress['nexttitle']['xp'] = $('experiencepoints', val).text();
			characterprogress['nexttitle']['careerearnings'] = $('careerearnings', val).text();
			characterprogress['nexttitle']['coursemasteryid'] = $('coursemasterylevelid', val).text();
			characterprogress['nexttitle']['coursemasterycount'] = $('coursemasterynumbercourses', val).text();
        
			return false;
		}
    });

	//get the xp amounts required for each level
	$('getcharacterprogressiontable characterprogressionlevels characterprogressionlevel', characterProgressionTableXML).each(function(i, val)
    {
		characterprogress['xplevels'][parseInt($('level', val).text())] = $('experiencepoints', val).text();
		characterprogress['cashlevels'][parseInt($('level', val).text())] = $('careerearnings', val).text();
    });
	
	//get the current title
	$('getcharacterprogressiontable titlelevels enumeration', characterProgressionTableXML).each(function(i, subval)
	{
		if($('enumerationid', subval).text() == characterprogress['currentlevel']['titleid'])
		{
			characterprogress['currenttitle']['title']  = formatWordsFirstLetterUpperCase( $('enumerationdescription', subval).text().replace("_"," ") );
			
			if(characterprogress['currenttitle']['title'].toLowerCase().indexOf("legend") >= 0)
				characterprogress['currenttitle']['title'] = "Legend";
			
			return false;
		}
	});

	//get the name of the title
	$('getcharacterprogressiontable titlelevels enumeration', characterProgressionTableXML).each(function(i, subval)
    {
		if($('enumerationid', subval).text() == characterprogress['nexttitle']['titleid'])
        {
			characterprogress['nexttitle']['title']  = formatWordsFirstLetterUpperCase( $('enumerationdescription', subval).text().replace("_"," ") );
			
			if(characterprogress['nexttitle']['title'].toLowerCase().indexOf("legend") >= 0)
				characterprogress['nexttitle']['title'] = "Legend";
			
            return false;
        }
    });

	//get the name of the course mastery title
	$('getcharacterprogressiontable coursemasterylevels enumeration', characterProgressionTableXML).each(function(i, subval)
    {
		if($('enumerationid', subval).text() == characterprogress['currenttitle']['coursemasteryid'])
        {
			characterprogress['currenttitle']['coursemasterytitle']  = formatWordsFirstLetterUpperCase( $('enumerationdescription', subval).text().replace("_"," ") );
			
			if(characterprogress['currenttitle']['coursemasterytitle'].toLowerCase().indexOf("legend") >= 0)
				characterprogress['currenttitle']['coursemasterytitle'] = "Course Legend";
			
            return false;
        }
    });
	
	//get the name of the course mastery title
	$('getcharacterprogressiontable coursemasterylevels enumeration', characterProgressionTableXML).each(function(i, subval)
    {
		if($('enumerationid', subval).text() == characterprogress['nexttitle']['coursemasteryid'])
        {
			characterprogress['nexttitle']['coursemasterytitle']  = formatWordsFirstLetterUpperCase( $('enumerationdescription', subval).text().replace("_"," ") );
			
			if(characterprogress['nexttitle']['coursemasterytitle'].toLowerCase().indexOf("legend") >= 0)
				characterprogress['nexttitle']['coursemasterytitle'] = "Course Legend";
			
            return false;
        }
    });

	//set player card data
	$('#masthead .user_level').html('Level&nbsp;'+ characterprogress['currentlevel']['level'] + '&nbsp;' + characterprogress['currenttitle']['title'] );
	$('#masthead .xp_count').text(formatLargeNumbers(characterprogress['currentlevel']['xp'])+' XP');

	// do any page specific character progress stuff if it exists
    try
    {
    	renderPageCharacterProgress();
    }
    catch(err)
    {
    	// expected for pages that do not need to handle character progoress data itself
    }
}

function loadPlayerHandicap(){
	DAL_Request(true, "/handicap_service/getUserHandicap",
        WSRequestTimeout,
        null,
        function(xml, textStatus)
        {       
			if ($("returnValue", xml).length > 0) {
				var handicapValue = parseInt( $("returnValue", xml).text() );
				if(handicapValue > 0)
					handicapValue = "+" + handicapValue;
				$(".handicap_value").text(handicapValue);
			}
        },
        function(XMLHttpRequest, textStatus)
        {
        },
        null);
}

var myCutLine = Array();
	
function loadMyCutLine () {
    var cutline        = parseInt($('getplayercutline cutline', myPlayerCardXML).text(), 10) / 100;
    var level          = parseInt($('getplayercutline level',   myPlayerCardXML).text(), 10);
    var score          = parseInt($('getplayercutline score',   myPlayerCardXML).text(), 10);
    var streak         = parseInt($('getplayercutline streak',  myPlayerCardXML).text(), 10);
    var timeRemaining  = parseInt($('getplayercutline timeremaining',  myPlayerCardXML).text(), 10);
    var hours          = Math.floor(timeRemaining/3600).toString();
    var minutes        = Math.floor((timeRemaining / 60) % 60).toString();
    var result         = ( (score > 0 && score <= cutline) ? '<img src="/img/dynamic_card/cutline_yes.gif" />' : '<img src="/img/dynamic_card/cutline_no.gif" />');

    playerLevel = level;
    if (cutline !== 0) { // don't want to divide by zero
        playerCutLine = cutline;
    }

    $('.cutline_today').html(playerCutLine.toString());
    $('#myScore').html(score.toString());
    $('#myStreak').html('x' + streak.toString());
    $('#myCutLineResult').html(result);

    if (timeRemaining <= 60) {
        $('.time_left span.info').html(timeRemaining.toString() + '&nbsp;sec');
    } else {
        $('.time_left span.info').html(hours + 'h&nbsp;' + minutes + 'min');
    }
	
	//real data
	myCutLine['cutline'] = playerCutLine;
	myCutLine['level'] = level;
	myCutLine['score'] = score;
	myCutLine['streak'] = streak;
	myCutLine['hours'] = hours;
	myCutLine['minutes'] = minutes;
}


function loadPlayerCardCash()
{
	DAL_Request(false, "/nucleus/mywallets",
        WSRequestTimeout,
        null,
        function(xml, textStatus)
        {
            $('.my_real_wallet_balance').html('-');
    		$('.my_wallet_balance').html('-');
    		var earnedWalletFound = false;
    		var paidWalletFound = false;
            $(xml).find("walletAccount").each(function()
            {
                var currency = $(this).find("currency").text();
                if (currency == '_TB')
                {
                	earnedWalletFound = true;
                    var cash = $(this).find("balance").text();
                    userMoney = cash;
                    $('.my_wallet_balance').html('$'+formatLargeNumbers(cash));
                }
                else if( currency == '_SV')
                {
                	paidWalletFound = true;
                	if(!ignoreSubscriptions)
                	{
                		var cash = $(this).find("balance").text();
                		playerCashBalance = cash;
                		$('.my_real_wallet_balance').html(formatLargeNumbers(cash) + ' Points');
						$('.my_real_wallet_balance_no_label').html(formatLargeNumbers(cash));
                		
                		// allow click to buy more points thru lockbox
                		var returnUrl = escape( document.location.toString() );
                		$(".add_points").unbind();
                		$(".add_points").click(function(){
                			document.location = "/users/purchasePointsRedirect?surl=" + escape(document.location);  
			            });
                		$("#pointsDisplay").show();
                	}
                }
            });
            // this can occur if no billing address set yet, assume 0
            if (!paidWalletFound)
            {
            	// we can show 0 points since they have no wallet yet
				$('.my_real_wallet_balance_no_label').html('0');
            	$('.my_real_wallet_balance').html('0 Points');
            	
        		// allow click to buy more points thru lockbox
        		var returnUrl = escape( document.location.toString() );
        		$(".add_points").unbind();
        		$(".add_points").click(function(){
        			document.location = "/users/purchasePointsRedirect?surl=" + escape(document.location);  
        		});
        		$("#pointsDisplay").show();
            }
			
			try{
				renderWallet();
			}catch(err){}
        },
        function(XMLHttpRequest, textStatus)
        {
            $('.my_wallet_balance').html('-');
            $('.my_real_wallet_balance').html('-');
			$('.my_real_wallet_balance_no_label').html('-');
        },
        null);
}


function loadPlayerSkillLevel()
{

    //If there is data
    if($("getstat keyscopestatsvaluemap", myPlayerCardXML).length > 0)
    {
        var avgScore = $("entitystats statvalues statvalues:eq(0)", myPlayerCardXML).text();
        $('.my_average_score').html(formatZeroIsGoodStat(avgScore));

        var roundsComplete = $("entitystats statvalues statvalues:eq(17)", myPlayerCardXML).text();
        $('.my_rounds_complete').html(roundsComplete);
    }
    else
    {
        $('.my_average_score').html('-');
        $('.my_rounds_complete').html('-');
    }
}

function loadPlayerOpenGames()
{ 
    //If there is data
    if($("getactivegames", myPlayerCardXML).length > 0)
    {
    	
        activeGameId = $("gameid", myPlayerCardXML).length > 0 ? $("gameid", myPlayerCardXML).text() : -1;
        activeTournamentRoundId = $("getactivegames tournamentroundid", myPlayerCardXML).text();
        activeTournamentId = $("getactivegames tournamentid", myPlayerCardXML).text();
        isActiveGameMultiplayer = $("getactivegames ismultiplayergame", myPlayerCardXML).text() == '1';
        isActiveGameTournament = $("getactivegames istournamentgame", myPlayerCardXML).text() == '1';


        var name = $("getactivegames coursename", myPlayerCardXML).text();
        var hole = parseInt($("getactivegames hole", myPlayerCardXML).text()) - 1;
        var score = parseInt($("getactivegames score", myPlayerCardXML).text(), 10);

        if (score === 0) {
            score = 'E';
        } else if (score > 0) {
            score = '+' + score;
        }

        $('#my_open_games').html( '<ul class="opengame">' +
                '<li class="round_information"><a class="round_summary" href="/play/resumeGame/' + activeGameId + '">' + name +'</a><em>Score: ' + score.toString() + '</em><em>thru: ' + hole + ' hole' + (hole != 1 ? 's' : '') + '</em></li>' +
                '<li class="UserButton_spacer">' +
                '<span class="UserButton UserButton_white UserButton_alignLeft"><a class="UserButton_text" href="/play/resumeGame/' + activeGameId + '">Resume Game</a></span>' +
                '<span class="UserButton UserButton_white UserButton_spacer UserButton_alignLeft"><a class="UserButton_text" href="javascript:void(0);" onclick="leaveGameConfirm();">Leave Game</a></span>' +
                '</li>' +
           '</ul>');
    }
    else
    {
        $('#my_open_games').html('<ul class="opengame"><li class="noGame"><span class="UserButton UserButton_white UserButton_alignLeft"><a class="UserButton_text" href="/play">Play a Game</a></span></li></ul>');
    }

    // do any page specific course stuff if it exists
    try
    {
        renderPageActiveGameData($('getactivegames', myPlayerCardXML));
    }
    catch(err)
    {
        // expected for pages w/o game data specific stuff
    }

}

function leaveGameConfirm()
{
    $('#my_open_games').html( '<ul class="opengame">' +
    		'<li class="leave_confirm">Leaving this game will end the round.</li>' +
        	'<li class="UserButton_spacer leave_options">' +
        	'<span class="UserButton UserButton_white UserButton_spacer UserButton_alignLeft"><a class="UserButton_text" href="javascript:void(0);" onclick="leaveGame();">Accept</a></span>' +
        	'<span class="UserButton UserButton_white UserButton_spacer UserButton_alignLeft"><a class="UserButton_text" href="javascript:void(0);" onclick="loadPlayerOpenGames();">Decline</a></span>' +
        	'</li>' +
       '</ul>');
}

function leaveGame()
{
	// assume it works and replace with play a game to prevent resume button
	$('#my_open_games').html('<ul class="opengame"><li class="noGame"><span class="UserButton UserButton_white UserButton_alignLeft"><a class="UserButton_text" href="/play">Play a Game</a></span></li></ul>');
    // Disable the 'Resume' button so the user can't click it before the page reloads - MJB
    $('.UserButton_teeoff').removeClass('UserButton_teeoff').addClass('UserButton_disabled').click(function () { return false; });

    callPostWS(false, "/blaze/finishgame",
        WSRequestTimeout, "",
        null,
        function(xml, textStatus)
        {
        	// game left, go back to play game state
        	if ($("status", xml).text() == 'SUCCESS')
        	{
        		$('#my_open_games').html('<ul class="opengame"><li class="noGame"><span class="UserButton UserButton_white UserButton_alignLeft"><a class="UserButton_text" href="/play">Play a Game</a></span></li></ul>');
        	}
        	else
        	{
        		$('#my_open_games').html('<ul class="opengame"><li class="noGame">Unable to leave game</li></ul>');
        	}
        },
        function(XMLHttpRequest, textStatus)
        {
        	// something might have failed, re update open games state
    		loadPlayerOpenGames()
        },
        null);
}

/*====Dynamic Nav bar =========================*/
//called on any page that displays launcher with counter...
function setCourseMenuItems()
{
    $("#courseDropDown").html();
    DAL_Request(true, "/courses_service/courses",
        WSRequestTimeout,
        null,
        function(xml, textStatus)
        {
    		coursesXml = xml;

    		// success
    		if($("errorName", xml).length == 0)
    		{
	            $("getcourses courses course", xml).each(function()
           		{
                var name =$("coursename", this).text()
                var web =$("webimage", this).text()
                $("#courseDropDown").append('<li class="' + web + '"><a href="/courses/' + web + '"><span></span>' + name + '</a></li>');
            });
    		}
    		// server error
    		else
    		{
    			$("#courseDropDown").append("<li><a href=\"javascript:openErrorWindow('','WebBug', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '');\"><span></span>Could not retrieve courses from server</a></li>");
    		}

            // do any page specific course stuff if it exists
            try
            {
            	renderPageCourses(xml);
            }
            catch(err)
            {
            	// expected for pages that do not need to handle course data itself
            }
        },
        function(XMLHttpRequest, textStatus)
        {
            $("#courseDropDown").html();
        },
        null);
}


function getCourseData(courseId){
	var dataToReturn = "";
	if(coursesXml != null){
		$("getcourses courses course", coursesXml).each(function(i){
			if($("courseid", this).text() == courseId){
				dataToReturn = $(this);
			}
		});
	}

	return dataToReturn;
}

// Retrieve url params for the current page as an associative array.
// TODO: should ideally go in globals.js or some other shared location that's included for game window.
function getUrlVars()
{
	var vars = [], hash;
	var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
	for(var i = 0; i < hashes.length; i++)
	{
		hash = hashes[i].split('=');
		vars.push(hash[0]);
		vars[hash[0]] = hash[1];
	}
	return vars;
}

/*----First Time User Flow--------------------------*/

function setupPageFTUF()
{
	if(!hideFTUF( $("#HelpID").text() ))
	{
		$(".welcome_bar").slideDown(500);
		$("#buttonCollapseHelp").click(function(){
			$(".welcome_bar").slideUp(500);
			setFTUF( $("#HelpID").text() );
		});
	}
}

//Checks to see if a page has already asked for help not to be displayed on this page
function hideFTUF(key)
{
	var found = false;
	var cookieData = getCookie("TWOCookie[FTUF]");

	 if(cookieData != undefined && cookieData != null && cookieData != "")
	 {
		if(cookieData.indexOf(key) >= 0)
		{
			return true;
		}
	 }

	return false;
}

//Tells the help tab on this page not to show up any more
function setFTUF(key)
{
	var cookieData = getCookie("TWOCookie[FTUF]");
	if(cookieData != undefined && cookieData != null && cookieData != "")
	{
		var found = false;
		var cookieArray = cookieData.split("|");
		for(var i=0;i<cookieArray.length;i++)
		{
			if(cookieArray[i].toString() == key)
				found = true;
		}

		if(!found)
		{
			cookieData += "|" + key;
			setCookie("TWOCookie[FTUF]", cookieData);
		}
	}
	else
	{
		setCookie("TWOCookie[FTUF]", key);
	}
}

// String extensions:
String.prototype.camelCase = function() {
  return this.toString()
    .replace(/([A-Z]+)/g, function(m,l){
      return l.substr(0,1).toUpperCase() + l.toLowerCase().substr(1,l.length);
    })
    .replace(/[\-_\s](.)/g, function(m, l){
      return ' ' + l.toUpperCase();
    });
};

/**
 * Global variable to namespace functionality specific to EA
 */
var EA = { };

/**
 * Global variable to provide a place to specify enums throughout the app
 */
EA.enums = { };

/**
 * Fan enum specification
 */
EA.enums.fan = {
    INVALID : 0,
    TV      : 1,
    GALLERY : 2,
    SPONSOR : 3
};
