//
// UIFStats.js
// --
// Script to make JavaScript-based XML client-server requests
// to dynamically load and sort statistics tables
//

	// Navigation stack
	var navigation = new Array();
	var navigation_pointer = -1;

	// For dynamic html
	var tables = Array();
	
	// HTTP images directory
	var ls_baseimages = '/lib/share/uifstats/images/';
	
	var nocache = 0;	// disable caching
	var debug = 0;		// debugging

	// URL to jsrs handler script
	var jsrs_handler = '/lib/share/uifstats/UIFStats_handler.php';


//
// Create the XML event handler
// --
//
	
	SAXEventHandler = function() {
		this.characterData = ""; 
	}

	SAXEventHandler.prototype.characters = function(data, start, length) {
		this.characterData += data.substr(start, length);
	}
	

	SAXEventHandler.prototype.endElement = function(name) {
		this._handleCharacterData();
		
	}

	SAXEventHandler.prototype.startCDATA = function(name) {
		this._handleCharacterData();
		tables["current"]["incdata"] = true;
	}

	SAXEventHandler.prototype.endCDATA = function(name) {
		this._handleCharacterData();
		tables["current"]["incdata"] = false;
	}
	
	// Start element
	SAXEventHandler.prototype.startElement = function(name, attrs) {
		this._handleCharacterData();

		var attrsnew = new Array();
		for (var i = 0; i < attrs.getLength(); i++) {
			attrsnew[attrs.getName(i)] = attrs.getValue(i);
		}
		attrs = attrsnew;

		// Error message
		if (name == 'error') {
			alert(attrs["msg"]);
		}

		// Table title
		if (name == 'infstats') {
			if (attrs["name"]) {
				tables["current"]["title"] = attrs["name"];
			}
		}		
		
		// Header
		if (name == 'header') {
			tables["current"]["numheaders"]++;	
			tables["current"]["headers"][tables["current"]["numheaders"]] = new Array();
			tables["current"]["headers"][tables["current"]["numheaders"]] = attrs;
			if (attrs["defaultsort"] == "true") {
				tables["current"]["defaultsort"] = attrs["id"];
			}
			if (attrs["reversesort"] == "true") {
				tables["current"]["reversesort"][attrs["id"]] = true;
			}
		}	
		
		// Navigation
		if (name == 'nav') {
			tables["current"]["navigationindex"].push(attrs["link"]);
			tables["current"]["navigation"][attrs["link"]] = attrs["value"];
		}
		
		// Start a row
		if (name == 'row' && attrs["type"] != "hidden") {
			tables["current"]["numrows"]++;
			tables["current"]["rows"][tables["current"]["numrows"]] = new Array();
			if (attrs["groupby"]) {
				if (!tables["current"]["groups"][attrs["groupby"]]) {
					tables["current"]["groups"][attrs["groupby"]] = new Array();
					tables["current"]["groupindex"].push(attrs["groupby"]);
					//alert('New group');
				}
				tables["current"]["groups"][attrs["groupby"]].push(tables["current"]["numrows"]);
				//alert('Adding ' + (tables["current"]["numrows"]) + ' to the array');
			}
		}
		
		// Cell inside a row
		if (name == 'cell' && attrs["type"] != "hidden") {
			var value = '';
			var id = '';
			tables["current"]["rows"][tables["current"]["numrows"]][attrs["id"]] = attrs;
		}
	}
		
	SAXEventHandler.prototype._fullCharacterDataReceived = function(fullCharacterData) {
//		alert(fullCharacterData);
//		if (tables["current"]["incdata"]) {
			tables["current"]["html"] = tables["current"]["html"] + fullCharacterData;
//		}
	}
	
	SAXEventHandler.prototype._handleCharacterData = function()  {
		if (this.characterData != "") {
			this._fullCharacterDataReceived(this.characterData);
		}
		//reset the characterData variable
		this.characterData = "";
	}


/*
 * Table construction functions
 * --
 **/

	// Reset the temp variables
	function resetvars() {
		tables["current"] = new Array();
		tables["current"]["headers"] = new Array();
		tables["current"]["rows"] = new Array();
		tables["current"]["groups"] = new Array();	
		tables["current"]["groupindex"] = new Array();		
		tables["current"]["reversesort"] = new Array();
		tables["current"]["navigation"] = new Array();
		tables["current"]["navigationindex"] = new Array();		
		tables["current"]["title"] = '';
		tables["current"]["numrows"] = 0;
		tables["current"]["numheaders"] = 0;
	}

	function ls_prev() {
		if (navigation_pointer <= 0) {
			//alert('Error!  You cannot go backwards from here.');
		}
		else {
			navigation_pointer = navigation_pointer - 1;
			loadTable(navigation[navigation_pointer], 0, 1);
		}
	}
	
	function ls_next() {
		if (navigation_pointer >= navigation.length - 1) {
			//alert('Error!  You cannot go forwards from here.');
		}
		else {
			navigation_pointer = navigation_pointer + 1;
			loadTable(navigation[navigation_pointer], 0, 1);
		}
	}

	function ls_enableNext() {
		next = document.getElementById('livestatsnext');
		next.src = ls_baseimages + 'icon_arrowright.png';
	}
	
	function ls_disableNext() {
		next = document.getElementById('livestatsnext');
		next.src = ls_baseimages + 'icon_arrowright_dis.png';
	}
	
	function ls_enablePrev() {
		prev = document.getElementById('livestatsprev');
		prev.src = ls_baseimages + 'icon_arrowleft.png';
	}
	
	function ls_disablePrev() {
		prev = document.getElementById('livestatsprev');
		prev.src = ls_baseimages + 'icon_arrowleft_dis.png';		
	}

	function ls_setStatus(msg) {
		box = document.getElementById('livestatsstatus');
		box.value = msg;
	}

	function loadType(type) {
		loadTable(type);
	}

	// Fetch a stat table if it's not already in the cache
	function loadTable(type, force, nopointerinc) {

		if (!nopointerinc) {
			navigation_pointer++;
			navigation[navigation_pointer] = type;
		}
		
		// Enable navigation buttons
		if (navigation.length >= 1 && navigation_pointer != 0) {
			ls_enablePrev();
		}
		else {
			ls_disablePrev();
		}
		if (navigation_pointer < navigation.length - 1) {
			ls_enableNext();
		}		
		else {
			ls_disableNext();
		}

		// Save current table to cache and instantiate new one
		if (tables["current"]) {
			tables[tables["current"]["id"]] = tables["current"];
		}
		resetvars();
		tables["current"]["id"] = type;

		// Reload page from cache
		if (tables[type] && !nocache && !force) {
			tables["current"] = tables[type];
			display();
		}

		// Fetch the page and cache it
		else {
			ls_setStatus('One moment please...');
			jsrsExecute(jsrs_handler, translateXML, 'loadTable', type, false);
		}

	}
	
	function debugmsg(text) {
		if (debug) {
			text = 	'numheaders: ' + tables["current"]["numheaders"] + "\n" +
					'numrows: ' + tables["current"]["numrows"] + "\n\n" +
					text;
			
			debug = document.getElementById('livestatsdebug');
			debug.value = text;	
		}
	}

	function translateXML(XML) {
		var parser = new SAXDriver();
		var eventHandler = new SAXEventHandler();
		ls_setStatus('Building display table...');
		parser.setDocumentHandler(eventHandler);
		parser.setLexicalHandler(eventHandler);
		parser.setErrorHandler(eventHandler);
		parser.parse(XML);
		ls_setStatus('');
		
		//div = document.getElementById('debug');
		//div.value = XML;

		if (tables["current"]["defaultsort"]) {
			sortBy(tables["current"]["defaultsort"]);
		}
		else {
			display();
		}
		debugmsg(XML);
	}

	// Display the current loaded stats
	function display() {
		var html;
		
		tables["current"]["divider"] = '';

		html = '<h3>' + tables["current"]["title"] + ' &gt;</h3>';

		if (tables["current"]["navigationindex"].length > 0) {
			html = html + '<p>Click on drop down menu to select stats.</p>';
		}

		//alert(tables["current"]["html"]);
		if (tables["current"]["html"]) {
			s = new String(tables["current"]["html"]);
			s = s.replace(/\^\^/g, "<");
			s = s.replace(/\$\$/g, ">");
			s = s.replace(/\[CDATA\[/g, "");
			s = s.replace(/undefined/g, "");
			s = s.replace(/\]\]/g, "");
			html = html + s;
		}

		html = html + '<table cellpadding="0" cellspacing="0" border="0">';
		html = html + tableNav("current");
		
		// Headers
		html = html + '<tr>';
		for (var i = 1; i <= tables["current"]["numheaders"]; i++) {
			var header = tables["current"]["headers"][i];
			if (header["onsortdivideby"] && tables["current"]["sort"] == header["id"]) {
				tables["current"]["divider"] = header["id"];
			}
			if (header["nosort"]) {
				html = html + '<th>' + header["value"] + '</th>';
			}
			else {
				align = 'left';
				if (header["align"]) {
					align = header["align"];
				}
				if (header['id'] == tables["current"]["sort"]) {					
					html = html + '<th class="' + align + 'sortby"><a href="JavaScript:sortBy(\'' + header["id"] +
						'\')">' + header["value"] + '</a></th>';
				}
				else {
					html = html + '<th class="' + align + 
						'"><a href="JavaScript:sortBy(\'' + header["id"] + '\')">' + header["value"] + '</a></th>';
				}
			}
		}
		html = html + '</tr>';

		groups =  tables["current"]["groupindex"];
		if (groups.length > 0) {
			for (var i = 0; i < groups.length; i++) {
				html = html + '<tr><td class="group" colspan="' + tables["current"]["numheaders"] + 
					'">' + groups[i] + ' &gt;</td></tr>';
				for (k = 0; k < tables["current"]["groups"][groups[i]].length; k++) {
					node = tables["current"]["groups"][groups[i]][k];
					html = html + ls_getRowHtml(node);
				}
			}
		}
		else {
			for (i = 1; i <= tables["current"]["numrows"]; i++) {
				html = html + ls_getRowHtml(i);
			}	
		}
		
		// Close table
		html = html + '</table>';

		html = html + '<p style="font-family: arial; font-size: 7pt">ID: ' + tables["current"]["id"] + '</p>';

		panel = document.getElementById('livestatspanel');
		panel.innerHTML = html;

		// Post rendering...  do highlights
		if (tables["current"]["select_row"] && tables["current"]["select_col"]) {
			ls_highlight(tables["current"]["select_row"], tables["current"]["select_col"]);
		}

	}
	
	function ls_getRowHtml(node) {
		var html = '';
		if (tables["current"]["divider"]) {
			var div = tables["current"]["rows"][node][tables["current"]["divider"]]["value"];
			if (div != tables["current"]["divider_buffer"]) {
				tables["current"]["divider_buffer"] = div;
				html = html + '<tr><td class="divider" colspan="' + tables["current"]["numheaders"] + 
					'">&nbsp;</td></tr>';
			}
		}
		html = html + '<tr>';
		for (x = 1; x <= tables["current"]["numheaders"]; x++) {
			var header = tables["current"]["headers"][x];
			var cell = tables["current"]["rows"][node][header["id"]];
			var value = cell["value"];
			var cellclass = '';
			if (cell["link"]) {
				value = '<a href="JavaScript:loadTable(\'' + cell["link"] + '\')">' + value + '</a>';
			}
			if (header["isbold"]) {
				value = '<b>' + value + '</b>';
			}
			if (cell["align"]) {
				cellclass = 'align="' + cell["align"] + '" ';
			}
			html = html + '<td ' + cellclass + '>' + value + '&nbsp;</td>';
		}
		html = html + '</tr>';
		return html;
	}
	
	// Reload a stat table
	function ls_reload(table) {
		loadTable(table, 1);
	}
	
	// Clear a selection
	function ls_clearSelect(table) {
		for (i = 1; i <= tables["current"]["numheaders"]; i++) {
			cell = document.getElementById('lscell_' + tables["current"]["select_row"] + '_' + i);
			if (cell) {
					cell.bgColor = '#ffffff';
			}
		}
		for (i = 1; i <= tables["current"]["numrows"]; i++) {
			cell = document.getElementById('lscell_' + i + '_' + tables["current"]["select_col"]);
			if (cell) {
					cell.bgColor = '#ffffff';
			}
		}
		tables["current"]["select_row"] = 0;
		tables["current"]["select_col"] = 0;
	}
	
	// Highlight
	function ls_highlight(row, col) {
		ls_clearSelect("current");
		tables["current"]["select_row"] = row;
		tables["current"]["select_col"] = col;		
		for (i = 1; i <= tables["current"]["numheaders"]; i++) {
			cell = document.getElementById('lscell_' + row + '_' + i);
			if (cell) {
					cell.bgColor = '#f5f5f5';
			}
		}
		for (i = 1; i <= tables["current"]["numrows"]; i++) {
			cell = document.getElementById('lscell_' + i + '_' + col);
			if (cell) {
					cell.bgColor = '#f5f5f5';
			}
		}	
		//alert('Highlighting row ' + row + ' col ' + col);
	}
	
	// The comparison function sortBy() uses...  differentiates between numbers and strings,
	// as well as supports the reversesort cell property
	function sortBy_compare(node1, node2, field) {
		if (node1.match(/[0-9]+/) && node2.match(/[0-9]+/)) {
			node1 = Number (node1);
			node2 = Number (node2);
		}
		if (tables["current"]["reversesort"][field]) {
			reverseSort = 1;
		}
		else {
			reverseSort = 0;
		}
		if ((reverseSort && node1 <= node2) || (!reverseSort && node1 >= node2)) {
			return 1;
		}
		else {
			return 0;
		}
	}
	
	// Sort by field, then redisplay the table
	function sortBy(field) {
		ls_setStatus('One moment please...');
		ls_clearSelect("current");
		tables["current"]["sort"] = field;		
		groups =  tables["current"]["groupindex"];
		if (groups.length > 0) {
			for (i = 0; i < groups.length; i++) {
				for (j = 0; j < tables["current"]["groups"][groups[i]].length; j++) {
					for (k = 0; k < tables["current"]["groups"][groups[i]].length; k++) {
						node1 = tables["current"]["rows"][
								tables["current"]["groups"][groups[i]][j]
								]
						node2 = tables["current"]["rows"][
								tables["current"]["groups"][groups[i]][k]
								]
						if (sortBy_compare(node1[field]["value"], node2[field]["value"], field)) {
							temp = tables["current"]["groups"][groups[i]][j];
							tables["current"]["groups"][groups[i]][j] = tables["current"]["groups"][groups[i]][k];
							tables["current"]["groups"][groups[i]][k] = temp;
						}
					}
				}
			}
		}
		else {
			for (i = 1; i <= tables["current"]["numrows"]; i++) {
				for (k = 1; k <= tables["current"]["numrows"]; k++) {
					if (sortBy_compare(tables["current"]["rows"][i][field]["value"], tables["current"]["rows"][k][field]["value"], field)) {
						temp = tables["current"]["rows"][i];
						tables["current"]["rows"][i] = tables["current"]["rows"][k];
						tables["current"]["rows"][k] = temp;
					}
				}
			}
		}
		ls_setStatus('');		
		display();
	}

	// Build the table navigation
	function tableNav(table) {
		var html = 	'<tr>' +
					'<td colspan="' + tables[table]["numheaders"] + '" class="livestatstablenav">';

		// Navigation
		if (tables["current"]["navigationindex"].length > 0) {
			html = html + '<div class="livestatssubnav"><select ' + 
				'onChange="loadTable(this.options[this.selectedIndex].value)" ' +
				'><option value="">-- Select Stats --</option>';
			for (var i = 0; i < tables[table]["navigationindex"].length; i++) {
				if (tables["current"]["id"] == tables[table]["navigationindex"][i]) {
					selected = 'selected';
				}
				else {
					selected = '';
				}
				html = html + '<option ' + selected + ' value="' + tables[table]["navigationindex"][i] + '">' +
					tables[table]["navigation"][tables[table]["navigationindex"][i]] + '</option>';
			}
			html = html + '</select></div>';
		}					
					
		html = html + '</td>' + 
					'</tr>';
		return html;
	}

