/*************************************************************************************************
 *  pubbase.js                                                                                   *
 *  Copyright 2009 Skill Technology, LLC                                                         *
 *                                                                                               *
 *  Author:  Matt Haak                                                                           *
 *  Website: http://www.skilltechnology.com                                                      *
 *                                                                                               *
 *  This contains JavaScript used by both the GimmeGolf public site and web application. There   *
 *  are 3 sections:                                                                              *
 *    I.   CONSTANTS - Constant variables that are used by both the public site and web          *
 *         application                                                                           *
 *    II.  COMMON FUNCTIONS - Functions that don't have general usefulness in JavaScript         *
 *         applications, but are used by both the public site and the web application            *
 *    III. ACTION FUNCTIONS - There is only one action (interaction with server) that is shared  *
 *         between the public site and web app: GET_BESTS_BY_COURSE_ACTION                       *
 *                                                                                               *
 *  pubbase.js MUST be loaded after http.js (which defines the HTTP object used here) but before *
 *  external.js and any web application JavaScript files which use the actionResponseHandler     *
 *  object. The toAbsScore() and toAbsScoreByName() functions as well as the                     *
 *  GET_BESTS_BY_COURSE_ACTION are dependent on a/js/jsconfig.jsp.                               *
 *                                                                                               *
 *  Note that the HOLE_MASK object has been moved to common.js.                                  *
 *                                                                                               *
 *  ~                                                                                            *
 *                                                                                               *
 *  I. CONSTANTS                                                                                 *
 *                                                                                               *
 *  These constants are used by both the public site and web application.                        *
 *************************************************************************************************/

var UPDATE_SESSION_ACTION = "updateSession";
var KEEP_ALIVE_ACTION = "keepAlive";
var CHAT_ACTION = "chat";
var CREATE_LOBBY_ACTION = "createLobby";
var LOBBY_INVITER_ACTION = "lobbyInviter";
var START_GAME_ACTION = "startGame";
var JOIN_LOBBY_ACTION = "joinLobby";
var LEAVE_LOBBY_ACTION = "leaveLobby";
var FIND_LOBBY_ACTION = "findLobby";
var SIGN_UP_ACTION = "signUp";
var SET_STATUS_ACTION = "setStatus";
var SET_CHAR_ID_ACTION = "setCharId";
var FIND_ACTION = "find";
var ADD_BUDDY_ACTION = "addBuddy";
var REMOVE_BUDDIES_ACTION = "removeBuddies";
var GET_PROFILE_ACTION = "getProfile";
var SAVE_ACCOUNT_PROFILE_ACTION = "saveAccountProfile";
var SAVE_ACCOUNT_SETUP_ACTION = "saveAccountSetup";
var REFRESH_STATUSES_ACTION = "refreshStatuses";
var FIND_GAMES_ACTION = "findGames";
var FIND_HISTORY_ACTION = "findHistory";
var REMOVE_GAME_ACTION = "removeGame";
var GET_MINI_PROFILE_ACTION = "getMiniProfile";
var GET_GAME_DETAILS_ACTION = "getGameDetails";
var RECORD_ERROR_ACTION = "recordError";
var INVALIDATE_SESSION_ACTION = "invalidateSession";
var FORGOT_PW_ACTION = "forgotPW"
var GET_BESTS_BY_COURSE_ACTION = "getBestsByCourse";
var FIND_TRX_ACTION = "findTrx";
var SET_EXPRESS_CHECKOUT_ACTION = "setExpressCheckout";
var CREATE_RECURRING_PAYMENTS_PROFILE_ACTION = "createRecurringPaymentsProfile";
var CANCEL_SUBSCRIPTION_ACTION = "cancelSubscription";
var GET_BALANCES_ACTION = "getBalances";
var WITHDRAWAL_ACTION = "withdrawal";
var LIST_TOURNS_ACTION = "listTourns";
var ENTER_TOURN_ACTION = "enterTourn";
var CLIENT_KEY_EVENT_REG_ACTION = "clientKeyEventReg";

var COMPLETED_CONDITION = "COMPLETED";
var ERROR_GENERAL_CONDITION = "ERROR_GENERAL";
var ERROR_ACTION_CONDITION = "ERROR_ACTION";
var DEBUG_CONDITION = "DEBUG";


/*************************************************************************************************
 *  II. COMMON FUNCTIONS                                                                         *
 *                                                                                               *
 *  These functions don't have general usefulness in any JavaScript application, but are used    *
 *  by both the GimmeGolf public site and the web application.                                   *
 *************************************************************************************************/

var console_auto_scroll = true;

function toggleConsoleAutoScroll() {
	console_auto_scroll = !console_auto_scroll;
}

function toConsole(txt) {
	var now = new Date();
	var time_stamp = '[';
	time_stamp += now.getYear() + '-';
	time_stamp += (now.getMonth()+1).toString().replace(/^(\d)$/,"0$1") + '-';
	time_stamp += now.getDate().toString().replace(/^(\d)$/,"0$1") + ' ';
	time_stamp += now.getHours().toString().replace(/^(\d)$/,"0$1") + ':';
	time_stamp += now.getMinutes().toString().replace(/^(\d)$/,"0$1") + ':';
	time_stamp += now.getSeconds().toString().replace(/^(\d)$/,"0$1") + '] ';
	var new_entry = document.createElement('<p>');
	new_entry.innerHTML = time_stamp + txt;
	var cc = document.getElementById('console_content');
	cc.appendChild(new_entry);
	if (console_auto_scroll)
		cc.scrollTop = cc.scrollHeight;
}

function clearConsole() {
	put('','console_content');
}

function hideConsole() {
	hide('console');
}

function showConsole() {
	show('console');
}

function submitLoginForm() {

	var login_btn_elmt = document.getElementById('login_btn');
	if (login_btn_elmt)
		login_btn_elmt.className = 'login_btn_working';

	var parameters = {};
	parameters.action = UPDATE_SESSION_ACTION;

	player_name_elmt = document.getElementById('login_fld_player_name');
	player_passwd_elmt = document.getElementById('login_fld_player_passwd');

	if (player_name_elmt != undefined) {
		parameters.player_name = player_name_elmt.value;
		parameters.player_passwd = player_passwd_elmt.value;
	} else {
		var login_form = document.forms['login_form'];
		parameters.player_name = login_form.elements['player_name'].value;
		parameters.player_passwd = login_form.elements['player_passwd'].value;
	}
	
	parameters.browser_metrics = getBrowserMetrics();

	HTTP.get(parameters);
	return false;
}

function clearActionError(action) {
	actionError(action, null);
}

function actionError(action, msg) {
	try {
		var error_alerts_div = document.getElementById(action + '_alerts');
		if (msg!=null) {
			// alert('Hi: ' + (error_alerts_div.innerHTML == msg));
			if (error_alerts_div.innerHTML == msg) {
				shake(action + '_alerts', true, 5);
			} else {
				error_alerts_div.innerHTML = msg;
			}
		} else
			error_alerts_div.innerHTML = '';
		error_alerts_div.style.display = (msg!=null)?'block':'none';
	} catch (e) {
		if (msg!=null)
			generalError(msg);
		// else, who cares about clearing something that isn't there?
	}
}

function shake(elmnt_id, to_right, diminish, distance_px, flash_elmt_id, flash_base_color, flash_bright_color) {
	if (!distance_px)
		distance_px = 6;
	var elmnt = document.getElementById(elmnt_id);
	elmnt.style.marginLeft = (to_right ? distance_px + "px" : "-" + distance_px + "px");
	elmnt.style.marginRight = (to_right ? "-" + distance_px + "px" : distance_px + "px");
	
	var flash_elmt = null;
	var flash_elmt_id_call = 'null';
	var flash_base_color_call = 'null';
	var flash_bright_color_call = 'null';
	if (flash_elmt_id) {
		flash_elmt = document.getElementById(flash_elmt_id);
		flash_elmt_id_call = '\'' + flash_elmt_id + '\'';
		flash_base_color_call = '\'' + flash_base_color + '\'';
		flash_bright_color_call = '\'' + flash_bright_color + '\'';
		flash_elmt.style.color = (!to_right ? flash_base_color : flash_bright_color);
	}
	
//	elmnt.style.textDecoration = (to_right ? "underline" : "none");
	diminish--;
	var next_to_right = (to_right ? "false" : "true");
	if (diminish > 0) {
		setTimeout("shake('" + elmnt_id + "'," + next_to_right + "," + diminish + "," + distance_px + "," + flash_elmt_id_call + "," + flash_base_color_call + "," + flash_bright_color_call + ")", 100);
	} else {
		elmnt.style.marginLeft = "0px";
		elmnt.style.marginRight = "0px";
		if (flash_elmt)
			flash_elmt.style.color = flash_base_color;
//		elmnt.style.textDecoration = "none";
	}
}

function generalError(msg) {
	var inner_html = '<img src="imgs/close.gif" width="13" height="13" class="general_alert_closer" ';
	inner_html += 'onClick="clearGeneralError()">' + msg;
	showMsgRow('general_errors','general_error_msg',inner_html);
//	document.getElementById('general_error_msg').innerHTML = inner_html;
//	try { document.getElementById('general_errors').style.display = 'table-row'; }
//	catch (e) { document.getElementById('general_errors').style.display = 'block'; }
}

function clearGeneralError() {
	hideMsgRow('general_errors','general_error_msg');
//	document.getElementById('general_error_msg').innerHTML = '';
//	document.getElementById('general_errors').style.display = 'none';
}

function showMsgRow(row_elmnt_id, msg_elmnt_id, msg_html) {
	document.getElementById(msg_elmnt_id).innerHTML = msg_html;
	showRow(row_elmnt_id);
	try { sizeDivs(); } catch (e) {}
}

function hideMsgRow(row_elmnt_id, msg_elmnt_id) {
	document.getElementById(msg_elmnt_id).innerHTML = '';
	hide(row_elmnt_id);
	try { sizeDivs(); } catch (e) {}
}

function handleHttpError(status, statusText) {
	alert('There was an error communicating with the server via scripted HTTP: \n' + status + '\n' + statusText);
}

function validateResponse(response) {
	if ( window.DDOC && DDOC.$('screen_lock') )
		DDOC.hideById('screen_lock');

	try {
		if (response.condition != COMPLETED_CONDITION) { throw response; }
		if (response.msg != null && response.msg != '')
			generalError(response.msg);
		return true;
	} catch(e) {
		if ( e == response )  { handleResponseGenerically(response); }
		else { alert('Unrecognized actionResponseHandler exception: ' + e); } // shouldn't happen
	}
	return false;
}

var account_locked_msg_showing = false;

function handleResponseGenerically(response) {
	if ( window.DDOC && DDOC.$('screen_lock') )
		DDOC.hideById('screen_lock');
	
	try {
		
		if (! (response.condition && response.action && response.msg) ) {throw -1}
		if ( response.condition == ERROR_GENERAL_CONDITION ||
				response.condition == DEBUG_CONDITION ) {
			if (response.msg.indexOf('ACCOUNT_LOCKED') == 0) {
				var msg_stmt = response.msg.substr(15);
				try {
					showGoGGHome();
					var inner_html = document.getElementById('go_gg_home_panel').innerHTML;
					inner_html = msg_stmt + '<br>&nbsp;<hr size="1" noshade>&nbsp;<br>' + inner_html;
					put(inner_html, 'go_gg_home_panel');
					show('go_gg_home');
					show('blackout');
					account_locked_msg_showing = true;
				} catch (e) {
					generalError(response.msg.substr(15));
				}
			} else if (response.msg.indexOf('UNAUTHORIZED') == 0) {
				try {
					if (!account_locked_msg_showing) {
						show('go_gg_home');
						show('blackout');
						// alert('Calling showGoGGHome because response is UNAUTHORIZED');
						showGoGGHome();
						toConsole(response.msg);
					}
				} catch (e) {
					generalError(response.msg.substr(13));
				}
			} else
				generalError(response.msg);
		} else if (response.condition == ERROR_ACTION_CONDITION) {
			actionError(response.action, response.msg);
		} else {
			alert('Error: Unknown server response condition:\n' + response);
	}	}
	catch (e) {
		alert('Error: Got invalid response object from the server.\n' +
			'response.condition: ' + response.condition + '\n' +
			'response.action: ' + response.action + '\n' +
			'response.msg: ' + response.msg + '\n\n' + e.message);
	}
}

function submitLoginEnter(myfield,e) {
	var keycode;
	if (window.event)
		keycode = window.event.keyCode;
	else if (e)
		keycode = e.which;
	else
		return true;
	
	if (keycode == 13) {
		return submitLoginForm();
	} else
		return true;
}

/*************************************************************************************************
 *  III. ACTION-RELATED FUNCTIONS                                                                *
 *                                                                                               *
 *  The only action that is shared between the public site and web app is                        *
 *  GET_BESTS_BY_COURSE_ACTION                                                                   *
 *************************************************************************************************/

var actionResponseHandler = {};
var lowLevelResponseTextHandler = {};

var ALL_TIME_MODE = 0;
var WEEK_MODE = 1;
actionResponseHandler[GET_BESTS_BY_COURSE_ACTION] = function(response) {
	if (validateResponse(response)) {

		var wifr = null;
		var dm = DDOC;
		var table_width = '';

		if (response.passthru) {
			if (response.passthru.wifr) {
				wifr = response.passthru.wifr;
				dm = wifr.getDomManipulator();
			}
			if (response.passthru.wide_tables)
				table_width = ' width="100%"';
		}
			
		var courses = response.payload.bests_by_course;
		var mode = response.payload.mode;

		var bests_div_id = (mode == WEEK_MODE ? 'weekly_bests_breif_cell' : 'all_time_bests_breif_cell');
		var bests_div = dm.getElementById(bests_div_id);

		var this_week_start = getThisWeekStart();
		var title_text = (mode == WEEK_MODE ?
				'Week of ' + days[this_week_start.getDay()] + '. ' +
				months[this_week_start.getMonth()] + '. ' + this_week_start.getDate() :
				'All Time');

		var inner_html = "";
		var first = true;

		if (bests_div != undefined) { // this block is called for "brief" standings

			if (mode == ALL_TIME_MODE)
				title_text = 'All Time Best Scores';

			inner_html += '<table border="0" cellspacing="1"' + table_width + '><tr><td colspan="3" class="course_head_cell">' +
				title_text + '</td></tr>';
				
			for (var course_name in courses) {
				first = false;

				inner_html += '<tr><td class="stat_label">' + course_name + '</td>';

				var best_scores = courses[course_name];
				var first_place_name;
				var first_place_score;
				var addnl_first_placers = -1;
				for (var i=0; i<best_scores.length; i++) {
					if (addnl_first_placers == -1) {
						first_place_name = best_scores[i].player_name;
						first_place_score = best_scores[i].score_rtp;
					}
					if (best_scores[i].place == 1)
						addnl_first_placers++;
					else
						break;
				}
				
				inner_html += '<td class="stat_label">' + first_place_name;
				if (addnl_first_placers > 0)
					inner_html += ' (+' + addnl_first_placers + ')';
				inner_html += '</td><td class="stat_cell">' + toScoreHtml(first_place_score) + '</td></tr>';
				
			}

			if (first)
				inner_html += '<tr><td colspan="3" class="stat_cell"><i>No games completed yet.</i></td></tr>';

			inner_html += '</table>';


		} else { // this block is called for the fuller stats listing

			bests_div_id = (mode == WEEK_MODE ? 'weekly_bests_cell' : 'all_time_bests_cell');
			bests_div = dm.getElementById(bests_div_id);
			inner_html += '<b>' + title_text + '</b>';
	
			for (var course_name in courses) {
				var course_id = COURSE_NAME_ID[course_name];
				var course_id_key = 'course_id_' + course_id;
			
				if (first)
					first = false;
				else
					inner_html += '<br>';
				inner_html += '<table border="0" cellspacing="0"' + table_width + '><tr><td colspan="3" class="course_head_cell" align="left">' +
					'<table border="0" align="left"><tr><td>' +
					'<img src="../a/imgs/' + escape('course ' + course_name + ' sm notxt.jpg') + '" width="40" height="40" style="display:block;border:1px solid #f4e7da">' +
					'</td><td align="left">' + course_name + ' (Par&nbsp;' + COURSE_ID_PAR[course_id_key] + ')</td></tr></table></td></tr>';
				var best_scores = courses[course_name];
				prev_place = 999;
				for (var i=0; i<best_scores.length; i++) {
					var place_html = best_scores[i].place != prev_place ? toOrdinal(best_scores[i].place) : '';
					inner_html += '<tr>' +
						'<td class="stat_label" width="25%">' + place_html + '</td>' +
						'<td class="stat_label">' + best_scores[i].player_name + '</td>' +
						'<td class="stat_cell" width="15%">' + toAbsScore(course_id, best_scores[i].score_rtp) + '</td>' +
						'</tr>';
					prev_place = best_scores[i].place;
				}
				inner_html += '</table>';
			}
			if (first)
				inner_html += '<br><i>No games completed yet.</i>';
		}

		bests_div.innerHTML = inner_html;
		
		if (wifr != null) {
			wifr.hide();
			wifr.show();
		}
	}
}

if (window.slp)
	slp(5);