function CancelBubbling(e) {
	if (!e) var e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();

}

/*=============================================================================
' Subroutine:	GR_Sort
' Description:	None.
' Notes:		None.
' Usage:		None
' Input:		None.
' Return value: None.
'------------------------------------------------------------------------------
' 2002-10-15 JRM - Created.
' 2003-01-25 JRM - Added error handling.
' 2003-11-18 JRM - Modified code to reset the PageNumber field to 1 when
'				a new sort field is used.
'============================================================================*/

function GR_Sort (objForm, strFieldName) {
	if (objForm) {
		try {
			if (objForm.SortBy && objForm.SortBy.value.toUpperCase() == strFieldName.toUpperCase()) {
				if (objForm.SortDirection.value == "" || objForm.SortDirection.value == "DESC") {
					objForm.SortDirection.value = "ASC";
				} else if (objForm.SortDirection && objForm.SortDirection.value.toUpperCase() == "ASC") {
					objForm.SortDirection.value = "DESC";
				}
			} else {
				if (objForm.SortDirection) {
					objForm.SortDirection.value = "DESC";
				}
			}
		
			if (objForm.SortBy) {
				objForm.SortBy.value = strFieldName;
			}
		
			if (objForm.PageNumber) { 
				objForm.PageNumber.value = 1; 
			}
		} catch (e) { }
		
		objForm.submit();
	}
}

/*=============================================================================
' Subroutine:	GR_CollapseBlock
' Description:	None.
' Notes:		None.
' Usage:		None
' Input:		None.
' Return value: None.
'------------------------------------------------------------------------------
' 2004-05-04 JRM - Created.
'============================================================================*/

function GR_CollapseBlock (strID) {
	var objName = document.getElementById(strID);
	
	if (! objName) { return; }
	
	if (! objName.style.display || objName.style.display == "block") {
		objName.style.display = "none";
	} else {
		if (is_ie) { objName.style.display = "block"; }
		else { objName.style.display = ""; }
	}
}

/*=============================================================================
' Subroutine:	GR_ToggleExtra
' Description:	None.
' Notes:		None.
' Usage:		None
' Input:		None.
' Return value: None.
'------------------------------------------------------------------------------
' 2004-05-05 JRM - Created.
'============================================================================*/

function GR_ToggleExtra (objName) {
	
	if (objName) {
		var objDivTags = objName.getElementsByTagName("DIV");

		if (objDivTags && objDivTags.length == 1) {
			if (objDivTags[0].id == "ExtraData") {
				GR_CollapseBlock (objDivTags[0].uniqueID);
			}
		}
	}
}

/*=============================================================================
' Subroutine:	GR Row Functions
' Description:	None.
' Notes:		None.
' Usage:		None
' Input:		None.
' Return value: None.
'------------------------------------------------------------------------------
' 2004-05-18 JRM - Created.
' 2004-05-27 JRM - Added fix for Safari, where null values and 0 values are
'				treated differently, rather than the value "false".
' 2004-05-29 JRM - Added call to Row detection function, to eliminate possible
'				bugs when calling these Row methods. This allows us to pass in
'				a TD or INPUT element, rather than just the TR element.
'============================================================================*/

function GR_RowWarm(objElement) {var objRow=GR_GetElementRow(objElement);if (!objRow.getAttribute("Hot")||objRow.getAttribute("Hot")==0) {objRow.className='RowWarm';}}
function GR_RowHot(objElement) {var objRow=GR_GetElementRow(objElement);objRow.setAttribute("Hot", 1);objRow.className='RowHot';}
function GR_RowReset(objElement) {var objRow=GR_GetElementRow(objElement);objRow.setAttribute("Hot", 0);var strRowClass=objRow.getAttribute("Row");objRow.className=strRowClass;}
function GR_RowClass(objElement) {var objRow=GR_GetElementRow(objElement);var strRowClass=objRow.getAttribute("Row");if (!objRow.getAttribute("Hot")||objRow.getAttribute("Hot")==0) {objRow.className=strRowClass;}}

/*=============================================================================
' Subroutine:	GR_GetElementRow
' Description:	Takes an element from a generic report (INPUT, TD, TR, etc) 
'				and returns the corresponding TR object (row).
' Notes:		None.
' Usage:		None
' Input:		None.
' Return value: None.
'------------------------------------------------------------------------------
' 2004-05-29 JRM - Created.
'============================================================================*/

function GR_GetElementRow (objElement) {
	var objRow;
	
	if (objElement.tagName == "INPUT") {
		objRow = objElement.parentNode.parentNode;
	} else if (objElement.tagName == "TD") {
		objRow = objElement.parentNode;
	} else if (objElement.tagName == "TR") {
		objRow = objElement;
	} else {
		objRow = objElement.parentNode;
	}
	
	return (objRow);
}

/*=============================================================================
' Subroutine:	GR_RowMark
' Description:	None.
' Notes:		None.
' Usage:		None
' Input:		None.
' Return value: None.
'------------------------------------------------------------------------------
' 2004-05-18 JRM - Created.
' 2004-05-23 JRM - Added Netscape support, replacing parentElement 
'				with parentNode.
' 2004-05-29 JRM - Removed Row detection code and made it its own function.
'				- Added ability to mark CHECKBOX or RADIO elements that are
'				embedded in a Row object.
'============================================================================*/

function GR_RowMark (objElement, blnAllowMultiples) {
	var objContainer;
	var strOldRowID;
	var objOldRow;
	var strOldInputID;
	var objOldInput;
	var objRow = GR_GetElementRow(objElement);
	
	if (objElement.tagName == "INPUT") {
		objRow = objElement.parentNode.parentNode;
	} else if (objElement.tagName == "TD") {
		objRow = objElement.parentNode;
	} else if (objElement.tagName == "TR") {
		objRow = objElement;
	} else {
		objRow = objElement.parentNode;
	}
	
	if (objRow) {
		objContainer = objRow.parentNode;

		if (objElement.tagName == "INPUT") {
			if (objElement.checked) { 
				// The checkbox or radio button has just been selected.
				if (! blnAllowMultiples) {
					// We only allow one row to be selected at a time, so we must
					// deselect any previously selected row.
					strOldRowID = objContainer.getAttribute("HotRowID");
					objOldRow = document.getElementById(strOldRowID);
					strOldInputID = objContainer.getAttribute("HotInput");
					objOldInput = document.getElementById(strOldInputID);

					if (objOldRow) { GR_RowReset(objOldRow); }
					if (objOldInput) { objOldInput.checked=false; }
				}
				GR_RowHot(objRow);
				if (objRow.uniqueID) {
					objContainer.setAttribute("HotRowID", objRow.uniqueID);
				} else {
					objContainer.setAttribute("HotRowID", objRow.id);
				}
				objContainer.setAttribute("HotInput", objElement.id);
			} else { 
				// The checkbox has just been deselected.
				GR_RowReset(objRow); 
			}
			
		} else {	
			// We have a non checkbox or radio object.
			strOldRowID = objContainer.getAttribute("HotRowID");
			objOldRow = document.getElementById(strOldRowID);
		
			if (objOldRow) { 
				if (! blnAllowMultiples && ! RowHasCheckedElements (objOldRow)) { 
					strOldInputID = objContainer.getAttribute("HotInput");
					objOldInput = document.getElementById(strOldInputID);

					if (objOldRow) { GR_RowReset(objOldRow); }
					if (objOldInput) { objOldInput.checked=false; }
				}
				GR_RowHot(objRow); 
				objContainer.setAttribute("HotRowID", objRow.id);
			} else {
				GR_RowHot(objRow); 
				//objContainer.setAttribute("HotRow", objRow);
				objContainer.setAttribute("HotRowID", objRow.id);

				//objOldRow = objContainer.getAttribute("HotRow");
				strOldRowID = objContainer.getAttribute("HotRowID");
				objOldRow = document.getElementById(strOldRowID);
			}

			// Work the magic for the Unique Row object.
			var strUniqueRowData;
			var strUniqueRowTitle;
			var strReportName = objContainer.getAttribute("ReportName");
			var objDataDx = document.getElementById(strReportName + "_DataDx");
			var objDataHx = document.getElementById(strReportName + "_DataHx");
			var strRowID = objRow.getAttribute("RowID");
			var objUniqueRowData = document.getElementById(strRowID + "_Data");
			
			if (objUniqueRowData) { 
				strUniqueRowData = objUniqueRowData.innerHTML; 
				strUniqueRowTitle = objUniqueRowData.getAttribute("TITLE");
			}
			
			if (objDataDx) { objDataDx.innerHTML = strUniqueRowData; }
			if (objDataHx) { if (objDataHx.tagName == "TR") { objDataHx.firstChild.innerHTML = strUniqueRowTitle; } else { objDataHx.innerHTML = strUniqueRowTitle; } }
		}
		
	}
}

// Check to see if we have an embedded CHECKBOX or RADIO element,
// because if we do, we should CHECK it.
function RowHasCheckedElements (objRow) {
	var objCheckboxElements = objRow.getElementsByTagName ("INPUT");
	var blnHasCheckedElements = false;

	for (var i=0; i < objCheckboxElements.length; i++) {
		if (objCheckboxElements[i].checked) {
			blnHasCheckedElements = true;
		}
	}
	return (blnHasCheckedElements);
}

/*=============================================================================
' Subroutine:	GR_KeypressHandler
' Description:	Handles the KeyPress events for the application BODY tag.
' Notes:		Currently only supported in Internet Explorer.
' Assumptions:  None.
' Dependencies:	The browser detection in libBrowser.js.
' Usage:		<BODY ONKEYPRESS="JavaScript:OnKeyPressBody();">
' Input:		None.
' Return value: None.
'------------------------------------------------------------------------------
' 2004-05-20 JRM - Created.
'============================================================================*/

function GR_KeypressHandler (e, strReportName, objReportForm) {
	if (document.all) { e=window.event; }
	try {
		if (document.all) {
			GR_KeyboardPaging (e, objReportForm);
			GR_KeyboardBrowsing (e, strReportName);
		} else if (document.captureEvents) {
			GR_KeyboardPaging (e, objReportForm);
			GR_KeyboardBrowsing (e, strReportName);
		}
	} catch (e) {
		// There was an error handling the keyboard events.
		if (document.all) {
			alert ("Error! " + e.description);
		} else if (document.captureEvents) {
			alert ("Error! " + e);
		}
	}
}

/*=============================================================================
' Subroutine:	GR_KeyboardPaging
' Description:	Contains code for report navigation in Netscape and IE.
' Notes:		None.
' Usage:		None
' Input:		None.
' Return value: None.
'------------------------------------------------------------------------------
' 2004-05-20 JRM - Created.
' 2004-05-25 JRM - Added Safari support for <-- Arrow Navigation -->.
'============================================================================*/

function GR_KeyboardPaging (e, objForm) {
	if (document.all) {
		var blnLeftPressed = (e.keyCode == 37); var objLeftKey = 37;
		var blnRightPressed = (e.keyCode == 39); var objRightKey = 39;
	} else if (document.captureEvents) {
		var blnLeftPressed = (e.which == 37); var objLeftKey = 37;
		var blnRightPressed = (e.which == 39); var objRightKey = 39;
	}

	if (! blnLeftPressed && ! blnRightPressed) { return; }
	
	if (objForm) {
		switch (e.keyCode) {
			case objLeftKey:
				if (! objForm.MovePrev.disabled) {
					if (objForm.PageNumber.selectedIndex > 0) { objForm.PageNumber.selectedIndex--; objForm.submit(); }
				}
				break;
			case objRightKey:
				if (! objForm.MoveNext.disabled) {
					if (objForm.PageNumber.selectedIndex < objForm.PageNumber.childNodes.length-1) { objForm.PageNumber.selectedIndex++; objForm.submit(); }
				}
				break;
			default:
				//return false;
		}
	}
}

/*=============================================================================
' Subroutine:	GR_KeyboardBrowsing
' Description:	Contains code for keyboard navigation in Netscape and IE.
' Notes:		None.
' Usage:		None
' Input:		None.
' Return value: None.
'------------------------------------------------------------------------------
' 2004-05-20 JRM - Created.
'============================================================================*/

function GR_KeyboardBrowsing (e, strReportName) {
	if (document.all) {
		var blnUpPressed = (e.keyCode == 38); var objUpKey = 38;
		var blnDownPressed = (e.keyCode == 40); var objDownKey = 40;
	} else if (document.captureEvents) {
		var blnUpPressed = (e.which == 38); var objUpKey = 38;
		var blnDownPressed = (e.which == 40); var objDownKey = 40;
	}

	if (! blnUpPressed && ! blnDownPressed) { return; }

	var objTBody = document.getElementById(strReportName + "_TBody");
	var strOldRowID = objTBody.getAttribute("HotRowID");
	var objOldRow = document.getElementById(strOldRowID);
	var strOldInputID = objTBody.getAttribute("HotInput");
	var objOldInput = document.getElementById(strOldInputID);

	if (objOldRow) {
		var objPrevRow = objOldRow.previousSibling;
		var objNextRow = objOldRow.nextSibling;
	} else {
		var objFirstChild = GR_GetFirstRowChild (objTBody);	
		var objLastChild = GR_GetLastRowChild (objTBody);
		if (! objFirstChild || ! objLastChild) { return; }
	}

	switch (e.keyCode) {
		case objUpKey:
			if (! objOldRow && objLastChild) {
				GR_RowMark (objLastChild, false); 
			} else if (objPrevRow && objPrevRow.getAttribute("RowID")) {
				GR_RowMark (objPrevRow, false);
			} e.returnValue = false; break;
		case objDownKey:
			if (! objOldRow && objFirstChild) {
				GR_RowMark (objFirstChild, false);
			} else if (objNextRow && objNextRow.getAttribute("RowID")) {
				GR_RowMark (objNextRow, false);
			} e.returnValue = false; break;
		default:
			//return false;
	}
}

/*=============================================================================
' Subroutine:	GR_GetFirstRowChild
' Description:	Grabs the first valid child in a table container.
' Notes:		If no valid child exists, returns 0.
' Usage:		None
' Input:		None.
' Return value: Object.
'------------------------------------------------------------------------------
' 2004-05-20 JRM - Created.
' 2004-05-23 JRM - Added Netscape support, replacing children with childNodes.
'============================================================================*/

function GR_GetFirstRowChild (objContainer) {
	if (objContainer && objContainer.childNodes) {
		for (var i=0; i < objContainer.childNodes.length; i++) {
			if (objContainer.childNodes[i].getAttribute("RowID")) {
				return (objContainer.childNodes[i]);
			}
		}
	}
	return (0);
}

/*=============================================================================
' Subroutine:	GR_GetLastRowChild
' Description:	Grabs the last valid child in a table container.
' Notes:		If no valid child exists, returns 0.
' Usage:		None
' Input:		None.
' Return value: Object.
'------------------------------------------------------------------------------
' 2004-05-20 JRM - Created.
' 2004-05-23 JRM - Added Netscape support, replacing children with childNodes.
'============================================================================*/

function GR_GetLastRowChild (objContainer) {
	if (objContainer && objContainer.childNodes) {
		for (var i=objContainer.childNodes.length-1; i >= 0; i--) {
			if (objContainer.childNodes[i].getAttribute("RowID")) {
				return (objContainer.childNodes[i]);
			}
		}
	}
	return (0);
}
/*=============================================================================
' Subroutine:	GR_HighlightCheckedRows
' Description:	This code scans each row of a container object and marks all
'				rows that have checkboxes that have been checked.
' Notes:		None.
' Usage:		None
' Input:		None.
' Return value: Object.
'------------------------------------------------------------------------------
' 2004-05-28 JRM - Created.
'============================================================================*/

function GR_HighlightCheckedRows (objContainer) {
	if (objContainer && objContainer.childNodes) {
		for (var i=0; i < objContainer.childNodes.length; i++) {
			var objCheckboxes = objContainer.childNodes[i].getElementsByTagName("INPUT");
			if (objCheckboxes.length > 0) {
				if (objCheckboxes[0].checked) {
					GR_RowMark (objContainer.childNodes[i], objCheckboxes[0].type.toUpperCase() == "CHECKBOX"); 
				}
			}
		}
	}

	return (0);
}

/*=============================================================================
' Subroutine:	GR_ToggleCheckboxes
' Description:	This generic code goes through all CHECKBOX INPUT elements in 
'				then given element and marks them all as checked.
' Notes:		None.
' Usage:		None
' Input:		None.
' Return value: None.
'------------------------------------------------------------------------------
' 2002-10-05 JRM - Created.
'============================================================================*/

function GR_ToggleCheckboxes (objElement) {
	var objCheckboxes = objElement.getElementsByTagName("INPUT");
	
	if (objCheckboxes) {
		for (i = 0; i < objCheckboxes.length; i++) {
			var objElement = objCheckboxes[i];
			
			if (objElement.type.toUpperCase() == "CHECKBOX") {
				if (objElement.checked) {
					objElement.checked = false;
					GR_RowReset (objElement, true);
				} else {
					objElement.checked = true;
					GR_RowMark (objElement, true);
				}
			}
		}
	}
}

/*=============================================================================
' Subroutine:	GR_ClearRadioButtons
' Description:	This generic code goes through all RADIO INPUT elements in 
'				then given element and clears them all.
' Notes:		None.
' Usage:		None
' Input:		None.
' Return value: None.
'------------------------------------------------------------------------------
' 2002-10-05 JRM - Created.
'============================================================================*/

function GR_ClearRadioButtons (objElement) {
	var objCheckboxes = objElement.getElementsByTagName("INPUT");
	
	if (objCheckboxes) {
		for (i = 0; i < objCheckboxes.length; i++) {
			var objElement = objCheckboxes[i];
			
			if (objElement.type.toUpperCase() == "RADIO") {
				objElement.checked = false;
				GR_RowReset (objElement, true);
			}
		}
	}
}
