/* 
	Cross-browser compatible method for retrieving page elements by ID 
*/
function getObject(sObjId) {
	if (document.layers)
		return document.layers[sObjId];
	else if (document.all)
		return document.all[sObjId];
	else if (document.getElementById)
		return document.getElementById(sObjId);
}

/* 
	Returns the name of the tag that represents the given element 
*/
function getTag(oElem) {
	if (oElem.localName) {
		var sName = oElem.localName;
	} else if (oElem.nodeName) {
		var sName = oElem.nodeName;
	} else {
		return null;
	}
	return sName.toLowerCase();
}

/*
	Cross-browser compatible add and remove event methods.
*/
function addEvent(elm, evType, fn, useCapture) {
	try {
		if (elm.addEventListener) {
			elm.addEventListener(evType, fn, useCapture);
			return true;
		} else if (elm.attachEvent) {
			return elm.attachEvent('on' + evType, fn);
		} else {
			// Handler could not be added via traditional methods
			var fEvFunct = eval('elm.on' + evType);
			if (typeof fEvFunct != 'function') {
				eval('elm.on' + evType + ' = fn;');
			} else {
				eval('elm.on' + evType + ' = function() { fEvFunct(); fn(); };');
			}
		}
	} catch (e) {
		// May want some sort of notification process in here.
	}
}

function removeEvent(elm, evType, fn, useCapture) {
	if (elm.removeEventListener) {
		elm.removeEventListener(evType, fn, useCapture);
		return true;
	} else if (elm.detachEvent) {
		return elm.detachEvent('on' + evType, fn);
	} else {
		// Handler could not be removed.
	}
}

/*
	Gets the target of the event
*/
function getTarget(e) {

	var oTarg = null;

	if (e.target) {
		oTarg = e.target;
	} else if (e.srcElement) {
		oTarg = e.srcElement;
	}
	
	// For Safari
	if (oTarg.nodeType == 3) {
		oTarg = oTarg.parentNode;
	}
	
	return oTarg;
}

/* 
	Removes all whitespace from both ends of a string.
*/
String.prototype.trim = function() {
	return this.replace( /^\s+|\s+$/, "" );
}

/*
	Generates a unique ID value. Always good to have one of these around.
*/
function getUniqueId() {
	var oDate = new Date();
	return Math.floor(Math.random() * (oDate.getSeconds().toString() + oDate.getMilliseconds().toString()));
}

/*
	Used in striping and sorting functions to retrieve the number of rows
	that comprise a row group, as specified in the class declaration of the
	parent table element.
*/
function getRowGroupLen(sClassName, oElem) {
	var oRegexp = new RegExp(sClassName + '-?(\\d)*');
	var aResults = oRegexp.exec(oElem.className);
	if (aResults[1]) {
		return aResults[1];
	} else {
		return 1;
	}
}

/*
	Toggles the visibility of the element whose ID is given.
*/
function toggleVis(sId, bAsInline) {
	var oStyle = getStyleObject(sId);
	if (isVisible(sId)) {
		oStyle.display = 'none';
	} else {
		if (bAsInline) {
			oStyle.display = 'inline';
		} else {
			oStyle.display = 'block';
		}
	}
	return false;
}

function isVisible(sId) {
	var oStyle = getStyleObject(sId);
	return (oStyle.display == 'block' || oStyle.display == 'inline');
}

/*
	Cross-browser compatible method of retrieving an element's 'style'
	attribute.
*/
function getStyleObject(sId) {
	var oElem = getObject(sId);
	if (oElem) {
		if (document.getElementById || document.all) {
			return oElem.style;
		} else if (document.layers) {
			return oElem;
		}
	}
	return false;
}

/* 
	Dynamically removes a CSS class name from an element.
*/
function removeCSSClass(oElem, sClassName) {
	if (typeof oElem == "string") {
		var oElem = getObject(oElem);
	}
	oElem.className = oElem.className.replace(sClassName, "" ).trim();
}

/* 
	Dynamically adds a CSS class name to an element. 
*/
function addCSSClass(oElem, sClassName) {
	if (typeof oElem == "string") {
		var oElem = getObject(oElem);
	}
	oElem.className = (oElem.className + ' ' + sClassName).trim();
}

/*
	Tells if the element in question is empty.
*/
function isEmpty(oElem) {
	if (typeof oElem == "string") {
		var oElem = getObject(oElem);
	}
	
	var bRet = false;
	
	// For now, skip elements that are not found, such as those that are
	// in address entry fields. Will need to fix this later...
	if (oElem != null) {
		switch (oElem.type) {
			case 'select-one':
			case 'select-multiple':
				if (oElem.options.selectedIndex <= 0) {
					bRet = !(oElem.options.selectedIndex == 0 && oElem.options[0].value != '')
				} else {
					bRet = false;
				}
				break;
			case 'radio':
			case 'checkbox':
				bRet = oElem.checked;
				break;
			case 'password':
			case 'text':
			case 'textarea':
			case 'hidden':
				bRet = (oElem.value.trim() == '');
				break;
			default:
				break;
		}
	}
	
	return bRet;
}