//Globals

// Namespace: EA.Tiburon.TWo
// Create a namespace that can optionally be used when creating new
// objects (and hopefully will be used site-wide in the future):
var EA = {};
    EA.Tiburon = {};
    EA.Tiburon.TWO = {};

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

var personaName, personaId;
var omnitureId = 'No ID';

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



//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();	
    setupToolTips();    
    setupScrollToTop();
	//setupPlayerCard();
	setupProfileAccordion();
    setupTabs();
    checkAuthentication();
	setupSubNav();	
	setupModalWindow();
});


// 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').val('').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));
	        $("#passwordField").attr("value", "");
	        $("#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' );
            }
	    	  //$("#passwordField").attr("value", "");
            $("#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 == '/users/nopersona');
    		if (!onPersonaPage)
    		{
    			document.location = '/users/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();
	
		    // reset messages/requests count
		    getFollowingCount();
		    setRequestsCount();
			
			// 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();
        }catch(er){}
    }
}

//Loads the cookie used to set persona info
function loadPersonaCookie(){
    var fullPersona = urldecode(getCookie('TWOCookie[PERSONA]'));
		
    if(fullPersona)
    {
        var arrCookie = fullPersona.split("&");
        for(var i=0; i<arrCookie.length; i++)
        {
            if(arrCookie[i].toLowerCase().indexOf("personaid") == 0)
            {
                personaId = arrCookie[i].substr(arrCookie[i].indexOf("=")+1);
            }
            else if(arrCookie[i].toLowerCase().indexOf("personaname") == 0)
            {
                personaName = arrCookie[i].substr(arrCookie[i].indexOf("=")+1);
            }
            else if(arrCookie[i].toLowerCase().indexOf("omnitureid") == 0)
            {
                omnitureId = arrCookie[i].substr(arrCookie[i].indexOf("=")+1);
            }
        }
    }
}

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

function logoutOfSite(){
    try{
        logOutAndCleanUp();
    }
    catch(err){}
	
    document.location = "/users/logout?surl="+document.location;  //Wrong address
}


/*====WebServices===========================*/
function callGetWS(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 callSyncGetWS(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 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===========================*/
function spawnModalWindow(content) {
	
	var modalWindow = "";
	modalWindow += "\
		<div id='modal-wrapper'>\
			<div id='modal-window'>\
				<table id='borders'>\
					<tr>\
						<td class='tl'></td>\
						<td class='tc'></td>\
						<td class='tr'></td>\
					</tr>\
					<tr>\
						<td class='lc'></td>\
						<td class='content' valign='top'><iframe src="+ content +" scrolling='no' frameborder='0' ></iframe></td>\
						<td class='rc'></td>\
					</tr>\
					<tr>\
						<td class='bl'></td>\
						<td class='bc'></td>\
						<td class='br'></td>\
					</tr>\
				</table>\
				<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 setupModalWindow() {
	$('a.modal').click(function() {
		hideUnity();
		var goHere = $(this).attr('rel');
		spawnModalWindow(goHere);
	});
}

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

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


//Removing Open/Closed Bc I dont Think They Want It
//function setupPlayerCard(){
    // Open / Close Player Card
//    $('.card_toggle a').toggle(function() {
//        $('.card_toggle a').html('Open Player Card');
//        $('#toggle_content').hide();
//        $('.green').addClass('closed');
//    }, function () {
//        $('.card_toggle a').html('Close Player Card');
//        $('#toggle_content').show();
//        $('div.green').removeClass('closed');
//    });
//}

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

/*====EncodingDecoding==================*/
function urldecode( str ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Philip Peterson
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: AJ
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir
    // %          note: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
    // *     example 1: urldecode('Kevin+van+Zonneveld%21');
    // *     returns 1: 'Kevin van Zonneveld!'
    // *     example 2: urldecode('http%3A%2F%2Fkevin.vanzonneveld.net%2F');
    // *     returns 2: 'http://kevin.vanzonneveld.net/'
    // *     example 3: urldecode('http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a');
    // *     returns 3: 'http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'
    if (str != null)
    {
	    var histogram = {};
	    var ret = str.toString();
	    
	    var replacer = function(search, replace, str) {
	        var tmp_arr = [];
	        tmp_arr = str.split(search);
	        return tmp_arr.join(replace);
	    };
	    
	    // The histogram is identical to the one in urlencode.
	    histogram["'"]   = '%27';
	    histogram['(']   = '%28';
	    histogram[')']   = '%29';
	    histogram['*']   = '%2A';
	    histogram['~']   = '%7E';
	    histogram['!']   = '%21';
	    histogram['%20'] = '+';
	 
	    for (replace in histogram) {
	        search = histogram[replace]; // Switch order when decoding
	        ret = replacer(search, replace, ret) // Custom replace. No regexing   
	    }
	    
	    // End with decodeURIComponent, which most resembles PHP's encoding functions
	    ret = decodeURIComponent(ret);
	 
	    return ret;
    }
    else
    {
    	return null;
    }
}

/*	Base64 encoding	*/
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function encode64(input) {
    input = escape(input);
    var output = "";
    var chr1, chr2, chr3 = "";
    var enc1, enc2, enc3, enc4 = "";
    var i = 0;
	
    do {
        chr1 = input.charCodeAt(i++);
        chr2 = input.charCodeAt(i++);
        chr3 = input.charCodeAt(i++);
	
        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;
	
        if (isNaN(chr2)) {
            enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
            enc4 = 64;
        }
	
        output = output +
        keyStr.charAt(enc1) +
        keyStr.charAt(enc2) +
        keyStr.charAt(enc3) +
        keyStr.charAt(enc4);
        chr1 = chr2 = chr3 = "";
        enc1 = enc2 = enc3 = enc4 = "";
    } while (i < input.length);
	
    return output;
}



/*====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 formatScores(nStr)
{
	if(parseInt(nStr) == 9999 || parseFloat(nStr) == 9999.00)
	{
		return "--";
	}
	else
	{
		return formatLargeNumbers(nStr);
	}
}

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



/*====Errors============================*/
function openErrorWindow(info, type, 
    errorCode, location, courseId, hole, equipment, apparel,
    operatingSystem, processorCount, processorType, systemMemorySize,
    graphicsDeviceVendor, graphicsDeviceName,  graphicsMemorySize, graphicsDeviceVersion,
    supportsShadows, supportsImageEffects, supportsVertexPrograms, supportsRenderTextures, supportsARGB32RenderTextureFormat, supportsDepthRenderTextureFormat)
{	
    var DELIM = '|';
	
    // game specific info
    gameInformation = //info + DELIM +
    errorCode + DELIM +
    location + DELIM +
    courseId + DELIM +
    hole + DELIM +
    equipment + DELIM +
    apparel;
	
    // system/browser info
    systemInformation = navigator.appName + ' ' + navigator.appCodeName; // browser
    systemInformation += DELIM + navigator.appVersion; // browser version
    //systemInformation += DELIM + navigator.platform;
    //systemInformation += DELIM + navigator.language;
    systemInformation += DELIM + operatingSystem + DELIM + processorCount + DELIM + processorType + DELIM + systemMemorySize + DELIM +
    graphicsDeviceVendor + DELIM + graphicsDeviceName + DELIM + graphicsMemorySize + DELIM + graphicsDeviceVersion + DELIM + supportsShadows + DELIM + supportsImageEffects + DELIM + supportsVertexPrograms + DELIM + supportsRenderTextures + DELIM + supportsARGB32RenderTextureFormat + DELIM + supportsDepthRenderTextureFormat;
	
    //save information to a cookie
    setCookie("TWOCookie[game_info]", escape(gameInformation), null);
    setCookie("TWOCookie[system_info]", escape(systemInformation), null);

    //open reporting window
    var newWin;
    try
    {
        newWin = window.open('/reports/' + type, 'errorwindow', 'toolbar=0,menubar=0,statusbar=1,resizable=1,scrollbars=1,width=625,height=600');
    }
    catch(err)
    {
    	// ignore errors?
    }
	
    if (newWin)	
    {
        newWin.focus();
    }
    else
    {
        alert("You appear to have pop-ups blocked for this site,\n in order to report an error you have to have pop-up blocking turned off");
    }
	
}

function openComplaintWindow(type, subject, blazeObjectId, blazeId, details)
{	
    var DELIM = '|';
	
    //open reporting window
    var newWin;
    try
    {
    	var encodedDetails = details.length > 0 ? encode64(details) : ''; 
        newWin = window.open('/complaints/' + type + '/' + subject + '/' + blazeObjectId + '/' + blazeId + '/' + encodedDetails, 'errorwindow', 'toolbar=0,menubar=0,statusbar=1,resizable=1,scrollbars=1,width=625,height=600');
    }
    catch(err)
    {
    	// ignore errors?
    }
	
    if(newWin)
    {
        newWin.focus();
    }
    else
    {
        alert("You appear to have pop-ups blocked for this site,\n in order to report an error you have to have pop-up blocking turned off");
    }
}



/*====Cookies===========================*/
function getCookie(name) 
{
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
	
    for(var i=0; i < ca.length; i++) 
    {
        var c = ca[i];
        while (c.charAt(0)==' ')
       	{
        	c = c.substring(1,c.length);
       	}
        if (c.indexOf(nameEQ) == 0) 
        {
        	return c.substring(nameEQ.length,c.length);
        }
    }
    return null;
}

function setCookie(name, value, expDateStr) 
{
    var cookieString = name + "=" + value + ";path=/;";
    if (expDateStr) 
    {
        document.cookie = cookieString + "expires=" + expDateStr;
    } 
    else 
    {
        document.cookie = cookieString;
    }
}

function deleteCookie(name) 
{
	document.cookie = name + "=;path=/;" + new Date().toGMTString();
}


/*====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();
                        },
                        function(XMLHttpRequest, textStatus)
                        {
                        	// warn('Unable to retrieve character data.');
                        },
                        null);
                }
            }
        },
        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 getFollowingCount()
{
	callGetWS(true, "/blaze/getfollowers/", 
			WSRequestTimeout, 
			null, 
			function(data,TextStatus){
				followersXml = data;	
				
				try{
					renderFollowersXml(data);
				}catch(err){}
				
				$("#follower-count").text( $("findplayers players playerstatus",data).length );
				
			}, function(XMLHttpRequest, textStatus, errorThrown){
				$("#followingCount a span").text("x");
			}, null);
}

function setRequestsCount()
{
	// no personal update data if we don't have a persona
	if (personaId != undefined)
	{
	    // update group petition requests count
	    callGetWS(true, "/blaze/mypetitions/0",
	        WSRequestTimeout,
	        null,
	        function(data, textStatus)
	        {
	            $("#request-count").text($("clubmessage", data).length);            
	        },
	        function(XMLHttpRequest, textStatus)
	        {
	            $("#request-count").text('-');
	        },
	        null);
	}
}

function loadPlayerCard()
{
	// no personal update data if we don't have a persona
	if (personaId != undefined)
	{
	    loadPlayerInfo();
	    loadPlayerCardCash();
	    loadPlayerSkillLevel();
	    loadPlayerOpenGames();
	}
}

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

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()
{
    callGetWS(true, "/blaze/stats",
        WSRequestTimeout,
        null,
        function(xml, textStatus)
        {
            //If there is data
            if($("getstat keyscopestatsvaluemap", xml).length > 0)
            {
            	var avgScore = $("entitystats statvalues statvalues:eq(0)", xml).text();
                $('.my_average_score').html(formatScores(avgScore));
                
                var roundsComplete = $("entitystats statvalues statvalues:eq(17)", xml).text();
                $('.my_rounds_complete').html(roundsComplete);
            }
            else
            {
                $('.my_average_score').html('--');
                $('.my_rounds_complete').html('--');
            }
		
        },
        function(XMLHttpRequest, textStatus)
        {
            $('.my_average_score').html('--');
            $('.my_rounds_complete').html('--');
        },
        null);
}

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


function loadPlayerOpenGames()
{
    callGetWS(true, "/blaze/activegame",
            WSRequestTimeout,
            null,
            function(xml, textStatus)
            {
                //If there is data
                if($("getgamestate", xml).length > 0)
                {
                	activeGameId = $("gameid", xml).text(); 
                	activeTournamentRoundId = $("tournamentroundid", xml).text();
                	
                	isActiveGameMultiplayer = $("ismultiplayergame", xml).text() == '1';
                	isActiveGameTournament = $("istournamentgame", xml).text() == '1';
                	
                	
                	var name = $("coursename", xml).text();
                	var hole = parseInt($("hole", xml).text()) - 1; 
                	var score = parseInt($("score", xml).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/gameresume/' + 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/gameresume/' + 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(xml);
                }
              	catch(err)
              	{
              		// expected for pages w/o game data specific stuff
              	}
            },
            function(XMLHttpRequest, textStatus)
            {
            	// nothing since we get 'errors' if we interrupt a request
            	try{
            		renderPageActiveGameData(null);
            	}catch(err){}
            },
            null);
	
}

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;
            $("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>');
				$("#courseNavList").append('<li class="' + web + '"><a href="/courses/' + web + '">' + name + '</a></li>');
            });
            
            // do any page specific course stuff if it exists
            try{
            	renderPageCourses(xml);
            }catch(err){}
        },
        function(XMLHttpRequest, textStatus)
        {
            $("#courseDropDown").html();
            $("#courseNavList").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;
}