/**
 
 * @class YAHOO.AHF.SortableTable
 * @constructor
 * @param {String} id the id of the table to model
 */

YAHOO.AHF.SimpleSortableTable = function(id) {
	this.tableId = id;
	this.whtSpEnds = new RegExp("^\\s*|\\s*$", "g");
	this.whtSpMult = new RegExp("\\s\\s+", "g");
	if (document.ELEMENT_NODE == null) {
		document.ELEMENT_NODE = 1;
		document.TEXT_NODE = 3;
	}
};

YAHOO.AHF.SimpleSortableTable.prototype = {

	tableId: "",
	whtSpEnds: null,
	whtSpMult: null,
	tbody: null,
	sortCol: 0,
	sortDir: false,
	FLOAT: 0,
	DATE: 1,
	STRING: 2,

	sortTable : function (col, type, rev) {
		if (typeof(force_dir_chng) == "undefined") {
			force_dir_chng = true;
		}
			
		// Get the table or table section to sort.
		this.tbody = document.getElementById(this.tableId).getElementsByTagName("tbody")[0];
		this.sortCol = col;
		this.sortDir = rev;
		
		// Sort the rows based on the content of the specified column using a
		// selection sort.
		this.quicksort(0, this.tbody.rows.length, type);
		
		if (this.sortDir) {
			this.reverseTable();
		}
		
	},
	
	quicksort: function (lo, hi, type) {
		if(hi <= lo + 1) return;
		 
		if((hi - lo) == 2) {
			if(this.get(hi - 1,type) > this.get(lo,type)) this.exchange(hi - 1, lo);
			return;
		}
		
		var i = lo + 1;
		var j = hi - 1;
		
		if(this.get(lo,type) > this.get(i,type)) this.exchange(i, lo);
		if(this.get(j,type) > this.get(lo,type)) this.exchange(lo, j);
		if(this.get(lo,type) > this.get(i,type)) this.exchange(i, lo);
		
		var pivot = this.get(lo,type);
		
		while(true) {
			j--;
			while(pivot > this.get(j,type)) j--;
			i++;
			while(this.get(i,type) > pivot) i++;
			if(j <= i) break;
			this.exchange(i, j);
		}
		this.exchange(lo, j);
		
		if((j-lo) < (hi-j)) {
			this.quicksort(lo, j,type);
			this.quicksort(j + 1, hi,type);
		} else {
			this.quicksort(j + 1, hi,type);
			this.quicksort(lo, j,type);
		}
	},
	
	get: function(idx,type) {
		if (this.tbody.rows[idx]) {
			if (type == this.FLOAT) {
				return parseFloat(this.trim(this.getTextValue(this.tbody.rows[idx].cells[this.sortCol])).toLowerCase().replace(/\D/g, ""))
			} else if (type == this.DATE) {
				return new Date(this.trim(this.getTextValue(this.tbody.rows[idx].cells[this.sortCol])).toLowerCase());
			} else {
				return this.trim(this.getTextValue(this.tbody.rows[idx].cells[this.sortCol])).toLowerCase();
			}
		} else {
			return "";
		}
	},
	
	reverseTable: function () {
		for(var i = 1; i < this.tbody.rows.length; i++) {
			this.tbody.insertBefore(this.tbody.rows[i], this.tbody.rows[0]);
		}
	},
	
	exchange: function (i, j) {
		if(i == j + 1) {
			this.tbody.insertBefore(this.tbody.rows[i], this.tbody.rows[j]);
		} else if(j == i + 1) {
			this.tbody.insertBefore(this.tbody.rows[j], this.tbody.rows[i]);
		} else {
			var tmpNode = this.tbody.replaceChild(this.tbody.rows[i], this.tbody.rows[j]);
			if(typeof(this.tbody.rows[i]) == "undefined") {
				this.tbody.appendChild(tmpNode);
			} else {
				this.tbody.insertBefore(tmpNode, this.tbody.rows[i]);
			}
		}
	},
	
	trim: function (inputString) {
		// Removes leading and trailing spaces from the passed string. Also removes
		// consecutive spaces and replaces it with one space. If something besides
		// a string is passed in (null, custom object, etc.) then return the input.
		if (typeof inputString != "string") return inputString;
		var retValue = inputString;
		
		/*** TB - I rewrote this to make it simpler and more compact. */
		retValue = retValue.replace(/^\s+/, "");
		retValue = retValue.replace(/\s+$/, "");
		
		return retValue; // Return the trimmed string back to the user
	},
	
	getTextValue : function (el) {

  	var i;
		var s;
	
		// Find and concatenate the values of all text nodes contained within the
		// element.
		s = "";
		for (i = 0; i < el.childNodes.length; i++)
			if (el.childNodes[i].nodeType == document.TEXT_NODE)
				s += el.childNodes[i].nodeValue;
			else if (el.childNodes[i].nodeType == document.ELEMENT_NODE &&
							 el.childNodes[i].tagName == "BR")
				s += " ";
			else
				// Use recursion to get text within sub-elements.
				s += this.getTextValue(el.childNodes[i]);
	
		return this.normalizeString(s);
	},
	
	normalizeString : function (s) {
		s = s.replace(this.whtSpMult, " ");  // Collapse any multiple whites space.
		s = s.replace(this.whtSpEnds, "");   // Remove leading or trailing white space.
		
		return s;
	},

	toString: function() {
		return "SimpleSortableTable";
	},
	
	getRowIndex: function(o, array) {
		var i;
		for (i = 0; i < array.length; i++) {
			if (o == array[i]) {
				break;
			}
		}
		return i;
	}
	
}; // end of SimpleSortableTable class definition

