/**
 * Copyright (C) 2009 Zigabyte Corporation. ALL RIGHTS RESERVED. NO COPYING ALLOWED.
 * Lincensed to: chicagotopcondos.com
 * 
 * call  enableTableControls(decument.getElementById('tableID')) to enable sorting for that table. 
 * The sort algorithm used here is Merge Sort.
 */
function TableSort(tableObj)
{
	this.lastSortedTh = null;
	this.table = tableObj;
	if (this.table && this.table.nodeName == "TABLE") {
		var headings = this.getHeadings();
		for (var i=0; headings[i]; i++) {
			if (headings[i].className.match(/asc|dsc/)) {
				this.lastSortedTh = headings[i];
			}
		}
		this.makeSortable();
	}
}

TableSort.prototype.getHeadings = function () {
		if(this.table.tHead) {
			return this.table.tHead.rows[0].cells;
		} else {
			return this.table.rows[0].cells;
		}
}

TableSort.prototype.makeSortable = function () {
	var headings = this.getHeadings();
	for(var i=0; headings[i]; i++) {
		headings[i].cIdx = i;
		var a = document.createElement("a");
		a.href="#";
		a.innerHTML = headings[i].innerHTML;
		a.onclick = function (that) {
			return function () {
				that.sortCol(this);
				return false;
			}
		} (this);
		headings[i].innerHTML = "";
		headings[i].appendChild(a);
	}
}

TableSort.prototype.sortCol = function (el) {
	var rows = this.table.rows;
	var alpha = [];
	var numeric = [];
	var aIdx = 0;
	var nIdx = 0;
	var th = el.parentNode;
	var cellIndex = th.cIdx;
	var col = [], top, bottom;

	for (var i = 1; rows[i]; i++) {
		var cell = rows[i].cells[cellIndex];
		var content = cell.textContent ? cell.textContent : cell.innerText;
		var num = content.replace(/(\$|\,|\s)/g, "");
		if (parseFloat(num) == num) {
			numeric[nIdx++] = {
				value : Number(num),
				row : rows[i]
			}
		} else {
			alpha[aIdx++] = {
				value: content, 
				row: rows[i]
			}
		}
	}

	if(th.className.match("asc")) {
		top = mergeSort(alpha, -1);
		bottom = mergeSort(numeric, -1);
		th.className = th.className.replace(/asc/, "dsc");
	} else {
		top = mergeSort(numeric, 1);
		bottom = mergeSort(alpha, 1);

		if(th.className.match("dsc")) {
			th.className = th.className.replace(/dsc/, "asc");
		} else {
			th.className += "asc";
		}
	}

	if (this.lastSortedTh && th != this.lastSortedTh) {
		this.lastSortedTh.className = this.lastSortedTh.className.replace(/dsc|asc/g, "");
	}

	this.lastSortedTh = th;
	col = top.concat(bottom);
	var tBody = this.table.tBodies[0];
	for(var i = 0; col[i]; i++) {
		tBody.appendChild(col[i].row);
	}
}

function mergeSort(arr, dir) 
{
	var left = [], right = [], result = [];
	if(arr.length <= 1) {
		return arr;
	}

	var i;
	var middle = Math.ceil((arr.length / 2) - 1);
	for (i = 0; i <= middle; i++) {
		left.push (arr[i]);
	}

	for(i = middle + 1; arr[i]; i++) {
		right.push (arr[i]);
	}

	left = mergeSort(left, dir);
	right = mergeSort(right, dir);

	var compareFunc;

	if(dir === 1) {
		compareFunc = function (val1, val2)  {
			return val1.value >= val2.value;
		}
	} else if (dir === -1) {
		compareFunc = function (val1, val2)  {
			return val1.value <= val2.value;
		}
	}

	if(compareFunc(left[left.length - 1] , right[right.length - 1])) {
		result = merge (left, right, compareFunc);
	} else {
		result = merge (right, left, compareFunc);
	}

	return result;
}

function merge (left, right, compareFunc) 
{
	result = [];
	while(left.length > 0 && right.length > 0) {
		if(compareFunc(left[0], right[0])) {
			var d = left.shift();
			result.push (d);
		} else {
			result.push (right.shift());
		}
	}

	if(left.length > 0) {
		result = result.concat(left);
	} else {
		result = result.concat(right);
	}

	return result;
}

function enableTableControls(id) 
{
	var ts = new TableSort(id);
}

