/** Global instances **/
var TABLES = new Array();
var DEFAULT_SORT_COL = -3; // defaults to col 3 (sorted inversely)

/** Function used to hand sorting, to ensure table objects can be reused. **/
function runSort(categoryKey, col, defaultReverse) {
	if (!TABLES[categoryKey]) {
		TABLES[categoryKey] = new CategoryTable(categoryKey);
	}
	return sortTableChangeDefault(TABLES[categoryKey], col, defaultReverse);
}

/** Implementation of Table object.  See tablesort.js for details. **/
function CategoryTable(categoryKey) {
	/** Public members **/
	this.lastColumn = DEFAULT_SORT_COL;
	this.body = null;
	this.rowPrefix = categoryKey+"Row";
	
	/** Private members **/
	var mDivTable = document.getElementById(categoryKey+"Table");
	var mOrderElements = new Array();
	var mHeaderImgs = new Array();
	var mArrowHide = "sort-arrow-hidden";
	var mArrowShow = "sort-arrow-shown";
	var mNumColumns = 5;  // this should correlate to the total number of columns, even if some are hidden
	var alternateClass = false;
	
	/** 
	 * Initialization code.  This only needs to be run once for a page, 
	 * so use only once instance of this object per sorted table.
	 **/	
	var header;
	var sortNode;
	for (var x = 0; x < mDivTable.childNodes.length; x++) {
		var child = mDivTable.childNodes[x];
		if (!child.id) {
			continue; // this is not a good node, skip it
		}
		if (child.id == categoryKey+"Header") {
			header = child;
		} else if (child.id == categoryKey+"Body") {
			this.body = child;
		} else if (child.id == categoryKey+"SortNodes") {
			sortNode = child;
		}
	}
	
	if (header) { // if table has a header, parse it now
		for (var i = 0; i < header.childNodes.length; i++) {
			if (!header.childNodes[i].id) {
				continue; // this is not a node we are interested in
			}
			var columnChildren = header.childNodes[i].childNodes;
			for (var x = 0; x < columnChildren.length; x++) {
				var img = columnChildren[x];
				
				if (!img.id) {
					continue;
				}
				
				for (var y = 1; y <= mNumColumns; y++) {
					if (img.id != "up"+y && img.id != "down"+y && img.id != "null"+y) {
						continue;
					}
					mHeaderImgs.push(img);
				}
			}
		}
	}
	
	for (var x = 0; x < sortNode.childNodes.length; x++) {
		var child = sortNode.childNodes[x];
		if (child.nodeType == document.ELEMENT_NODE && child.id) {
			mOrderElements[child.id] = child;
		}
	}
	
	/** Functions **/
	this.startSort = function () { alternateClass = false; }
	
	this.createNewBody = function () {
		var newDiv = document.createElement("div");
		newDiv.setAttribute("id",categoryKey+"Body");
		return newDiv;
	}	
	
	this.replaceBody = function (newBody) {
		mDivTable.replaceChild(newBody, this.body);
		this.body = newBody;
	}
	
	this.getOrderingNode = function (col, reverse) {
		var elemId;		
		if (reverse) {
			elemId = categoryKey+"order"+col+"b";
		} else {
			elemId = categoryKey+"order"+col+"a";
		}		
		return mOrderElements[elemId];
	}
	
	this.rowInsert = function (row) {
		if (row.className.search(/catFeatRow/) >= 0) {
			row.className="row catFeatRow";
		} else if (alternateClass) {
			row.className="row catAltRow";
			alternateClass = false;
		} else {
			row.className="row";
			alternateClass = true;
		}
	}
	
	this.sortOrder = function (col, reverse) {
		if (!header) {
			return;
		}
		
		for ( var x=0; x < mHeaderImgs.length; x++ ) {
			var img = mHeaderImgs[x];
			if (reverse && img.id == "up"+col) {
				img.className=mArrowShow;
			} else if (!reverse && img.id == "down"+col) {
				img.className=mArrowShow;
			} else if (img.id.indexOf("null") != -1 && img.id != "null"+col) {
				// set null image for any column we didn't sort
				img.className=mArrowShow;
			} else {
				img.className=mArrowHide;
			}
		}
	}
	
	function ieSetClassAttributeWorkAround(node, className) {
		for (var i = 0; i < node.attributes.length; i++) {
		    var attrName = node.attributes[i].name.toUpperCase();
			if (attrName == 'CLASS') {
				node.attributes[i].value = className;
			}
		}
	}
}

