/*

------------
Installation
------------

Call jaxTableRegister() during your document's onLoad() event to add a sortable
table to your document.  The table will be appended to the element specified by 
you, and will bear dimensions + look and feel as described by the jax-table.css 
file.  Some steps you'll need to follow to get it working:

	1) include jax-table.js in your html (via <script> tag),
	2) include common/jax-xmlhttprequest.js  in your html (via <script> tag),
	3) include the contents of jax-table.css in your html or other css 
	   file (via <style> or <link> tags),
	4) in the body of your html have a tag with an id (preferably a <div> tag),
	5) call jaxTableRegister() on document load,
	6) write a server-side response script that gathers stored content (like
	   from a database) and returns it.

Parameter descriptions for jaxTableRegister():

	contentURL: url that returns an xml feed to populate the table
	id:         id of the element (preferably div) to append table to

Additional functionality - you can gain additional functionality by calling the
following functions prior to the jaxTableRegister() function:

	1) jaxTableShowEdit        < the url to send a 'get' with id, allows user to edit file/folder
	2) jaxTableShowDelete      < the url to send a 'get' with id, allows user to delete file/folder

-------
Credits
-------

Authored by Dan Juliano in August of 2005.

*/

var jaxTableHeight = 0;
var jaxTableWidth = 0;
var jaxTableSortID = null;
var jaxTableSortIndex = -1;
var jaxTableSortDown = false;

var jaxTableTitles = null;
var jaxTableRecords = null;

var jaxTableFolderEditURL = null;
var jaxTableFolderDeleteURL = null;
var jaxTableSuppressId = false;
var jaxTableLinkColumn = -1;
var jaxTableLinkURL = "";
var jaxTableDateColumn = -1;
var jaxTableDateClassName = "";

function jaxTableRegister(contentURL, id) {
	jaxTableBuildContainer(id);
	xmlRequest(contentURL, null, jaxTableReturnXML);
}

function jaxTableBuildContainer(id) {
	var html = "";
	html += "<div id=\"table_loading\">Loading</div>";
	html += "<div id=\"table_container\"></div>";
	document.getElementById(id).innerHTML = html;
	jaxCommonLoadingMessageReset("table_loading", "table_container");
}

// Callback method for xmlRequest().
function jaxTableReturnXML(xml) {

	// Check to see if relevant xml data is present.
	jaxCommonLoadingMessageHide("table_loading");
	if (xml.getElementsByTagName("list_titles").length == 0) {
		document.getElementById("table_container").innerHTML = "<p>No records to display</p>";
		return;
	}
	
	// Transfer DOM to a set of arrays.
	jaxTableReadTitles(xml);
	jaxTableReadData(xml);
	
	// Create a table for viewing data.
	jaxTableCreateTable();
	jaxTableDecorateTable();
	jaxTableSort(jaxTableSortID);
	
	var x = Array("table_td", "table_td_highlight");
	highlightInit(x, 0);
}

// Create a two dimensional array to hold a mapping
// between tags and titles for column headers.
function jaxTableReadTitles(xml) {
	var titles = xmlFindChild(xml, "list_titles");
	var records = titles.getElementsByTagName("record");
	
	// Example titles xml node:
	// 	<list_titles>
	// 		<record>ID</record>
	// 		<record>First Name</record>
	// 		<record>Last Name</record>
	// 	</list_titles>
	
	jaxTableTitles = Array();
	for (var i = 0; i < records.length; i++) {
		if (records[i].nodeType == 1) {
			jaxTableTitles[jaxTableTitles.length] = records[i].firstChild.nodeValue;
		}
	}
}

// Create a two dimensional data array from the xml DOM.
function jaxTableReadData(xml) {
	
	// Example data record:
	//  <record>
	//    <a1>001</a1>
	//    <a2>Daniel</a2>
	//    <a3>Juliano</a3>
	//  </record>
	//
	// Where the <a1> tag will translate to a title "ID", <a2> will translate
	// to title "First Name", and <a3> will translate to title "Last Name".  We 
	// do this for two reasons:
	//  1) Titles can contain spaces and capitalization, abstracted from
	//     xml tags which cannot
	//  2) Xml tags like <a1> and <a2> take up very little space, which 
	//     helps with load and submit times.  Note: it is invalid to have a 
	//     number begin an xml tag, like <2>, which is why we prefix with "a".
	
	var data = xmlFindChild(xml, "list_data");
	var records = data.getElementsByTagName("record");
	
	// Create a two dimensional array to hold each record.
	var tag = "";
	jaxTableRecords = Array();
	for (var i = 0; i < records.length; i++) {
		jaxTableRecords[i] = Array();
		for(var j = 0; j < jaxTableTitles.length; j++) {
			tag = "a" + j.toString();
			if (records[i].getElementsByTagName(tag)[0].firstChild) {
				jaxTableRecords[i][j] = records[i].getElementsByTagName(tag)[0].firstChild.nodeValue;
			}
		}
	}
}

// Alert out the table.  Useful for debugging.
function jaxTableAlertTable() {
	var message = "";
	for (var i = 0; i < jaxTableRecords.length; i++) {
		for (var j = 0; j < jaxTableRecords[i].length; j++) {
			message += jaxTableRecords[i][j] + ", ";
		}
		message += "\n";
	}
	alert(message);
}

function jaxTableCreateTable() {
	
	// Build the display table.
	var html = "";
	var html_titles = "";
	var html_content = "";
	var html_anchor = "";
	
	// Check for extra column to display edit / delete button(s).
	var addButtonColumn = false;
	if (!(jaxTableFolderEditURL == null && jaxTableFolderDeleteURL == null)) addButtonColumn = true;
	
	// Build the column headers.
	html_titles += "<tr>";
	for (var i = 0; i < jaxTableTitles.length; i++) {
		if (i > 0 || (!jaxTableSuppressId)) {
			html_titles += "<th>" + jaxTableTitles[i] + "</th>";
		}
	}
	if (addButtonColumn) html_titles += "<td></td>";
	html_titles += "</tr>\n";
	
	// Build all rows and cell therein.
	for (var i = 0; i < jaxTableRecords.length; i++) {
		html_content += "<tr>";
		for (var j = 0; j < jaxTableTitles.length; j++) {
			if (j > 0 || (!jaxTableSuppressId)) {
				html_content += "<td></td>";
			}
		}
		
		html_anchor = "";
/*
		if (jaxTableFolderEditURL != null) {
			html_anchor = " <a href=\"\" title=\"Edit Node\" class=\"table_edit\">e</a>";
		}
		if (jaxTableFolderDeleteURL != null) {
			html_anchor = " <a href=\"\" title=\"Delete Node\" class=\"table_delete\">x</a>";
		}
		if (!(jaxTableFolderEditURL == null && jaxTableFolderDeleteURL == null)) {
			html_anchor = "<td>" + html_anchor + "</td>";
			addButtonColumn = true;
		}
*/
		html_content += html_anchor + "</tr>\n";
	}
	
	// Add the new table to the page.
	html += "<table><tbody>\n" + html_titles + html_content + "</tbody></table>\n";
	document.getElementById("table_container").innerHTML = html;
}

function jaxTableDecorateTable() {
	
	// Register event functionality across the table cells.
	var div = document.getElementById("table_container");
	var table = div.getElementsByTagName("TABLE")[0];
	var th = table.getElementsByTagName("TH");
	var tr = table.getElementsByTagName("TR");
	var td = tr[1].getElementsByTagName("TD");
	var id = "";
	var counter = -1;
	
	jaxTableHeight = tr.length - 1; // -1 for header row
	jaxTableWidth = td.length;
	
	// Set classes, id's, and mouse events for column headers.
	for (var i = 0; i < jaxTableWidth; i++) {
		if (th[i].innerHTML != "") {
			id = "table_title_" +  i;
			th[i].onclick = function(event) { jaxTableSort(this.id); };
			th[i].id = id;
			th[i].className = "table_title";
		}
	}
	
	// Set classes, id's, and mouse events for table cells.
	for (var i = 1; i < jaxTableHeight + 1; i++) {
		td = tr[i].getElementsByTagName("TD");
		for (var j = 0; j < jaxTableWidth; j++) {
			id = "table_td_" + (i - 1) + "_" + j;
			td[j].className = "table_td";
			td[j].onmouseover = function(event) { highlightRow(this, 1); };
			td[j].onmouseout = function(event) { highlightRow(this, 0); };
			td[j].id = id;
		}
	}
}

function jaxTableSort(id) {
	
	// First time table builds, id can be null.
	if (id == null) id = "table_title_0";
	
	// Determine if sorting in descending order.
	if (jaxTableSortID == id) {
		jaxTableSortDown = !jaxTableSortDown;
	} else {
		jaxTableSortDown = true;
	}
	jaxTableSortID = id;
	jaxTableSortIndex = id.split("_")[2];
	if (jaxTableSuppressId) jaxTableSortIndex++;
	
	// Sort the data array.
	if (jaxTableSortDown) {
		jaxTableRecords.sort(jaxTableSortDescending);
	} else {
		jaxTableRecords.sort(jaxTableSortAscending);
	}
	
	// Redraw the table.
	if (jaxTableSuppressId) jaxTableSortIndex--;
	jaxTableSortSetHeaders();
	jaxTableAddContent();
}
function jaxTableSortDescending(a, b) {
	if (a[jaxTableSortIndex] < b[jaxTableSortIndex]) { return -1; } 
	else if (a[jaxTableSortIndex] > b[jaxTableSortIndex]) { return 1; } 
	else { return 0; }
}
function jaxTableSortAscending(a, b) {
	if (a[jaxTableSortIndex] > b[jaxTableSortIndex]) { return -1; } 
	else if (a[jaxTableSortIndex] < b[jaxTableSortIndex]) { return 1; } 
	else { return 0; }
}
function jaxTableSortSetHeaders() {
	var div = document.getElementById("table_container");
	var table = div.getElementsByTagName("TABLE")[0];
	var th = table.getElementsByTagName("TH");
	
	for (var i = 0; i < th.length; i++) {
		if (i == jaxTableSortIndex) {
			if (jaxTableSortDown) {
				th[i].className = "table_title_down";
			} else {
				th[i].className = "table_title_up";
			}
		} else {
			th[i].className = "table_title";
		}
	}
}

function jaxTableAddContent() {
	
	var div = document.getElementById("table_container");
	var table = div.getElementsByTagName("TABLE")[0];
	var tr = table.getElementsByTagName("TR");
	var td = null;
	var message = "";
	
	var addButtonColumn = false;
	if (!(jaxTableFolderEditURL == null && jaxTableFolderDeleteURL == null)) addButtonColumn = true;
	
	// Loop through all rows (first row is header).
	for (var i = 0; i < jaxTableHeight; i++) {
		// Loop through all cells in the current row.
		td = tr[i + 1].getElementsByTagName("TD");
		for (var j = 0; j < jaxTableWidth; j++) {
			if (addButtonColumn && j == td.length - 1) {
				// Update edit / delete buttons with new url's.
				
			} else {
				// Add cell content.
				if (jaxTableSuppressId) {
					td[j].innerHTML = jaxTableRecords[i][j + 1];
				} else {
					td[j].innerHTML = jaxTableRecords[i][j];
				}
				
				// Mark up the content, if need be.
				if (j == jaxTableDateColumn && j == jaxTableLinkColumn) {
					td[j].innerHTML = "<span class=\"" + jaxTableDateClassName + "\">" + "<a href=\"" + jaxTableLinkURL + jaxTableRecords[i][0] + "\">" + jaxTableTranslateDate(td[j].innerHTML) + "</a></span>";
				} else if (j == jaxTableDateColumn) {
					td[j].innerHTML = "<span class=\"" + jaxTableDateClassName + "\">" + jaxTableTranslateDate(td[j].innerHTML) + "</span>";
				} else if (j == jaxTableLinkColumn) {
					//  <a href='admin_stories.php?request=edit&id=3'>A Good Title</a>
					td[j].innerHTML = "<a href=\"" + jaxTableLinkURL + jaxTableRecords[i][0] + "\">" + td[j].innerHTML + "</a>";
				}
			}
		}
	}
}
function jaxTableTranslateDate(sourceDate) {
	// Translate the date string from a database YYYY-MM-DD HH:MIPM to something a little more readable.
	year = sourceDate.substring(0, 4);
	month = sourceDate.substring(5, 7);
	day = sourceDate.substring(8, 10);
	hour = sourceDate.substring(11, 13);
	minute = sourceDate.substring(14, 16);
	ampm = sourceDate.substring(17);
	
	var months = ",January,February,March,April,May,June,July,August,September,October,November,December".split(",");
	if (month.substring(0,1) == '0') month = month.substring(1);
	return months[parseInt(month)] + " " + day + ", " + year;
}


function jaxTableShowEdit(url) {
	alert("This function not yet working - id's not being located for edit url pass!");
	jaxTableFolderEditURL = url
}
function jaxTableShowDelete(url) {
	alert("This function not yet working - id's not being located for delete url pass!");
	jaxTableFolderDeleteURL = url;
}
function jaxTableSetSuppressId() {
	// For now, assumes id is forst column.
	jaxTableSuppressId = true;
}
function jaxTableSetLinkColumn(column, url) {
	jaxTableLinkColumn = column;
	jaxTableLinkURL = url;
}
function jaxTableSetDateColumn(column, className) {
	jaxTableDateColumn = column;
	jaxTableDateClassName = className;
}
function jaxTableSetSortColumn(column) {
	jaxTableSortID = "table_title_" + column;
}
