/*******************************************************************************
 * Licensed Materials - Property of IBM
 * (c) Copyright IBM Corporation 2007, 2010. All Rights Reserved.
 * 
 * Note to U.S. Government Users Restricted Rights:
 * Use, duplication or disclosure restricted by GSA ADP Schedule
 * Contract with IBM Corp. 
 *******************************************************************************/

var ASCENDING = "Ascending";
var DESCENDING = "Descending";
var DEFAULT_SORT_DIRECTION = ASCENDING;

var SORT_DIR_ATTR = "Direction";
var SORT_COLUMN_ATTR = "Column";

var sortImages = new Array();
sortImages[ASCENDING] = "ascending.gif";
sortImages[DESCENDING] = "descending.gif";

function handleClick(documentObj, cellObj, relPathToRoot) {
	var tableObj = findParent(cellObj, "table");
	var columnNum = findParent(cellObj, "th").cellIndex;
	var tableHeaderRow = findParent(cellObj, "tr");

	sortColumnStr = tableHeaderRow.getAttribute(SORT_COLUMN_ATTR);

	var data = fetchRowValues(tableObj);

	var rowValues = data.rows;
	var backColors = data.backColors;

	if (undefined != sortColumnStr && parseInt(sortColumnStr) == columnNum) {
		sortDirection = tableHeaderRow.getAttribute(SORT_DIR_ATTR);
		sortDirection = sortDirection == ASCENDING ? DESCENDING : ASCENDING;
		if (tableHasGroups(tableObj)) {
			sort(rowValues, columnNum, sortDirection);
		} else {
			rowValues.reverse();
		}
	}

	else {
		sortDirection = DEFAULT_SORT_DIRECTION;
		sort(rowValues, columnNum, sortDirection);
	}

	var imgObj = documentObj.getElementById("sortImage")
	if (imgObj) {
		imgObj.parentNode.removeChild(imgObj);
	}

	tableHeaderRow.setAttribute(SORT_COLUMN_ATTR, columnNum);
	tableHeaderRow.setAttribute(SORT_DIR_ATTR, sortDirection);

	var sortImage = documentObj.createElement("img");

	sortImage.src = relPathToRoot + "images/" + sortImages[sortDirection];
	sortImage.id = "sortImage";

	cellObj.appendChild(sortImage);

	addSortedRows(tableObj, rowValues, backColors);

}

function checkKeystroke(documentObj, cellObj, relPathToRoot, event) {
    if (event.keyCode == 13) // enter pressed?
    	handleClick(documentObj, cellObj, relPathToRoot);    
}

function findParent(obj, parentsTag) {
	parentObj = obj;

	while (parentObj.nodeName.toLowerCase() != parentsTag) {
		parentObj = parentObj.parentNode;
	}
	return parentObj;
}

function displayTable(rowValues) {
	var stringValue = "";
	for (i = 0; i < rowValues.length; i++) {
		stringValue += rowValues[i].cells[0].innerHTML + "\n";
	}
	alert(stringValue);
}

function fetchRowValues(tableObj) {
	var rows = tableObj.rows;
	var rowValues = new Array(rows.length - 1);
	var backgroundColors = new Array(rows.length - 1);
	var currentGroup = "";

	groupFound = false;
	var groupIdcounter = 1;
	for (i = 1; i < rows.length; i++) {

		if (isGroupHeader(rows[i])) {
			currentGroup = groupIdcounter++;
			rows[i].setAttribute("sort-parentGroup", currentGroup);
			groupFound = true;
		} else if (currentGroup) {
			rows[i].setAttribute("sort-parentGroup", currentGroup);
		}
		backgroundColors[i - 1] = rows[i].style.backgroundColor;
		rowValues[i - 1] = rows[i];
	}
	if (groupFound) {
		tableObj.setAttribute("hasGrouping", groupFound);
	}
	var data = new Object();
	data.rows = rowValues;
	data.backColors = backgroundColors;

	return data;

}

function getGroup(elmt) {
	var attr = elmt.getAttribute("sort-parentGroup")
	if (attr) {
		return attr;
	}
	return "";
}

function sort(rowValues, colNum, sortDirection) {
	rowValues.sort(sortComparator(colNum, sortDirection));
}

function sortComparator(columnNum, sortDirection) {

	return function(rowI, rowJ) {

		rowIGroup = getGroup(rowI);
		rowJGroup = getGroup(rowJ);

		if (rowIGroup == rowJGroup) {
			if (isGroupHeader(rowI)) {
				return -1;
			}
			if (isGroupHeader(rowJ)) {
				return 1;
			}
			var cellIText = getElementValue(rowI.cells[columnNum]);
			var cellJText = getElementValue(rowJ.cells[columnNum]);
			
			var result = 0;
			switch(columnNum)
			{
				case 0:
				  result = compareStrings(cellIText, cellJText);
				  break;
				case 1:
				  var cellIVal = parseInt(cellIText);
				  var cellJVal = parseInt(cellJText);
				  if ( isNaN(cellIVal) || isNaN(cellJVal) ) {
				  	result = compareStrings(cellIText, cellJText);	
				  } else {
				  	result = compareNumbers(cellIVal, cellJVal);	
				  }
				  break;
			  case 2:
			  case 3:
			  case 4:
			  	result = compareNumbers(parseInt(cellIText),
						parseInt(cellJText));
			  	break;
				default:
				  result = compareStrings(cellIText, cellJText);
			}

			sortFactor = sortDirection == ASCENDING ? 1 : -1;

			return result * sortFactor;
		} else {
			return compareGroups(rowIGroup, rowJGroup);
		}
	}
}

function compareStrings(string1, string2) {
	var str1tmp = string1.toLowerCase();
	var str2tmp = string2.toLowerCase();
	if (str1tmp > str2tmp)
		return 1;
	else if (str1tmp < str2tmp)
		return -1;
	return 0;
}

function compareNumbers(num1, num2) {
	return num1 - num2;
}

function compareGroups(group1Id, group2Id) {
	return compareNumbers(parseFloat(group1Id), parseFloat(group2Id));
}

function getElementValue(elmt) {
	nodeVal = null;
	if ( elmt.childNodes.length == 0 ) 
		return null;

	var i = 0;
	for (i = 0; i < elmt.childNodes.length; i++) {
		var nodeVal = elmt.childNodes[i].nodeValue;
		/* Match on \S is supposed to on anything BUT whitespace. This works in modern browsers but apparently not IE6. Need to 
			do additional checks*/
		if (nodeVal && nodeVal.match(/\S/)) {
			if ( nodeVal.match(/\w/) ) {
				return elmt.childNodes[i].nodeValue;
			}
		} else {
			var childrenValue = getElementValue(elmt.childNodes[i]);
			if (childrenValue ) {
				return childrenValue;
			}
		}
	}
	return "";
}

function isGroupHeader(elmt) {
	return elmt.getAttribute("id")
			&& elmt.getAttribute("id").indexOf("group-header") >= 0;
}

function tableHasGroups(tableObj) {
	return tableObj.getAttribute("hasGrouping");
}

function addSortedRows(tableObj, rowValues, backColors) {
	tableObj.tBodies[0].appendChild(tableObj.rows[0]);
	for ( var counter = 0; counter < rowValues.length; counter++) {
		// sortableRows[counter].bgColor = rowValues[counter];
		rowValues[counter].style.backgroundColor = backColors[counter];
		tableObj.tBodies[0].appendChild(rowValues[counter]);
	}
}
