// Select initial row sorted.  Use '-1' if no row is initially sorted.
function init_sortTable(id, col_sorted) {
	document.getElementById(id).lastColumn = col_sorted;
}

// Concatenates all text values into a single string (watch for <br> and other 'newline' tags).
function getText(element) {
	// Creates this constant for browers that do not have it.
	if (document.TEXT_NODE == null) {
        	document.TEXT_NODE = 3;
	}

        var text = "";
        for (var i = 0; i < element.childNodes.length; i++)
                if (element.childNodes[i].nodeType == document.TEXT_NODE)
		    text += element.childNodes[i].nodeValue;
                else
		    text += getText(element.childNodes[i]);

        return text;
}

// Handles strings and numbers.
function compare(v1, v2) {
	// If numeric, prepare for comparison;
        if (!isNaN(v1) && !isNaN(v2)) {
	    v1 = parseFloat(v1);
	    v2 = parseFloat(v2);
        }

        // Compare the values.
        if (v1 == v2)
	    return 0;
        if (v1 > v2)
	    return 1;
        return -1;
}

// Mergesort fuction for table sorting.
function mergeSortTable(table, col, first, last) {
	if (first >= last)
		return;
	
	// first half
	var a_first = first;
	var a_last = Math.floor((first + last) / 2);
	// second half
	var b_first = a_last + 1;
	var b_last = last;

	mergeSortTable(table, col, a_first, a_last);
	mergeSortTable(table, col, b_first, b_last);

	// merge rows back together
	while((a_first <= a_last) && (b_first <= b_last)) {
		var comp = compare(getText(table.rows[a_first].cells[col]), getText(table.rows[b_first].cells[col]));
		if (table.col_sd[col]) // Reverse sort order if necessary.
			comp *= -1;
		if (comp < 0) { // order of values is correct
			a_first++;
		} else { // order of values is incorrect
			table.insertBefore(table.removeChild(table.rows[b_first]), table.rows[a_first]);
			a_first++;
			a_last++;
			b_first++;
		}
	}
}

// Use a selection sort by column. 'sd' is sort direction and accepts 'A' for ascending and 'D' for descending.
function sortTable(id, col, sd) {
	var table = document.getElementById(id);
	if (table.getElementsByTagName('TBODY').length)
		table = table.tBodies[0];

	// First time function is run create an array to hold initial direction to sort the column.
	if (table.col_sd == null)
		table.col_sd = new Array();

	// If no column was initialized then assume no column is initially sorted.
	if (table.lastColumn == null)
		table.lastColumn = -1;

	// First time a column is sorted, place it's initial sort direction into the array.
	if (table.col_sd[col] == null)
		if (sd == 'A')
			table.col_sd[col] = false;
		else
			table.col_sd[col] = true;
	if (col == table.lastColumn) // If a column is clicked twice in a row reverse the sort direction.
		table.col_sd[col] = !table.col_sd[col];

	mergeSortTable(table, col, 1, table.rows.length-1); // this line is different from tableSort.js

	// Set this column as the last one sorted.
	table.lastColumn = col;
	
	recolorRows(id);
	
	return false;
}

function sortArrow(tableId, column) {
	var table = document.getElementById(tableId);
	if (table) {
		var row = table.rows[0];
        	if (row) {
        		var headers = row.getElementsByTagName('th');
			for (var i = 0; i < headers.length; i++) {
				var images = headers[i].getElementsByTagName('img');
				if (i == column) {
					if (! images.length)
						headers[i].appendChild(document.createElement('img'));
					images = headers[i].getElementsByTagName('img');
					images[0].src = '/images/';
					images[0].src += (table.tBodies[0].col_sd[column] == false) ? 'down.gif' : 'up.gif';
				} else {
					if (images.length)
						headers[i].removeChild(images[0]);
				}
			}
		}
	}
}

function applySort() {
	var tables = document.getElementsByTagName('table');

	for (var i = 0; i < tables.length; i++) {
		var row = tables[i].rows[0];
		if (row) {
			var headers = row.getElementsByTagName('th');

			for (var j = 0; j < headers.length; j++) {
				var anchors = headers[j].getElementsByTagName('a');
				if (anchors[0]) {
						if (!tables[i].getAttribute('id'))
								tables[i].setAttribute('id', 'table'+(i+1));

					anchors[0].tableId = tables[i].getAttribute('id');
					anchors[0].column = j;
					anchors[0].onclick = function () {
						this.blur();
						sortTable(this.tableId, this.column, 'A');
					        sortArrow(this.tableId, this.column);
						return false;
					}
				}
			}
		}
	}
}

// recoloring row backgrounds (works for multiple colors and iterate through the number / slapped together)
function recolorRows(tableId) {

	var table = document.getElementById(tableId);
	if (table) {
		var row = table.rows[0];
		if (row) {
			// find colors
			var colors = [];
			var cells = table.getElementsByTagName("td");
			for (var i = 0; i < cells.length; i++) {
				colors[i] = cells[i].bgColor;
			}
		}
		// unique found colors
		colors.sort();
		var uniqueColors = [];
		var counter = 0;
		var lastColor = 0;
		for (var i = 0; i < colors.length; i++) {
			if (colors[i] != lastColor) {
				uniqueColors[counter++] = colors[i];
				lastColor = colors[i];
			}
		}
		// apply new coloring
		for (var i = 0; i < table.rows.length; i++) {
			for (var j = 0; j < table.rows[i].cells.length; j++) {
				if (table.rows[i].cells[j].tagName == "TD") { // ignore th cells
					table.rows[i].cells[j].bgColor = uniqueColors[i%(uniqueColors.length)];
				}
			}
		}
	}
}

addLoadEvent(applySort);
