// Extend string class
String.prototype.ltrim       = function() { return this.replace(/^\s+/,""); }
String.prototype.rtrim       = function() { return this.replace(/\s+$/,""); }
String.prototype.trim        = function() { return this.ltrim().rtrim(); }
String.prototype.toMixedCase = function() { return this.substring(0,1).toUpperCase() + this.substring(1).toLowerCase() }
String.prototype.padLeft     = function(len,chr){ var s = this; while(s.length < len){ s = chr + s;} return s;}
String.prototype.padRight    = function(len,chr){ var s = this; while(s.length < len){ s = s + chr;} return s;}

/* CommonFunctions class
 */
function CF()
{
}

/* Class method declarations
 */
CF.Hide                             = CF_Hide;
CF.Show                             = CF_Show;
CF.IconFocus                        = CF_IconFocus;
CF.IconBlur                         = CF_IconBlur;
CF.ClickImage                       = CF_ClickImage;
CF.ImageOver                        = CF_ImageOver;
CF.SwapClass                        = CF_SwapClass;
CF.ToggleVisibility                 = CF_ToggleVisibility;
CF.blnSetFocusElement               = CF_blnSetFocusElement;
CF.DisableRightClick                = CF_DisableRightClick;
CF.arrGetControls                   = CF_arrGetControls;
CF.strGetStackTrace                 = CF_strGetStackTrace;
CF.AddEventListener                 = CF_AddEventListener;

function CF_AddEventListener(elm, eventType, func)
{
	if (elm.addEventListener)
	{
		elm.addEventListener(eventType, func, false); 
	} 
	else if (elm.attachEvent)
	{
		elm.attachEvent('on' + eventType, func);
	}
}

/* Hides HTML elements. This function accepts a variable parameter
 * list - each parameter can be a reference to an object or a string
 * that matches the id property of one or more elements.
 */
function CF_Hide()
{
	var objDiv;

	for (var i=0; i < arguments.length; i++) {
		if (typeof arguments[i] == "string") {
			objDiv = document.all.item(arguments[i]);
		} else {
			objDiv = arguments[i];
		}
		if (objDiv && "object" == typeof objDiv.style) {
			objDiv.style.display = "none";
			objDiv.style.visibility = "hidden";
		} else if (objDiv && objDiv.length) {
			for (var j=0; j < objDiv.length; j++) {
				arguments.callee(objDiv[j]);
			}
		}
	}
}

/* Shows HTML elements. This function accepts a variable parameter
 * list - each parameter can be a reference to an object or a string
 * that matches the id property of one or more elements.
 */
function CF_Show()
{
	var objDiv;

	for (var i=0; i < arguments.length; i++) {
		if (typeof arguments[i] == "string") {
			objDiv = document.all.item(arguments[i]);
		} else {
			objDiv = arguments[i];
		}
		if (objDiv && "object" == typeof objDiv.style) {
			objDiv.style.display = "inline";
			objDiv.style.visibility = "visible";
		} else if (objDiv && objDiv.length) {
			for (var j=0; j < objDiv.length; j++) {
				arguments.callee(objDiv[j]);
			}
		}
	}
}

function CF_IconFocus(objElement)
{
    CF.ImageOver(objElement.firstChild);
}

function CF_IconBlur(objElement)
{
    CF.ImageOver(objElement.firstChild);
}

/* The icons need to have the ability to obtain focus, so they are
 * wrapped in an <A>nchor tag. This function simulates clicking on
 * an image when pressing 'Enter' on the <A>nchor.
 */
function CF_ClickImage()
{
	var objImage = event.srcElement.firstChild;
	if (objImage && "IMG" == objImage.tagName && objImage.style.visibility != "hidden" && !objImage.disabled) {
		objImage.click();
	}
}

/* Swaps the source of an image from its hover-over state to its normal
 * state and vice-versa.
 */
function CF_ImageOver( objImage )
{
	if ( objImage.disabled && true == objImage.disabled) {
		return;
	}

	if (event.type == "mouseover") {
		CF.ImageOver.gobjMouse = event.srcElement;
	} else if (event.type == "mouseout") {
		CF.ImageOver.gobjMouse = null;
	}

	if (event.type == "mouseover" || event.type == "focus") {
		if ( objImage.src.match(/Off/i) ) {
			objImage.src = objImage.src.replace(/Off/i, "Hover");
			objImage.style.cursor = "hand";
		}
	} else if (event.type == "mouseout" || event.type == "blur") {
		// turn the image to the off state if the anchor surrounding
		// the image does NOT have focus and the cursor has left
		// the region.
		if (((event.srcElement.parentElement != document.activeElement)
			|| ! (document.activeElement.tagName == "A"))
			&& ! (CF.ImageOver.gobjMouse)) {
				if ( objImage.src.match(/Hover/i) ) {
					objImage.src = objImage.src.replace(/Hover/i, "Off");
					objImage.style.cursor = "default";
				}
		}
	}
}

/* Swaps the class of an element
 */
function CF_SwapClass( objElement, evt )
{
    var pos = objElement.className.indexOf("_");
    var baseClass = (pos > -1 ? objElement.className.substring(0,pos) : objElement.className);
    
    if (evt.type == "focus") {
        objElement.setAttribute("sysFocus","true");
        objElement.className = baseClass + "_Focus";
    } else if (evt.type == "blur") {
        objElement.removeAttribute("sysFocus");
        objElement.className = baseClass;
    } else if (evt.type == "mouseover" && !objElement.getAttribute("sysFocus")) {
        objElement.className = baseClass + "_Over";
    } else if (evt.type == "mouseout" && !objElement.getAttribute("sysFocus")) {
        objElement.className = baseClass;
    }
}

/* Toggles the visibility of an element and swaps out the controlling image.
 */
function CF_ToggleVisibility( strElmID, strImgID )
{
	var oElm = document.all.item(strElmID);

	if ( strImgID ) {
	    var oImg = document.all.item(strImgID);
	} else {
	    var oImg = event.srcElement;
	}

	if ("none" == oElm.style.display) {
		CF.Show( oElm );
		oImg.src = oImg.src.replace(/Expand/i,"Collapse");
		oImg.alt = oImg.alt.replace(/Show/i,"Hide");
	} else {
		CF.Hide( oElm );
		oElm.style.visibility = "hidden";
		oImg.src = oImg.src.replace(/Collapse/i,"Expand");
		oImg.alt = oImg.alt.replace(/Hide/i,"Show");
	}
}

/* Calls the focus method for the speicifed element checking to
 * make sure that the element can have focus.
 */
function CF_blnSetFocusElement( objElement )
{
	// if an element is hidden or disabled, it cannot receive focus. rather than
	// check all focusable conditions, we will catch any exceptions and continue
	// processing.
	try {

    	// Set focus on element
    	objElement.focus();

		// Attempt to select text in an input or textarea
		try {
			if ( objElement.tagName != "INPUT" || objElement.type != "button" ) {
				objElement.select();
			}
		} catch (Exception) {}

    	// The scrollIntoView() method should only be used if the scrollbars
    	// for the taskarea are on the frame - this will cause problems and
    	// should not be used if the scrollbars are on a div or other element
    	objElement.scrollIntoView();

		return true;

	} catch (Exception) {}

	return false;
}



/* Disables the context menu on a right click for anchors within the
 * given container.
 */
function CF_DisableRightClick( objContainer )
{
	var fcnReturn = function() {return false;};

	var colAnchor = objContainer.all.tags("A");
	var intNumAnchor = colAnchor.length;

	for (var i=0; i<intNumAnchor; i++) {
		colAnchor.item(i).attachEvent("oncontextmenu",fcnReturn);
	}
}

/* Get a list of DOM controls based on an attribute and value.
 */
function CF_arrGetControls( objContainer, strAttribute, strMatchValue )
{
	var arrControls;

	var colAll = objContainer.all;
	var arrControls = new Array();

	// if the attribute is id or name, change the algorithm for efficiency
	if ( strAttribute.match(/id|name/gi) )
	{
		arrControls = colAll[strMatchValue];
		if ( ! arrControls ) {
			arrControls = new Array();
		} else if ( !arrControls.length && ( typeof arrControls == "object" ) )	{
			arrControls = [arrControls];
		}
	}
	else
	{
		var intNumElements = colAll.length;

		for (var i=0; i<intNumElements; i++) {
			var elmCurrent = colAll.item(i);
//			var strValue = elmCurrent.getAttribute(strAttribute);
			var strValue = elmCurrent[strAttribute];
			if ( ( strMatchValue && strValue == strMatchValue ) ||
				 ( ! strMatchValue && strValue ) ) {
				arrControls[arrControls.length] = elmCurrent;
				}
		}
	}

	return arrControls;
}

/* Used for debugging purposes to get a stack trace
 */
function CF_strGetStackTrace()
{
	var strStackTrace = "";

	for (var a=arguments.caller; a!=null; a=a.caller) {
		var strName = new String(a.callee).match(/function[ ]*(\w*)/)[1];
		if ( (strName == null) || (strName.length == 0) ) strName = "anonymous";
		if ( strName.match(/^LogTS_/) ) continue; // Don't print if called from LogTS
//		if ( strName == "anonymous" ) {
//			strStackTrace += a.callee.toString() + "\n";
//		} else {
			strStackTrace += strName + "\n";
//		}
	}

	return strStackTrace;
}
