//Globals

// 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;

var WSRequestTimeout = 12500;

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

var playerLevel   = 0;
var playerCutLine = 0;


var myPlayerCardXML = '';


//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();
	setupSubNav();
	setupModalWindow(); // ! please deprecate
	setupPageFTUF();
    modal_setup(); // new modal design
	
    // 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);
    }

    // Function: $.reverse
    //  Reverse the order of the jQuery collection.
    //  This is a pretty bad-arse function.
    jQuery.fn.reverse = function () {
        return this.pushStack(this.get().reverse(), arguments);
    };

});

//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','#');
	}	
}

// Function: modal_setup
//  Does all the necessary setup for modal windows. You should be
//  following the instructions on the WIKI for how to implement the markup
//  and activiation links.
function modal_setup () {
    //get the height and width of the page
    var window_width    = $(window).width();
    var window_height   = $(window).height();
    var document_height = $(document).height();

    $('#mask').css({'height': document_height});

    //vertical and horizontal centering of modal window(s)
    /*we will use each function so if we have more then 1
    modal window we center them all*/
    $('.modal_container').each(function () {
         //get the height and width of the modal
         var modal_height = $(this).outerHeight();
         var modal_width = $(this).outerWidth();

         //calculate top and left offset needed for centering
         var top = (window_height-modal_height)/2;
         var left = (window_width-modal_width)/2;

         //apply new top and left css values
         $(this).css({'top' : top , 'left' : left});
    });

    $('.activate_modal').click(function(){
        //get the id of the modal window stored in the name of the activating element
        var modal_id = $(this).attr('name');

        //use the function to show it
        show_modal(modal_id);
    });

    $('.close_modal, .modal .close').click(function(){
        //use the function to close it
        close_modal();
    });
}


// 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) {
    $("#emailField").css('color', '#333');
    if ( (e.which === 13) || (e.keyCode && e.keyCode === 13)) {
        submitLogin();
    }
});

$("#emailField").mousedown(function () {
    var strDefault = 'Email';

    if ($(this).val() === strDefault) {
        $(this).val('').css('color', '#333');
    }
});

$('#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).attr("value", "Email").css('color', '#999' );

               objEmailField.focus();

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

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

        try{
            pageReadyGuest();
        }catch(er){}
    }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)
    	{
    		// 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();

		    // also do check for character created yet
		    checkForCharacter();

			// Top-bar drop downs
			setupTopNav();

	        //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();
			setupToolTips();
        }catch(er){}
    }
}

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

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


/*====WebServices===========================*/
function callGetWS(isCachable, serviceUrl, timeoutTime,
    beforeSendCallback, successCallback, errorCallback, completeCallback)
{
    $.ajax({
        type: "GET",
        async: true,
        dataType: "xml",
        cache: isCachable,
        url: serviceUrl,
        timeout: timeoutTime,
        beforeSend: function(XMLHttpRequest){
            if(beforeSendCallback!=null)
                beforeSendCallback(XMLHttpRequest);
        },
        success: function(data, textStatus){
            if($("error code", data).text() == "TWO_AUTH"){
                //If you are no longer authenticated
                //TODO: this should actually show a timeout message, then redirect
                logoutOfSite();
            }else{
                if(successCallback!=null)
                    successCallback(data, textStatus);
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown){
            if(errorCallback!= null)
                errorCallback(XMLHttpRequest, textStatus, errorThrown);
        },
        complete: function(XMLHttpRequest, textStatus){
            if(completeCallback!=null)
                completeCallback(XMLHttpRequest, textStatus);
        }
    });
}

function callSyncGetWS(isCachable, serviceUrl, timeoutTime,
	    beforeSendCallback, successCallback, errorCallback, completeCallback)
{
	    $.ajax({
	        type: "GET",
	        async: false,
	        dataType: "xml",
	        cache: isCachable,
	        url: serviceUrl,
	        timeout: timeoutTime,
	        beforeSend: function(XMLHttpRequest){
	            if(beforeSendCallback!=null)
	                beforeSendCallback(XMLHttpRequest);
	        },
	        success: function(data, textStatus){
	            if($("error code", data).text() == "TWO_AUTH"){
	                //If you are no longer authenticated
	                //TODO: this should actually show a timeout message, then redirect
	                logoutOfSite();
	            }else{
	                if(successCallback!=null)
	                    successCallback(data, textStatus);
	            }
	        },
	        error: function(XMLHttpRequest, textStatus, errorThrown){
	            if(errorCallback!= null)
	                errorCallback(XMLHttpRequest, textStatus, errorThrown);
	        },
	        complete: function(XMLHttpRequest, textStatus){
	            if(completeCallback!=null)
	                completeCallback(XMLHttpRequest, textStatus);
	        }
	    });
	}

function callPostWS(isCachable, serviceUrl, timeoutTime, requestData,
    beforeSendCallback, successCallback, errorCallback, completeCallback)
{
    $.ajax({
        type: "POST",
        dataType: "xml",
        data: requestData,
        cache: isCachable,
        url: serviceUrl,
        timeout: timeoutTime,
        beforeSend: function(XMLHttpRequest){
            if(beforeSendCallback!=null)
                beforeSendCallback(XMLHttpRequest);
        },
        success: function(data, textStatus){
            if($("error code", data).text() == "TWO_AUTH"){
                //If you are no longer authenticated
                //TODO: this should actually show a timeout message, then redirect
                logoutOfSite();
            }else{
                if(successCallback!=null)
                    successCallback(data, textStatus);
            }
        },
        error: function(XMLHttpRequest, textStatus, errorThrown){
            if(errorCallback!= null)
                errorCallback(XMLHttpRequest, textStatus, errorThrown);
        },
        complete: function(XMLHttpRequest, textStatus){
            if(completeCallback!=null)
                completeCallback(XMLHttpRequest, textStatus);
        }
    });
}

/*====Modal Window - Please deprecate ===========================*/
function spawnModalWindow(content) {

	var modalWindow = "";
	modalWindow += "\
		<div id='modal-wrapper'>\
			<div id='modal-window'>\
					<div class='content' valign='top'><iframe src="+ content +" scrolling='no' frameborder='0' ></iframe></div>\
				<div class='modal-close'><a href='#' onClick='modalRemove();'><img src='/img/globals/modal/close.png' alt='' /></a></div>\
			</div>\
		</div>\n";

		$('body').append(modalWindow);
}

function goToPlayGame (e) {
    if (e) { e.preventDefault(); }
    parent.location.href = '/play/courseselect/singleplayer';
    parent.modalRemove();
}

// Please deprecate
function setupModalWindow() {
	$('a.modal_DEPRECATE').click(function() {
		hideUnity();
		var goHere = $(this).attr('rev');
		spawnModalWindow(goHere);
		return false;
	});
}

function modalRemove() {
	showUnity();
	$("#modal-wrapper").hide().remove();
	$('body').css('overflow','visible');
}


/*====Warning popups========================*/
function wb_remove() {
    warnActive = false;
    $(".wb_close").unbind("click");
    $(".wb_window, #wb_overlay").remove();
}

function showScrim() {
    // Set variables
    var btnClose = "/img/wb_btn_close.png";

    $("#wb_overlay, .wb_window, .wb_content").remove();

    // Black out the background
    if(msie6) {
        $("html").css("overflow", "hidden");
        $("body").append("<div id='wb_overlay'></div><div class='wb_window'></div>");
        $("#wb_overlay").addClass("wb_bg");
    } else {
        $("body").append("<div id='wb_overlay'></div><div class='wb_window'></div>");
        $("#wb_overlay").addClass("wb_bg");
    }
}

function warn(msg) {

    warnActive = true;

    // Add in our generic box
    $("body").append('<div id="warn_box" style="display:none;"><div class="wb_wrapper"><div class="wb_message"><strong>'+msg+'</strong></div><div class="wb_close"><a href="javascript:void(0);"><img src="/img/buttons/close_warn.png" /></a></div></div></div>');

    $("#warn_box").show();
	$("#warn_box .wb_wrapper").hide().fadeIn("slow");

    $(".wb_close").click(function(){
        $("#warn_box").remove();
    });

}

function removeWarn()
{
    $("#warn_box").slideUp("slow", function(){
        $("#warn_box").remove();
    });
}

function warnConfirm(msg, okHandler, cancelHandler) {
    warnActive = true;

    // Set variables
    var btnOk = "/img/wb_btn_accept.png";
    var btnCancel = "/img/wb_btn_decline.png";

    $("#wb_overlay, .wb_window, .wb_content").remove();

    // Black out the background
    if(msie6) {
        $("html").css("overflow", "hidden");
        $("body").append("<div id='wb_overlay'></div><div class='wb_window'></div>");
        $("#wb_overlay").addClass("wb_bg");
    } else {
        $("body").append("<div id='wb_overlay'></div><div class='wb_window'></div>");
        $("#wb_overlay").addClass("wb_bg");
    }

    // Spawn modal window
    $(".wb_window").append("<div class='wb_content'><div class='wb_top'></div><div class='wb_mid'><span class='message'><p>" + msg +"</p></span><span class='buttons'><a href='#' class='wb_ok'><img src='" + btnOk + "' alt=''></a><a href='#' class='wb_cancel'><img src='" + btnCancel + "' alt=''></a></span></div><div class='wb_btm'></div></div>");

    // Position modal window
    $(".wb_window").css({
        'position' : 'absolute',
        'left' : '50%',
        'top' : '50%',
        'margin-left' : '-' + parseInt($(".wb_window").width() / 2) + 'px',
        'margin-top' : '-' + parseInt($(".wb_window").height() / 2) + 'px'
    });


    // remove the modal window
    $(".wb_ok").click(function(){
        okHandler();
        wb_remove();
        $(".wb_ok").unbind();
    });
    $(".wb_cancel").click(function(){
        wb_remove();
        $(".wb_cancel").unbind();
    });


    document.onkeyup = function(e){
        if(warnActive){
            if (e == null) {
                // msie
                keycode = event.keyCode;
            } else {
                //firefox
                keycode = e.which;
            }

            if(keycode == 13){
                okHandler();
                wb_remove();
            }
            if(keycode == 27){
                wb_remove();
            }
        }
    };

}





/*====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');
            warn(msgIE6);
        } else if($.browser.chrome) 	{
            setCookie('TWOCookie[warning]','true','Fri, 1 Jan 2100 20:00:00 UTC');
            warn(msgChrome);
        } else if($.browser.opera) 	{
            setCookie('TWOCookie[warning]','true','Fri, 1 Jan 2100 20:00:00 UTC');
            warn(msgOpera);
        } else if ($.browser.mozilla && $.browser.version.indexOf('1.8.') > -1) {
            setCookie('TWOCookie[warning]','true','Fri, 1 Jan 2100 20:00:00 UTC');
            warn(msgff2);
        }
    }
}

/*====Setups===============================*/
function setupDirectedExperience(options) {
	var deHeader = "";
	var deIcon = "";
	var deIconLink = "";
	var deTitle = "";
	var deDescription = "";
	var deTutorialLink = "";
		
	if (typeof(options) === 'object') {
		deIcon = options.icon;
		deIconLink = options.iconLink;
		deTitle = options.title;
		deDescription = options.description;
		deTutorialLink = options.tutorialLink;
	}
	
	deHeader += '\
	<div class="ContentWhite DoubleBorder">\
	<ul class="inner">\
		<li class="section_icon">\
			<span class="de_doors">\
				<a class="icon ' + deIcon + '" href=' + deIconLink + ' >Return to Courses</a>\
			</span>\
		</li>\
		<li class="section_description">\
			<span class="de_doors">\
				<div class="content">\
					<h1>' + deTitle + '</h1>\
					 <p>' + deDescription + '</p>\
				</div>\
				<div class="UserActions"><a href="" class="help tooltip modal_DEPRECATE" rel="Need More Info?" rev="/gameGuide/' + deTutorialLink + '" onclick="return false;">Need More Info?</a></div>\
			</span>\
		</li>\
	</ul></div>\n';

		$('#de_page_header').append(deHeader);
}


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 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 authToken = getCookie("CEM-login");
	var returnUrl = escape( document.location.toString() );
	
	if(!ignoreSubscriptions)
	{
		$("#lockboxAccountManagementLink").click(function(){
			document.location = lockBoxBasePath + "/manage-billing-accounts?gameId=TigerWoods&authToken=" + authToken + "&returnUrl=" + returnUrl;  
		});
		
		if(subscriptionCookie.indexOf("freetoplay") >= 0){
			var subArray = subscriptionCookie.split("|");
			$("#SubscriptionTopBar").html('<strong>' + subArray[1] + ' Tee Times</strong> Remaining <span id="lockboxAccountManagementLink" class="UserButton UserButton_blue UserButton_spacer"><a class="UserButton_text">Upgrade Account</a></span>');
			
			if (typeof(lockBoxBasePath) !== 'undefined')  {   
				$("#lockboxAccountManagementLink a").unbind();
		        $("#lockboxAccountManagementLink a").click(function(){
		        	document.location = lockBoxBasePath + "/subscriptions?gameId=TigerWoods&authToken=" + authToken + "&returnUrl=" + returnUrl;        	
		        });
		    }
		}
		else 
		{
			$("#SubscriptionTopBar").html('<span id="lockboxAccountManagementLink" class="UserButton UserButton_blue"><a class="UserButton_text">Manage Account</a></span>');
			
			if (typeof(lockBoxBasePath) !== 'undefined')  {    	
				$("#lockboxAccountManagementLink a").unbind();
		        $("#lockboxAccountManagementLink a").click(function(){
		        	document.location = lockBoxBasePath + "/manage-billing-accounts?gameId=TigerWoods&authToken=" + authToken + "&returnUrl=" + returnUrl;        	
		        });
		    }
		}
	}
	else
	{
		$(".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 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().slideToggle();
			$(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;
//	});
}

/*====Formatting=========================*/
function formatLargeNumbers(nStr) {
	if(nStr != "" && nStr != null && nStr != undefined){
	    nStr += '';
	    x = nStr.split('.');
	    x1 = x[0];
	    x2 = x.length > 1 ? '.' + x[1] : '';
	    var rgx = /(\d+)(\d{3})/;
	    while (rgx.test(x1)) {
	        x1 = x1.replace(rgx, '$1' + ',' + '$2');
	    }
	    return x1 + x2;
	}else
		return "0";
}

// Function: formatRelativeScore
// This function formats a score, which is a +/- number relative to par
function formatRelativeScore(nStr)
{
	if(nStr == "0")
	{
		return "E";
	}
    else if(parseInt(nStr) == 9999 || parseFloat(nStr) == 9999.00 || nStr === '')
	{
		return "NA";
	}
	else
	{
        if (nStr > 0)
        {
            nStr = "+" + nStr;
        }
        return formatLargeNumbers(nStr);
	}
}

// Function: formatZeroIsGoodStat
// This function formats a stat, by watching for the 9999, which is an indicator of an undefined value
function formatZeroIsGoodStat(nStr)
{
    if(parseInt(nStr) == 9999 || parseFloat(nStr) == 9999.00 || nStr === '')
	{
		return "NA";
	}
    else
    {
        return formatLargeNumbers(nStr);
    }
}

function formatWordsFirstLetterUpperCase(words){
	if(words != "" && words != undefined)
	{
		var finalString = words.toLowerCase();
			
		if(finalString.indexOf(" ") >= 0)
		{			
			var arrSpaces = finalString.split(" ");
			var formattedStr = "";
						
			for(var i=0; i<arrSpaces.length; i++)
			{
				if(arrSpaces[i] != "" && arrSpaces[i] != undefined)
					formattedStr += formatFirstLetterUpperCase(arrSpaces[i]);
				
				if(i != arrSpaces.length -1)
					formattedStr += " ";
			}			
			finalString = formattedStr;
		}
		else
		{
			finalString = formatFirstLetterUpperCase(finalString);
		}
		
		if(finalString.indexOf("-") >= 0)
		{			
			var arrSpaces = finalString.split("-");
			var formattedStr = "";
						
			for(var i=0; i<arrSpaces.length; i++)
			{
				if(arrSpaces[i] != "" && arrSpaces[i] != undefined)
					formattedStr += formatFirstLetterUpperCase(arrSpaces[i]);
				
				if(i != arrSpaces.length -1)
					formattedStr += "-";
			}			
			finalString = formattedStr;
		}
		
		return finalString;
	}
	else
	{
		return words;
	}
}

function formatFirstLetterUpperCase(lowerCaseStr){
	if(lowerCaseStr != "" && lowerCaseStr != undefined)
	{
		return lowerCaseStr.charAt(0).toUpperCase() + lowerCaseStr.substring(1);
	}
	else
	{
		return "";
	}
}

function createXmlFromString(xmlData){
		if (window.ActiveXObject) {
			//for IE
			xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
			xmlDoc.async="false";
			xmlDoc.loadXML(xmlData);
			return xmlDoc;
		} else if (document.implementation && document.implementation.createDocument) {
			//for Mozila
			parser=new DOMParser();
			xmlDoc=parser.parseFromString(xmlData,"text/xml");
			return xmlDoc;
		}
}

function dateFromUTC(dateString){
	var thisDate = new Date( parseInt(dateString ) * 1000 );
	return thisDate.toDateString();
}

function dateTimeFromUTC(dateString){
	var thisDate = new Date( parseInt(dateString ) * 1000 );
	return thisDate.toLocaleString();
}

var dateFormat = function () {
    var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
    timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
    timezoneClip = /[^-+\dA-Z]/g,
    pad = function (val, len) {
        val = String(val);
        len = len || 2;
        while (val.length < len) val = "0" + val;
        return val;
    };

    // Regexes and supporting functions are cached through closure
    return function (date, mask, utc) {
        var dF = dateFormat;

        // You can't provide utc if you skip other args (use the "UTC:" mask prefix)
        if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
            mask = date;
            date = undefined;
        }

        // Passing date through Date applies Date.parse, if necessary
        date = date ? new Date(date) : new Date;
        if (isNaN(date)) throw SyntaxError("invalid date");

        mask = String(dF.masks[mask] || mask || dF.masks["default"]);

        // Allow setting the utc argument via the mask
        if (mask.slice(0, 4) == "UTC:") {
            mask = mask.slice(4);
            utc = true;
        }

        var	_ = utc ? "getUTC" : "get",
        d = date[_ + "Date"](),
        D = date[_ + "Day"](),
        m = date[_ + "Month"](),
        y = date[_ + "FullYear"](),
        H = date[_ + "Hours"](),
        M = date[_ + "Minutes"](),
        s = date[_ + "Seconds"](),
        L = date[_ + "Milliseconds"](),
        o = utc ? 0 : date.getTimezoneOffset(),
        flags = {
            d:    d,
            dd:   pad(d),
            ddd:  dF.i18n.dayNames[D],
            dddd: dF.i18n.dayNames[D + 7],
            m:    m + 1,
            mm:   pad(m + 1),
            mmm:  dF.i18n.monthNames[m],
            mmmm: dF.i18n.monthNames[m + 12],
            yy:   String(y).slice(2),
            yyyy: y,
            h:    H % 12 || 12,
            hh:   pad(H % 12 || 12),
            H:    H,
            HH:   pad(H),
            M:    M,
            MM:   pad(M),
            s:    s,
            ss:   pad(s),
            l:    pad(L, 3),
            L:    pad(L > 99 ? Math.round(L / 10) : L),
            t:    H < 12 ? "a"  : "p",
            tt:   H < 12 ? "am" : "pm",
            T:    H < 12 ? "A"  : "P",
            TT:   H < 12 ? "AM" : "PM",
            Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
            o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
            S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
        };

        return mask.replace(token, function ($0) {
            return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
        });
    };
}();

// Some common format strings
dateFormat.masks = {
    "default":      "ddd mmm dd yyyy HH:MM:ss",
    shortDate:      "m/d/yy",
    mediumDate:     "mmm d, yyyy",
    longDate:       "mmmm d, yyyy",
    fullDate:       "dddd, mmmm d, yyyy",
    shortTime:      "h:MM TT",
    mediumTime:     "h:MM:ss TT",
    longTime:       "h:MM:ss TT Z",
    isoDate:        "yyyy-mm-dd",
    isoTime:        "HH:MM:ss",
    isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
    isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
    dayNames: [
    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
    "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
    ],
    monthNames: [
    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
    "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
    ]
};

// For convenience...
Date.prototype.format = function (mask, utc) {
    return dateFormat(this, mask, utc);
};

/*====Enums==============================*/

function getTeeDisplay(enumInt)
{
    switch (enumInt)
    {
        case 0:
            enumStr = 'Gold'; // "Red"
            break;
        case 1:
            enumStr = 'White';
            break;
        case 2:
            enumStr = 'Blue';
            break;
        case 3:
            enumStr = 'Black';
            break;
        default:
            enumStr = '';
            break;
    }
    return enumStr;
}

function getPinDisplay(enumInt)
{
    switch (enumInt)
    {
        case 0:
            enumStr = 'Easy';
            break;
        case 1:
            enumStr = 'Medium';
            break;
        case 2:
            enumStr = 'Hard';
            break;
        case 3:
            enumStr = 'Expert';
            break;
        default:
            enumStr = '';
            break;
    }
    return enumStr;
}

function getFairwayDisplay(enumInt)
{
    switch (enumInt)
    {
        case 0:
            enumStr = 'Slow';
            break;
        case 1:
            enumStr = 'Average';
            break;
        case 2:
            enumStr = 'Fast';
            break;
        case 3:
            enumStr = 'Lightning';
            break;

        default:
            enumStr = '';
            break;
    }
    return enumStr;
}

function getRoughDisplay(enumInt)
{
    switch (enumInt)
    {
        case 0:
            enumStr = 'Short';
            break;
        case 1:
            enumStr = 'Medium';
            break;
        case 2:
            enumStr = 'Long';
            break;
        case 3:
            enumStr = '???';
            break;

        default:
            enumStr = '';
            break;
    }
    return enumStr;
}

function getWindDisplay(enumInt)
{
    switch (enumInt)
    {
        case 0:
            enumStr = 'Calm';
            break;
        case 1:
            enumStr = 'Breezy';
            break;
        case 2:
            enumStr = 'Windy';
            break;
        case 3:
            enumStr = 'Gale Force';
            break;
        default:
            enumStr = '';
            break;
    }
    return enumStr;
}

function getGreenSpeedDisplay(enumInt)
{
    switch (enumInt)
    {
        case 0:
            enumStr = 'Slow';
            break;
        case 1:
            enumStr = 'Medium';
            break;
        case 2:
            enumStr = 'Fast';
            break;
        case 3:
            enumStr = 'Lightning';
            break;
        default:
            enumStr = '';
            break;
    }
    return enumStr;
}

function getGreenHardnessDisplay(enumInt)
{
    switch (enumInt)
    {
        case 0:
            enumStr = 'Soft';
            break;
        case 1:
            enumStr = 'Average';
            break;
        case 2:
            enumStr = 'Hard';
            break;
        case 3:
            enumStr = 'Very Hard';
            break;
        default:
            enumStr = '';
            break;
    }
    return enumStr;
}

function getHoleSelectionDisplay(enumInt)
{
    switch (enumInt)
    {
        case 0:
            enumStr = '18 Holes';
            break;
        case 1:
            enumStr = 'Front 9';
            break;
        case 2:
            enumStr = 'Back 9';
            break;
        case 3:
            enumStr = "Par 3 Holes";
            break;
        case 4:
            enumStr = "Par 4 Holes";
            break;
        case 5:
            enumStr = "Par 5 Holes";
            break;
        case 6:
            enumStr = "Custom Select";
            break;

        default:
            enumStr = '';
            break;
    }
    return enumStr;
}


/*====Critical flow=========================*/
function checkForCharacter()
{
    callGetWS(true, "/blaze/characters",
        WSRequestTimeout,
        null,
        function(xml, textStatus)
        {
            if($("errorName", xml).length > 0)
            {
                var errorName = $("errorName", xml).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(XMLHttpRequest, textStatus)
        {
        // no warning since this can occur if they navigate too quickly from the page
        //warn('Unable to retrieve character data:' + textStatus);
        },
        null);
}

function addNewUserScreen()
{
   spawnModalWindow('/users/newuser');
}
/*
function removeNewUserScreen()
{
    $('html, body').css({
        'overflow' : 'visible'
    });
    $('#newUserWrapper').remove();
}
*/
/*====Player card =========================*/
//called on any page that displays launcher with counter...
function loadFanCount()
{
	callGetWS(true, "/blaze/followers/", 
			WSRequestTimeout,
			null,
			function(xml,TextStatus)
			{
				followersXml = xml;	

				try
				{
					renderFollowersXml(xml);
				}
				catch(err)
				{
					// expected for pages that don't need to do special follower data handling
				}

				if($("errorName", xml).length == 0)
	    		{
                    var intFanCount = $("findplayers players playerstatus",xml).length;
					$("#follower-count").text(intFanCount + ' ' + (intFanCount === 1 ? 'Fan' : 'Fans') );
	    		}
	    		else
	    		{
	    			$("#follower-count").text("0 Fans");
	    		}		
			}, 
			function(XMLHttpRequest, textStatus, errorThrown)
			{
				$("#follower-count").text("-");
			}, 
			null);
}

function setRequestsCount()
{
	// no personal update data if we don't have a persona
	if (personaId != undefined)
	{
	   if ($("myplayercard getpetitions clubpetitionslist clubmessage", myPlayerCardXML).length > 0)
       {
	       $("#request-count").text('Inbox (' + $("myplayercard getpetitions clubpetitionslist clubmessage", myPlayerCardXML).length + ')');
	   }
	   else {
           $("#request-count").text('Inbox (0)');
	   }
	}
}

function updateLevelInPlayerCard () {
    var level = '0';

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

    callGetWS(true, "/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();
    	// update fan count
	    loadFanCount();
		//request count
        callGetWS(true, '/blaze/myplayercard',
            WSRequestTimeout,
            null,
	        function(xml, textStatus)
            {
                if (textStatus !== 'error') {
                    myPlayerCardXML = xml;
                    loadPlayerInfo();
                    loadPlayerExp();
            	    setRequestsCount();
                    loadMyCutLine();
                    loadPlayerSkillLevel();
                    loadPlayerOpenGames();
                    
                    try
                    {
                    	renderPagePlayerCardData();
                    }
                    catch(err)
                    {
                    	// expected for pages not doing page specific things with the player card data
                    }
                }
	    		else
	    		{
	    			// TODO: dash out all the fields set above to show server error
	    		}
            },
            function(XMLHttpRequest, textStatus)
            {
            	// TODO: dash out all the fields set above to show server error
            },
            null);
    }
}

function loadPlayerInfo()
{
	$('.my_persona').html('Welcome ' + personaName +'!');
	var timeStamp = new Date().getTime();
	$("#imagePlayerCardAvatar").attr("src", '/players/avatarsbyid/' + personaId + '/' + timeStamp);
}


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



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']['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', myPlayerCardXML).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', myPlayerCardXML).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']['coursemasteryid'] = $('coursemasterylevelid', val).text();
			characterprogress['currenttitle']['coursemasterycount'] = $('coursemasterynumbercourses', val).text();
                return false;
            }
	});
           
	//get the next numeric level
	$('getcharacterprogressiontable characterprogressionlevels characterprogressionlevel', myPlayerCardXML).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']['coursemasteryid'] = $('coursemasterylevelid', val).text();
			characterprogress['nextlevel']['coursemasterycount'] = $('coursemasterynumbercourses', val).text();
			return false;
        }
	});

	//get the next title level
	$('getcharacterprogressiontable characterprogressionlevels characterprogressionlevel', myPlayerCardXML).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']['coursemasteryid'] = $('coursemasterylevelid', val).text();
			characterprogress['nexttitle']['coursemasterycount'] = $('coursemasterynumbercourses', val).text();
        
			return false;
		}
    });

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

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

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

	//set player card data
	$('#player_card .user_level').text(characterprogress['currenttitle']['title']);
//	$('#player_card .level-icon-s').text(characterprogress['currentlevel']['level']);
	$('#player_card .xp_count').text(formatLargeNumbers(characterprogress['currentlevel']['xp'])+' XP');
	$('#player_card .my_title').text(characterprogress['currenttitle']['title']);
	$('#player_card .my_level').text(characterprogress['currentlevel']['level']);

	// 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: loadCutLine
function loadCutLine () {

    var cutline = parseInt($('getcutline cutline', myPlayerCardXML).text(), 10);

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

    $('.cutline_today').html(playerCutLine.toString());
}

// Function: loadMyCutLine
//  Calls /blaze/mycutline to retrieve the cutline for the logged in user.
var myCutLine = Array();
	
function loadMyCutLine () {
    var cutline        = parseInt($('getmycutline cutline', myPlayerCardXML).text(), 10) / 100;
    var level          = parseInt($('getmycutline level',   myPlayerCardXML).text(), 10);
    var score          = parseInt($('getmycutline score',   myPlayerCardXML).text(), 10);
    var streak         = parseInt($('getmycutline streak',  myPlayerCardXML).text(), 10);
    var timeRemaining  = parseInt($('getmycutline 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" />');

    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()
{
    callGetWS(true, "/nucleus/mywallets",
        WSRequestTimeout,
        null,
        function(xml, textStatus)
        {
    		$('.my_wallet_balance').html('-');
            $(xml).find("walletAccount").each(function()
            {
                var currency = $(this).find("currency").text();
                if (currency == '_TB')
                {
                    var cash = $(this).find("balance").text();
                    userMoney = cash;
                    $('.my_wallet_balance').html('$'+formatLargeNumbers(cash));
                }
            });
        },
        function(XMLHttpRequest, textStatus)
        {
            $('.my_wallet_balance').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('-');
    }
}

var activeGameId = -1;
var activeTournamentRoundId = -1;
var isActiveGameMultiplayer = -1;
var isActiveGameTournament = -1;


function loadPlayerOpenGames()
{ 
    //If there is data
    if($("getactivegames", myPlayerCardXML).length > 0)
    {
    	
        activeGameId = $("gameid", myPlayerCardXML).text();
        activeTournamentRoundId = $("getactivegames tournamentroundid", 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();
    callGetWS(true, "/blaze/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;
}





/*===================Subscriptions==========================*/
function updateSubscriptionCookie(successCallback, errorCallback){
	if(ignoreSubscriptions != "1"){
		callGetWS(true, "/nucleus/entitlements/",
				WSRequestTimeout,
				null,
				function(data,TextStatus){
					var subscriptionInfo = "";
					var teeTimeInfo = "";
					var teeTimeCount = 0;
					var eaInfo = "";
					var betaInfo = "";
					var cookieString = "freetoplay|0";
					
					$("entitlement", data).each(function(i){
							if($("groupName", this).text() == "TIGERONLINE" && $("status", this).text() == "ACTIVE")
							{
								if($("entitlementTag", this).text() == "TIGERSUBSCRIPTION")
								{
									subscriptionInfo = "subscription";
								}
								else if($("entitlementTag", this).text() == "TIGERTEETIMES")
								{
									var useEntitlement = false;
									
									if($("terminationDate", this).text() == "")
									{
										useEntitlement = true;
									}
									else
									{
										var termArray = $("terminationDate", this).text().split("T");																		
										var termDateArray = termArray[0].split("-");
										var termYear = parseInt(termDateArray[0]);
										var termMonth = parseInt(termDateArray[1]);
										var termDay = parseInt(termDateArray[2]);										
										var nowDate = new Date();
										
										if(termYear > nowDate.getFullYear())
										{
											useEntitlement = true;
										}
										else if(termYear == nowDate.getFullYear())
										{
											if(termMonth > nowDate.getMonth() + 1)
											{
												useEntitlement = true;
											}
											else if(termMonth == nowDate.getMonth() + 1)
											{
												if(termDay >= nowDate.getDate())
												{
													useEntitlement = true;
												}
											}
										}
									}
																		
									if( useEntitlement )
									{
										teeTimeInfo = "freetoplay|";
										teeTimeCount += parseInt( $("useCount",this).text() );
									}
								}
								else if($("entitlementTag", this).text() == "TIGERUNLIMITED")
								{
									eaInfo = "tigerUnlimited";
								}
							}
							else if($("groupName", this).text() == "TIGERONLINEPCBETA" && $("status", this).text() == "ACTIVE")
							{
								if($("entitlementTag", this).text() == "tiger-woods-online-beta")
								{
									betaInfo = "betaEnabled";
								}
							}
					});

					if(eaInfo != "")
						cookieString = eaInfo;
					else if(betaInfo != "")
						cookieString = betaInfo;
					else if(subscriptionInfo != "")
						cookieString = subscriptionInfo;
					else if(teeTimeInfo != "")
						cookieString = teeTimeInfo + teeTimeCount;
					
					setCookie("TWOCookie[SUBSCRIPTION]", cookieString, null);
					if(successCallback != null)
						successCallback(cookieString);
					setupTopNav();
				}, function(){
					try
					{
						errorCallback("");
					}catch(Err){}
				}, null);
	}
	else
	{
		var cookieString = "tigerUnlimited";

		setCookie("TWOCookie[SUBSCRIPTION]", cookieString, null);
		if(successCallback != null)
			successCallback(cookieString);
		setupTopNav();
	}
}

// Function: close_modal
//  Hides the overlay mask and all .modal_container class divs.
function close_modal () {
    //hide the mask
    $('#mask').hide();

    //hide modal window(s)
    $('.modal_container').hide();

     // Reset the close button position
    $('.modal .close').css({top: '-4000px'}, 1000);
 }

// Function: show_modal
//  Fades in a modal window as well as the overlay mask behind the window.
//
// Parameters:
//  modal_id - DOMElement id of modal to show
function show_modal (modal_id) {

    //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);

    $('#'+modal_id).appendTo(document.body);

    //show the modal window
    $('#'+modal_id).fadeIn(500);


     // Animate the close button into view:
    $('.modal .close').animate({top: '-12px'}, 800);
    // Give it a little bounce:
    $('.modal .close').animate({top: '-17px'}, 100);

 }

/*----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();
    });
};
