/* xpscore.js - javascript for the XPWebScore server
 * $Id: xpscore.js,v 1.7 2007/08/28 05:18:30 dick Exp $
 *
 * $Log: xpscore.js,v $
 * Revision 1.7  2007/08/28 05:18:30  dick
 * Align for 3 digit playtimes.
 * Alter the formula to generate rank.
 *
 * Revision 1.6  2007/02/07 05:42:45  dick
 * Force seconds to be 2 digits. (08).
 *
 * Revision 1.5  2007/02/06 04:59:59  dick
 * Add lastVisit handling.
 *
 * Revision 1.4  2007/02/06 03:10:30  dick
 * Good parsing and sorting of the table.
 *
 * Revision 1.3  2007/01/28 21:44:55  dick
 * Display sorted columns.
 *
 * Revision 1.2  2007/01/28 04:43:59  dick
 * Read the Player data from the server and display it as preformatted lines.
 *
 * Revision 1.1  2007/01/25 06:03:37  dick
 * More XPWebScore skeleton checkin.
 *
 */

var trDEBUG = false;
var tableDEBUG = false;

var players = new Array();
var initializing = false;
var request = null;
var serverUrl = "ajax.do";
var refreshTimer = 0;

var hideRobots	= false;
var showPids	= true;

var SORTRANK		= 0;
var SORTPID			= 1;
var	SORTNICK		= 2;
var SORTSCORE		= 3;
var SORTKILLS		= 4;
var	SORTDEATHS		= 5;
var	SORTKDRATIO		= 6;
var SORTRATING		= 7;
var SORTSESSIONS	= 8;
var SORTPLAYTIME	= 9;
var SORTLASTVISIT	= 10;

var sortType = SORTRATING;

function Player() {
	this.pid = -1;
	this.nick = "";
	this.score = "0";
	this.kills = "0";
	this.deaths = "0";
	this.sessions = "0";
	this.playTime = "0";
	this.playerType = 0;
	this.kdRatio = 0;
	this.rating = 0;
	this.lastVisit = 0;
}

Player.prototype.getPlayTimeString = function() {
		var h = Math.floor(this.playTime/60/60);
		var m = Math.floor((this.playTime-(h*60*60))/60);
		var s = (this.playTime-(h*60*60)-(m*60))/60;
		var b = "";
		if (h < 100) b = " ";
		if (h < 10) h = "0" + h.toFixed(); else h = h.toFixed();
		if (m < 10) m = "0" + m.toFixed(); else m = m.toFixed();
		if (s < 10) s = "0" + s.toFixed(); else s = s.toFixed();
		return("" + b + h + ":" + m + ":" + s);
}

Player.prototype.getLastVisitString = function() {
	if (this.lastVisit == null)
		return("");
	var sb = new StringBuffer();
	sb.append(p.lastVisit.getFullYear());
	if (p.lastVisit.getMonth()+1 < 10)
		sb.append("0");
	sb.append(p.lastVisit.getMonth()+1);
	if (p.lastVisit.getDate() < 10)
		sb.append("0");
	sb.append(p.lastVisit.getDate());
	sb.append("-");
	if (p.lastVisit.getHours() < 10)
		sb.append("0");
	sb.append(p.lastVisit.getHours());
	sb.append(":");
	if (p.lastVisit.getMinutes() < 10)
		sb.append("0");
	sb.append(p.lastVisit.getMinutes());
	sb.append(":");
	if (p.lastVisit.getSeconds() < 10)
		sb.append("0");
	sb.append(p.lastVisit.getSeconds());

	return(sb.toString());
}

////////////////////////////////////////////////////////////////////////////////
function homeLoad() {
	//alert("Hi mom");
	mainEntryPoint();
	window.setInterval(mainEntryPoint, 1000);
	refreshTimer = refreshDelay;
}

////////////////////////////////////////////////////////////////////////////////
function updateCountdownDiv() {
	var div = document.getElementById("Countdown");
	div.innerHTML = refreshTimer + ' seconds until <a href=""  onclick="doRefresh(); return(false);">refresh</a>';

}

////////////////////////////////////////////////////////////////////////////////
// Load the players
function mainEntryPoint() {
	if (this.initializing == true)
		return;
	--refreshTimer;
	updateCountdownDiv();
	if (refreshTimer <= 0) {
		refreshTimer = refreshDelay;
		updateCountdownDiv();
		request = xmlRequest();
		if (request) {
			initializing = true;
			var stopID = setTimeout("stopLoadData()",20000);
			var theDate = new Date();
			var responseFunc = "playerDataOnLoad("+stopID+");";
			this.request.onreadystatechange = function() { eval(responseFunc) };
			try {
				this.request.open("GET", serverUrl, true);
				this.request.send("");
			} catch(e) {alert (e);}
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
function stopLoadData() {
    if (initializing) {
    	request.abort();
    	//alert("stopLoadData");
    }
    initializing = false;
}

////////////////////////////////////////////////////////////////////////////////
function playerDataOnLoad(stopID) {
	var data;
	var div;
	var i, j;
    //  If data is completely loaded
	if (request.readyState == 4) {
		initializing = false;
		//  If return status is OK
		try {
			if (request.status == 200) {
				clearTimeout(stopID);
				// alert("data=" + request.responseText);
				response = request.responseXML.documentElement;

				// Players
				players = new Array();
				parsePlayerList(response);
				//alert("parsed players");
				displayPlayers();

				// Sysdom
				/*
				var sysdom = response.getElementsByTagName('System');
				sysdom = sysdom[0];
				var _date = null;
				try {
					_date = sysdom.getElementsByTagName("date")[0].firstChild.data;
				} catch (e) {alert(e);}
				if (_date != null) {
					div = document.getElementById("Date");
					div.innerHTML = _date;
				}
				_status = null;
				try {
					_status = sysdom.getElementsByTagName("refreshDelay")[0].firstChild.data;
				} catch (e) {}
				if (_status != null) {
					refreshDelay = _status;
				}
				*/
				return;
			}
		} catch (e) {
			if (trDEBUG) alert("crash out: " + e);
		}
		displayScoreServerDown();
	}
}
////////////////////////////////////////////////////////////////////////////////
function displayScoreServerDown() {
	var s = "<span class=\"red\">Score Server down</span>";
	div = document.getElementById("scoreTable");
	div.innerHTML = s;
}			

////////////////////////////////////////////////////////////////////////////////
function displayPlayers() {
	sortPlayers();
	var sb = buildPlayerList();
	div = document.getElementById("scoreTable");
	div.innerHTML = sb.toString();
	sb.dispose();
}

////////////////////////////////////////////////////////////////////////////////
function doHideRobotsClick() {
	hideRobots = !hideRobots;
	div = document.getElementById("robotToggleText");
	if (hideRobots)
		div.innerHTML = "Show Robots";
	else
		div.innerHTML = "Hide Robots";
	
	displayPlayers();
}

////////////////////////////////////////////////////////////////////////////////
function parsePlayerList(response) {
	var pl, xmlPlayers, i;
	var tableBorder = "";
	if (tableDEBUG)
		tableBorder = " border=\"1\" ";
	//alert("data='" + data);
	//var response = GXml.parse(data);
	//alert("response=" + response);
	xmlPlayers = response.getElementsByTagName('Player');
	//alert("player count=" + xmlPlayers.length);
	for (i=0; i<xmlPlayers.length; i++) {
		pl = xmlPlayers[i];
		//alert("pl = " + pl);
		var _pid = 0, _nick = "???", _playerType = 0, _score = 0, _kills = 0,
			_deaths = 0, _sessions = -1, playTime = 0, _lastVisit = 0;
		try {
			_pid = pl.getElementsByTagName("pid")[0].firstChild.data;
		} catch (e) {}
		try {
			_nick = pl.getElementsByTagName("nick")[0].firstChild.data;
		} catch (e) {}
		try {
			_playerType = pl.getElementsByTagName("playerType")[0].firstChild.data;
		} catch (e) {}
		//alert("_playerType=" + _playerType);

		p = new Player();
		p.pid = _pid;
		p.nick = _nick;
		p.playerType = _playerType;
		p.lastVisit = null;
/*		p.score = 0;
		p.kills = 0;
		p.deaths = 0;
		p.sessions = 0;
		p.playTime = 0;
		p.kdRatio = 0;
		p.rating = 0;
*/
		var ssList = pl.getElementsByTagName("Ss");
		if (ssList.length > 0) {
			var ssTag = ssList[0];
			//alert("ssTag = " + ssTag);
			try {
				_score = ssTag.getElementsByTagName("score")[0].firstChild.data;
			} catch (e) {}
			try {
				_kills = ssTag.getElementsByTagName("kills")[0].firstChild.data;
			} catch (e) {}
			try {
				_deaths = ssTag.getElementsByTagName("deaths")[0].firstChild.data;
			} catch (e) {}
			try {
				_sessions = ssTag.getElementsByTagName("sessions")[0].firstChild.data;
			} catch (e) {}
			try {
				_playTime = ssTag.getElementsByTagName("playTime")[0].firstChild.data;
			} catch (e) {}
			try {
				_lastVisit = ssTag.getElementsByTagName("lvisit")[0].firstChild.data;
			} catch (e) {}
			p.score = _score;
			p.kills = _kills;
			p.deaths = _deaths;
			p.sessions = _sessions;
			p.playTime = _playTime;
			p.kdRatio = p.deaths != 0 ? p.kills / p.deaths : p.kills * 1 ;
			p.rating = (p.kdRatio / 400) + (p.score / 400) + (p.kills/250);
			p.lastVisit = new Date(Number(_lastVisit));
		}
		//alert("pid=" + _pid + " nick=" + _nick);
		players[p.pid] = p;
	}
}

////////////////////////////////////////////////////////////////////////////////
function buildPlayerList() {
//	alert("build");
	var sb = new StringBuffer();
	sb.append('   ');
	if (showPids)
		sb.append('<pre>    <a href="" onclick="doSortByPid(); return(false);">Pid</a>');
	sb.append(' <a href="" onclick="doSortByNick(); return(false);">Nick</a>');
	sb.append('                 <a href="" onclick="doSortByScore(); return(false);">Score</a>');
	sb.append('   <a href="" onclick="doSortByKdRatio(); return(false);">K/D</a>');
	sb.append('   <a href="" onclick="doSortByKills(); return(false);">Kills</a>');
	sb.append(' <a href="" onclick="doSortByDeaths(); return(false);">Deaths</a>');
	sb.append('  <a href="" onclick="doSortByRating(); return(false);">Rating</a>');
	sb.append('  <a href="" onclick="doSortBySessions(); return(false);">Sessns</a>');
	sb.append('   <a href="" onclick="doSortByPlayTime(); return(false);">Playtime</a>');
	sb.append('  <a href="" onclick="doSortByLastVisit(); return(false);">Last Visit</a>\n');
	for (i=0, r=1; i<=players.length; i++) {
		p = players[i];
		if (!p)
			continue;
		if (hideRobots && p.playerType == 2)
			continue;
		if (p.playerType == 2)
			sb.append('<span class="robgrey">');
		prepend(sb, 3, "" + r++);
		if (showPids)
			prepend(sb, 4, p.pid);
		sb.append(" ");
		append(sb, 17, p.nick);
		prepend(sb, 9, p.score);
		prepend(sb, 6, p.kdRatio.toFixed(2));
		prepend(sb, 8, p.kills);
		prepend(sb, 7, p.deaths);
		prepend(sb, 8, p.rating.toFixed(2));
		prepend(sb, 8, p.sessions);
		sb.append("  " + p.getPlayTimeString());
		sb.append("  " + p.getLastVisitString());
		if (p.playerType == 2)
			sb.append('</span>');
		sb.append("\r\n");
	}
	sb.append("</pre>");
	return(sb);
}

////////////////////////////////////////////////////////////////////////////////
function append(sb, width, text) {
	sb.append(text);
	var i;
	for (i=text.length; i<width; i++)
		sb.append(" ");
	
}

////////////////////////////////////////////////////////////////////////////////
function prepend(sb, width, text) {
	var i;
	for (i=text.length; i<width; i++)
		sb.append(" ");
	sb.append(text);
}

function doSortByPid() { sortType = SORTPID; displayPlayers(); }
function doSortByRating() { sortType = SORTRATING; displayPlayers(); }
function doSortByNick() { sortType = SORTNICK; displayPlayers(); }
function doSortByScore() { sortType = SORTSCORE; displayPlayers(); }
function doSortByKdRatio() { sortType = SORTKDRATIO; displayPlayers(); }
function doSortByKills() { sortType = SORTKILLS; displayPlayers(); }
function doSortByDeaths() { sortType = SORTDEATHS; displayPlayers(); }
function doSortBySessions() { sortType = SORTSESSIONS; displayPlayers(); }
function doSortByPlayTime() { sortType = SORTPLAYTIME; displayPlayers(); }
function doSortByLastVisit() { sortType = SORTLASTVISIT; displayPlayers(); }

function doRefresh() { refreshTimer = 0; mainEntryPoint(); }

////////////////////////////////////////////////////////////////////////////////
function sortPlayers() {
	if (sortType == SORTRANK)
		players.sort(sortByRank);
	else if (sortType == SORTPID)
		players.sort(sortByPid);
	else if (sortType == SORTNICK)
		players.sort(sortByNick);
	else if (sortType == SORTKDRATIO)
		players.sort(sortByKdRatio);
	else if (sortType == SORTKILLS)
		players.sort(sortByKills);
	else if (sortType == SORTDEATHS)
		players.sort(sortByDeaths);
	else if (sortType == SORTRATING)
		players.sort(sortByRating);
	else if (sortType == SORTSESSIONS)
		players.sort(sortBySessions);
	else if (sortType == SORTPLAYTIME)
		players.sort(sortByPlayTime);
	else if (sortType == SORTLASTVISIT)
		players.sort(sortByLastVisit);
	else
		players.sort(sortByScore);
}

function sortByPid(a,b) {	return(a.pid - b.pid); }
function sortByScore(b,a) {
	if (a.score != b.score)
		return(a.score - b.score); 
	if (a.rating != b.rating)
		return(a.rating - b.rating);
	return(a.pid - b.pid);
}
function sortByKills(b,a) {
	if (a.kills != b.kills)
		return(a.kills - b.kills);
	if (a.deaths != b.deaths)
		return(b.deaths - a.deaths);
	if (a.rating != b.rating)
		return(a.rating - b.rating);
	return(a.pid - b.pid);
}
function sortByDeaths(b,a) {
	if (a.deaths != b.deaths)
		return(a.deaths - b.deaths); 
	if (a.kills != b.kills)
		return(a.kills - b.kills);
	if (a.rating != b.rating)
		return(a.rating - b.rating);
}
function sortByKdRatio(b,a) { 
	if (a.kdRatio != b.kdRatio)
		return(a.kdRatio - b.kdRatio); 
	if (a.kills != b.kills)
		return(a.kills - b.kills);
	if (a.score != b.score)
		return(a.score - b.score);
	return(a.pid - b.pid);
}
function sortBySessions(b,a) {
	return(a.sessions - b.sessions); 
}
function sortByPlayTime(b,a) {
	if (a.playTime != b.playTime)
		return(a.playTime - b.playTime); 
	return(sortByRating(b,a));
}
function sortByNick(a,b) {
	if (a.nick < b.nick)
		return(-1);
	if (a.nick > b.nick)
		return(1);
	return(0);
}
function sortByRating(b,a) {
	if (a.rating != b.rating)
		return(a.rating - b.rating);
	return(sortByKdRatio(b,a));
}

function sortByLastVisit(a,b) {
	if (a.lastVisit == null && b.lastVisit == null)
		return(sortByPid(b,a));
	if (a.lastVisit == null)
		return(-1);
	if (b.lastVisit == null)
		return(1);
	return(b.lastVisit.getTime() - a.lastVisit.getTime());
}
