// --------------------------------------------------------------------------------------------------
//	tables.js
//	Javscript functions used to validate html form inputs
//
//	Version	Date		Reason
//	0.1		11-Nov-2009	First draft based on the sort_tables_by_columns.js script provided by
//						James Edwards & Cameron Adams in 'The JavascriptAnthology', Sitepoint 2006
//						Code to cater for IE5/Mac, Opera 6 and earlier and Safari 1 and 1.2 removed.
//						Use base.js rather than the functions provided in sort_tables_by_columns.js to 
//						manage event listeners and event handlers. Use Node.TEXT_NODE rather than 3.
//						Use class name of sortable rather than sortableTable. Removed code to get element 
//						to which the listener was attached as Base ensures that "this" points to it.
// ---------------------------------------------------------------------------------------------------

var sortableTables = {
	init: function() {
		var i, j, k;

		var tables = Base.getElementsByClass('sortable');
		var ths;

		for (i = 0; i < tables.length; i++) {

			ths = tables[i].getElementsByTagName('th');
			
			for (j = 0; j < ths.length; j++) {
				var newA = document.createElement('a');
				newA.setAttribute('href', '#');
				newA.setAttribute('title', 'Sort by this column in descending order');
				
				for (k = 0; k < ths[j].childNodes.length; k++) {
					newA.appendChild(ths[j].childNodes[k]);
				}
				
				ths[j].appendChild(newA);
				
				Base.addEventListener(newA, 'click', sortableTables.sortColumn);
			}
		}
		return true;
	},
	sortColumn: function(event) {
		var i, j;
		var targetA, targetTh, targetTr, targetTrChildren, targetTable, targetTbody, targetTrs, targetColumn;
		var newTbody;

//		targetA = Base.getEventTarget(event, 'a');
		targetA = this;
		
		targetTh = targetA.parentNode;
		targetTr = targetTh.parentNode;
		targetTrChildren = targetTr.getElementsByTagName('th');
		targetTable = targetTr.parentNode.parentNode;
		targetTbody = targetTable.getElementsByTagName('tbody')[0];
		targetTrs = targetTbody.getElementsByTagName('tr');
		targetColumn = 0;
		
		for (i = 0; i < targetTrChildren.length; i++) {
			targetTrChildren[i].className = targetTrChildren[i].className.replace(/(^| )sortedDescending( |$)/, '$1');
			targetTrChildren[i].className = targetTrChildren[i].className.replace(/(^| )sortedAscending( |$)/, '$1');
			
			if (targetTrChildren[i] == targetTh) {
				targetColumn = i;
				
				if (targetTrChildren[i].sortOrder === 'descending' && targetTrChildren[i].clicked) {
					targetTrChildren[i].sortOrder = 'ascending';
					targetTrChildren[i].className += ' sortedAscending';
					targetA.setAttribute('title', 'Sort by this column in descending order');
			} else {
					if (targetTrChildren[i].sortOrder === 'ascending' && !targetTrChildren[i].clicked) {
						targetTrChildren[i].className += ' sortedAscending';
					} else {
						targetTrChildren[i].sortOrder = 'descending';
						targetTrChildren[i].className += ' sortedDescending';
						targetA.setAttribute('title', 'Sort by this column in ascending order');
					}
				}
				targetTrChildren[i].clicked = true;
			} else {
				targetTrChildren[i].clicked = false;
			
				if (targetTrChildren[i].sortOrder === 'ascending') {
					targetTrChildren[i].firstChild.setAttribute('title', 'Sort by this column in ascending order');
				} else {
					targetTrChildren[i].firstChild.setAttribute('title', 'Sort by this column in descending order');
				}
			}
		}
		
		newTbody = targetTbody.cloneNode(false);
		
		for (i = 0; i < targetTrs.length; i++) {
			var newTrs = newTbody.childNodes;
			var targetValue = sortableTables.getInternalText(targetTrs[i].getElementsByTagName('td')[targetColumn]);
		
			for (j = 0; j < newTrs.length; j++) {
				var newValue = sortableTables.getInternalText(newTrs[j].getElementsByTagName('td')[targetColumn]);
			
				if (targetValue === parseInt(targetValue, 10) && newValue === parseInt(newValue, 10)) {
					targetValue = parseInt(targetValue, 10);
					newValue = parseInt(newValue, 10);
				} else if (targetValue === parseFloat(targetValue) && newValue === parseFloat(newValue)) {
					targetValue = parseFloat(targetValue, 10);
					newValue = parseFloat(newValue, 10);
				}
				
				if (targetTrChildren[targetColumn].sortOrder === 'descending') {
					if (targetValue >= newValue) {
						break;
					}
				} else {
					if (targetValue <= newValue) {
						break;
					}
				}
			}
		
			if (j >= newTrs.length) {
				newTbody.appendChild(targetTrs[i].cloneNode(true));
			} else {
				newTbody.insertBefore(targetTrs[i].cloneNode(true), newTrs[j]);
			}
		}
		targetTable.replaceChild(newTbody, targetTbody);
		Base.preventDefault(event);
		return false;
	},
	getInternalText: function(target) {
		var i;
		var elementChildren = target.childNodes;
		var internalText = '';
		
		for (i = 0; i < elementChildren.length; i++) {
			if (elementChildren[i].nodeType === Node.TEXT_NODE) {
				if (!/^\s*$/.test(elementChildren[i].nodeValue)) {
					internalText += elementChildren[i].nodeValue;
				}
			} else {
				internalText += sortableTables.getInternalText(elementChildren[i]);
			}
		}
		return internalText;
	}
};
Base.start(sortableTables);
