//	====================================================================================================
//	|	Display Table Library (supports IE & DOM)
//	|	DOM support is included for future browsers because only IE renders "display" CSS tag correctly
//	|	While hide/show doesn't work properly in NS, collapse/expand works fine
//	====================================================================================================

// =================== Public Section ===================
	
	//public function (add description)
	function hideTableElement(tableName, rowNumber, columnNumber) {
		tableObject = getObject(tableName);
		tableObject.rows[rowNumber].cells[columnNumber].style.display = "none";
	}
	
	//public function (add description)
	function showTableElement(tableName, rowNumber, columnNumber) {
		tableObject = getObject(tableName);
		tableObject.rows[rowNumber].cells[columnNumber].style.display = "block";
	}

	//public function (add description)
	function collapseTableElement(tableName, rowNumber, columnNumber) {
		tableObject = getObject(tableName);
		tableDataContent = tableObject.rows[rowNumber].cells[columnNumber].getElementsByTagName("DIV");
		tableDataContent[0].style.display = "none";
		tableDataContent[1].style.display = "block";
	}
	
	//public function (add description)
	function expandTableElement(tableName, rowNumber, columnNumber) {
		tableObject = getObject(tableName);
		tableDataContent = tableObject.rows[rowNumber].cells[columnNumber].getElementsByTagName("DIV");
		tableDataContent[0].style.display = "block";
		tableDataContent[1].style.display = "none";
	}

	//public function (add description)
	function hideTableRow(tableName, rowNumber, startPos, endPos) {
		tableObject = getObject(tableName);
		startPos = (startPos) ? startPos : 0;
		rowLength = tableObject.rows[rowNumber].cells.length;
		endPos = (endPos) ? (endPos + 1) : rowLength;
		for (var i=startPos; i < endPos; i++) {
			tableObject.rows[rowNumber].cells[i].style.display = "none";
 		}
 		arrayElement = "h" + "." + tableName + "." + rowNumber;
 		if (!inArray(hiddenRows, arrayElement)) {
 			arrayElement = arrayElement + "." + startPos + "." + endPos;
 			hiddenRows[hiddenRows.length] = arrayElement;
 		}
	}

	//public function (add description)
	function showTableRow(tableName, rowNumber, startPos, endPos) {
		tableObject = getObject(tableName);
		startPos = (startPos) ? startPos : 0;
		rowLength = tableObject.rows[rowNumber].cells.length;
		endPos = (endPos) ? (endPos + 1) : rowLength;
		for (var i=startPos; i < endPos; i++) {
			elementStatus = nextElementStatus("show", "row", tableName, rowNumber, i, startPos, endPos-1);
			if (elementStatus == "none") {
				tableObject.rows[rowNumber].cells[i].style.display = "block";
			}
 		}
 		excludeFromArray(hiddenRows, "h" + "." + tableName + "." + rowNumber + "." + startPos + "." + endPos);
	}

	//public function (add description)
	function hideTableColumn(tableName, columnNumber, startPos, endPos) {
		tableObject = getObject(tableName);
		startPos = (startPos) ? startPos : 0;
		columnLength = tableObject.rows.length;
		endPos = (endPos) ? (endPos + 1) : columnLength;
		for (var j=startPos; j < endPos; j++) {
			tableObject.rows[j].cells[columnNumber].style.display = "none";
		}
		arrayElement = "h" + "." + tableName + "." + columnNumber;
 		if (!inArray(hiddenColumns, arrayElement)) {
 			arrayElement = arrayElement + "." + startPos + "." + endPos;
 			hiddenColumns[hiddenColumns.length] = arrayElement;
 		}
	}

	//public function (add description)
	function showTableColumn(tableName, columnNumber, startPos, endPos) {
		tableObject = getObject(tableName);
		startPos = (startPos) ? startPos : 0;
		columnLength = tableObject.rows.length;
		endPos = (endPos) ? (endPos + 1) : columnLength;
		for (var j=startPos; j < endPos; j++) {
			elementStatus = nextElementStatus("show", "column", tableName, j, columnNumber, startPos, endPos-1);
			if (elementStatus == "none") {
				tableObject.rows[j].cells[columnNumber].style.display = "block";
			}
 		}
 		excludeFromArray(hiddenColumns, "h" + "." + tableName + "." +  columnNumber + "." + startPos + "." + endPos);
	}

	//public function (add description)
	function collapseTableRow(tableName, rowNumber, startPos, endPos) {
		tableObject = getObject(tableName);
		startPos = (startPos) ? startPos : 0;
		rowLength = tableObject.rows[rowNumber].cells.length;
		endPos = (endPos) ? (endPos + 1) : rowLength;
		
		for (var i=startPos; i < endPos; i++) {
			tableDataContent = tableObject.rows[rowNumber].cells[i].getElementsByTagName("DIV");
			tableDataContent[0].style.display = "none";}
			
 		arrayElement = "c" + "." + tableName + "." + rowNumber;
 		if (!inArray(hiddenRows, arrayElement)) {
 			arrayElement = arrayElement + "." + startPos + "." + endPos;
 			hiddenRows[hiddenRows.length] = arrayElement;
 		}
	}

	//public function (add description)
	function expandTableRow(tableName, rowNumber, startPos, endPos) {
		tableObject = getObject(tableName);
		startPos = (startPos) ? startPos : 0;
		rowLength = tableObject.rows[rowNumber].cells.length;
		endPos = (endPos) ? (endPos + 1) : rowLength;
		for (var i=startPos; i < endPos; i++) {
			elementStatus = nextElementStatus("expand", "row", tableName, rowNumber, i, startPos, endPos-1);
			if (elementStatus == "block") {
				tableDataContent = tableObject.rows[rowNumber].cells[i].getElementsByTagName("DIV");
				tableDataContent[0].style.display = "block";}
 		}
 		excludeFromArray(hiddenRows, "c" + "." + tableName + "." + rowNumber + "." + startPos + "." + endPos);
	}

	//public function (add description)
	function collapseTableColumn(tableName, columnNumber, startPos, endPos) {
		tableObject = getObject(tableName);
		startPos = (startPos) ? startPos : 0;
		columnLength = tableObject.rows.length;
		endPos = (endPos) ? (endPos + 1) : columnLength;
		for (var j=startPos; j < endPos; j++) {
			tableDataContent = tableObject.rows[j].cells[columnNumber].getElementsByTagName("DIV");
			tableDataContent[0].style.display = "none";
			tableDataContent[1].style.display = "block";
		}
		arrayElement = "c" + "." + tableName + "." + columnNumber;
 		if (!inArray(hiddenColumns, arrayElement)) {
 			arrayElement = arrayElement + "." + startPos + "." + endPos;
 			hiddenColumns[hiddenColumns.length] = arrayElement;
 		}
	}

	//public function (add description)
	function expandTableColumn(tableName, columnNumber, startPos, endPos) {
		tableObject = getObject(tableName);
		startPos = (startPos) ? startPos : 0;
		columnLength = tableObject.rows.length;
		endPos = (endPos) ? (endPos + 1) : columnLength;
		for (var j=startPos; j < endPos; j++) {
			elementStatus = nextElementStatus("expand", "column", tableName, j, columnNumber, startPos, endPos-1);
			if (elementStatus == "block") {
				tableDataContent = tableObject.rows[j].cells[columnNumber].getElementsByTagName("DIV");
				tableDataContent[0].style.display = "block";
				tableDataContent[1].style.display = "none";
			}
 		}
 		excludeFromArray(hiddenColumns, "c" + "." + tableName + "." +  columnNumber + "." + startPos + "." + endPos);
	}

	//public function (add description)
	function loadDisplayData(persistentRowName, persistentColumnName) {
		var tempString;
	   var sLocation = location.href;
	   var sData = sLocation.substring(sLocation.indexOf("?") + 1,sLocation.length);
		aData = sData.split("&");
	   for (var i=0; i<aData.length; i++) {
	      var sName = aData[i].substring(0,aData[i].indexOf("="));
	      var sValue = aData[i].substring(aData[i].indexOf("=") + 1,aData[i].length);
	      switch (sName) {
	      	case persistentRowName:
	      		serializedHiddenRows = unescape(sValue);
	      		break;
	      	case persistentColumnName:
	      		serializedHiddenColumns = unescape(sValue);
	      		break;
	      	default:
	      }
	   }
		unserializeArray("hiddenRows", ":");
		unserializeArray("hiddenColumns", ":");
		if (hiddenRows.length > 0) {
			for (i=0; i<hiddenRows.length; i++) {
				tempString = hiddenRows[i].split(".");
				switch (tempString[0]) {
					case "h" :
						hideTableRow(tempString[1], tempString[2], parseInt(tempString[3]), parseInt(tempString[4]) - 1);
						break;
					case "c" :
						collapseTableRow(tempString[1], tempString[2], parseInt(tempString[3]), parseInt(tempString[4]) - 1);
						break;
					default:
						alert("Undefined Switch Case or Function Not Implemented (loadDisplayData 2)!!!");
				}
			}
		}
		if (hiddenColumns.length > 0) {
			for (i=0; i<hiddenColumns.length; i++) {
				tempString = hiddenColumns[i].split(".");
				switch (tempString[0]) {
					case "h" :
						hideTableColumn(tempString[1], tempString[2], parseInt(tempString[3]), parseInt(tempString[4]) - 1);
						break;
					case "c" :
						collapseTableColumn(tempString[1], tempString[2], parseInt(tempString[3]), parseInt(tempString[4]) - 1);
						break;
					default:
						alert("Undefined Switch Case or Function Not Implemented (loadDisplayData 3)!!!");
				}
			}
		}
	}

	//public function (add description)
	function saveDisplayArray(persistentRowName, persistentColumnName) {
		var tempObject;
		serializeArray(hiddenRows, "hiddenRows", ":");
		serializeArray(hiddenColumns, "hiddenColumns", ":");
		tempObject = getObject(persistentRowName);
		tempObject.value = serializedHiddenRows;
		tempObject = getObject(persistentColumnName);
		tempObject.value = serializedHiddenColumns;
	}

	//public function (add description)
	function isHiddenRow(tableName, rowNumber) {
		var returnStatus = nextElementStatus("show", "row", tableName, rowNumber, columnNumber, startPost, endPos);
		if (returnStatus == "block") {
			return true;
		}
		return false;
	}

	//public function (add description)
	function isCollapsedRow(tableName, rowNumber) {
		var returnStatus = nextElementStatus("expand", "row", tableName, rowNumber, columnNumber, startPost, endPos);
		if (returnStatus == "block") {
			return true;
		}
		return false;
	}

	//public function (add description)
	function isHiddenColumn(tableName, columnNumber) {
		var returnStatus = nextElementStatus("show", "column", tableName, rowNumber, columnNumber, startPost, endPos);
		if (returnStatus == "block") {
			return true;
		}
		return false;
	}

	//public function (add description)
	function isCollapsedColumn(tableName, columnNumber) {
		var returnStatus = nextElementStatus("expand", "column", tableName, rowNumber, columnNumber, startPost, endPos);
		if (returnStatus == "block") {
			return true;
		}
		return false;
	}
	
	//public function (add description)
	function isHiddenTableElement(tableName, rowNumber, columnNumber) {
		tableObject = getObject(tableName);
		if (tableObject.rows[rowNumber].cells[columnNumber].style.display == "none") {
			return true;
		}
		return false;
	}
	
	//public function (add description)
	function isCollapsedTableElement(tableName, rowNumber, columnNumber) {
		tableObject = getObject(tableName);
		tableDataContent = tableObject.rows[rowNumber].cells[columnNumber].getElementsByTagName("DIV");
		if (tableDataContent[0].style.display == "none") {
			return true;
		}
		return false;
	}

// =================== Private Section ===================

	//global variables (add description)
	var hiddenRows = new Array();
	var hiddenColumns = new Array();
	var serializedHiddenRows = new String("");
	var serializedHiddenColumns = new String("");

	//to be removed
	function getTableObject(objectName) {
		if (document.all) {
			return document.all[objectName];
		} else {
			return document.getElementById(objectName);
		}
	}

	//private function (add description)
	function getObject(objectName) {
		return document.getElementById(objectName);
	}
	
	//private function (add description)
	function inArray(arrayObject, searchedObject) {
		var tempString;
		var arrayLength = arrayObject.length;
		if (arrayLength == 0) {
			return false;
		}
		for (var i=0; i<arrayLength; i++) {
			tempString = arrayObject[i].split(".");
			tempString = tempString[0] + "." + tempString[1] + "." + tempString[2];
			if (tempString == searchedObject) {
				return true;
			}
		}
		return false;
	}

	//private function (add description)
	function excludeFromArray(arrayObject, excludeObject) {
		var arrayLength = arrayObject.length;
		if (arrayLength == 0){
			return;
		}
		if (arrayLength == 1) {
			if (arrayObject[0] == excludeObject) {
				arrayObject.length = 0;
			}
			return;
		}
		for (var i=0; i<(arrayLength-1); i++) {			
			if (arrayObject[i] == excludeObject) {
				arrayObject[i] = arrayObject[arrayLength-1];
				arrayObject.length = arrayLength - 1;
				return;
			}
		}
		arrayObject.length = arrayLength - 1;
		return;
	}

	//private function (add description)
	function nextElementStatus(operationType, functionType, tableName, rowNumber, columnNumber, startPos, endPos) {
		var returnStatus = "block";
		var prefix = (operationType == "show") ? "h" : "c";
		switch (functionType) {
			case "row" :
				ifStatement = inArray(hiddenColumns, prefix + "." + tableName + "." + columnNumber);
				break;
			case "column" :
				ifStatement = inArray(hiddenRows, prefix + "." + tableName + "." + rowNumber);
				break;
			default :
				alert("Undefined Switch Case or Function Not Implemented (nextElementStatus 1)!!!");
		}
		if (ifStatement) {
			returnStatus = "none";
			switch (operationType) {
				case "show" :
					tableObject = getObject(tableName);
					tableDataContent = tableObject.rows[rowNumber].cells[columnNumber].getElementsByTagName("DIV");
					if (tableDataContent[0]) {
						returnStatus = "block";
					}
					break;
				case "expand" :
					break;
				default :
					alert("Undefined Switch Case or Function Not Implemented (nextElementStatus 2)!!!");
			}
		}
		return returnStatus;
	}

	//private function (add description)
	function serializeArray(arrayObject, arrayName, delimiter) {
		if (arrayObject.length > 0) {
			switch (arrayName) {
				case "hiddenRows" :
					serializedHiddenRows = arrayObject.join(delimiter);
					break;
				case "hiddenColumns" :
					serializedHiddenColumns = arrayObject.join(delimiter);
					break;
				default :
					alert("Undefined Switch Case or Function Not Implemented (serializeArray)!!!");
			}
		}
		return;
	}

	//private function (add description)
	function unserializeArray(arrayName, delimiter) {
		var tempString, delimiterPos;
		switch (arrayName) {
			case "hiddenRows" :
				tempString = serializedHiddenRows;
				hiddenRows.length = 0;
				if (tempString.length > 0) {
					hiddenRows = tempString.split(":");
				}
				break;
			case "hiddenColumns" :
				tempString = serializedHiddenColumns;
				hiddenColumns.length = 0;
				if (tempString.length > 0) {
					hiddenColumns = tempString.split(":");
				}
				break;
			default:
				alert("Undefined Switch Case or Function Not Implemented (unserializeArray)!!!");
		}
		return;
	}