﻿// JScript File

/**
* ODACommonLibrary file version
* @returns the version of the current file
* @type string
*/
function ODACommonLibrary()
{
    return "1.0";
}

if(typeof SelectVersion == 'undefined' || SelectVersion() != "1.0"){
    alert("CommonLibrary.js requires Selection.js which could not be located. on page " + location.href);
}


//////////////////////////////////////////////////////////////////////////////////////////
////////    Textbox Helper Methods
//////////////////////////////////////////////////////////////////////////////////////////
/**
* Sets focus to the element and put the cursor at the end of the current Text
* @param{input} sender: the instance of the input field on which to set focus
*/
function setFocus(sender)
{
    sender.focus();
    sender.select();
    moveCursorToEnd(sender);
}

/**
* Sets color to black and removes the mask if the sender value
* matches the mask value.
* @param{input} sender: the instance of the input field on which to clear the mask.
* @param{string} mask: value to check for.
*/
function clearMask(sender,mask)
{
    sender.style.color = 'Black';
    if(sender.value == mask)
    {
        sender.value = '';
    }
}

/**
* If the value of sender is empty string ('') then it sets the value to the mask
* sent in and sets the color to gray.
* @param{input} sender: the instance of the input field on which to set the mask.
* @param{string} mask: value to set.
*/
function setMask(sender,mask)
{
    if(sender.value == '' || sender.value == mask)
    {
        sender.value = mask;
        sender.style.color = 'gray';
    }
}

/**
* Finds many times _char exists in _string.
* @param {string} _string: String that may contain '_char'.
* @param {char} _char: char to count instances in '_string'.
* @returns count of how many times char is found in string
* @type int
*/
function getCharCount(_string,_char)
{
    var count = 0;
    var lastIndex = -1;
    for(var j=0; j<_string.length; j++)
    {
        if(lastIndex == -1)
        {
            lastIndex = _string.indexOf(_char);
            if(lastIndex > -1){count++;}
        }
        else
        {
            var temp = _string.indexOf(_char,lastIndex+1);
            if(temp > -1)
            {
                lastIndex = temp;
                count++;
            }
        }
    }
    return count;
}

/**
* Gets previous character.
* @param {input} myField: field to get character before cursor
* @returns Character before cursor or '' if cursor is at begining.
* @type char
*/
function getPreviousChar(myField)
{
    var sel = new Selection(myField);
    var orgRng = sel.create();
    
    if(orgRng.start == 0)
        return "";
    
    sel.setRange(orgRng.start-1,orgRng.end);
    var nextChar = sel.create().text;
    
    sel.setRange(orgRng.start,orgRng.end);
    return nextChar;
}

/**
* Gets next character.
* @param {input} myField: field to get character after cursor.
* @returns Character after cursor or '' if cursor is at end.
* @type char
*/
function getNextChar(myField)
{
    var sel = new Selection(myField);
    var orgRng = sel.create();
    
    if(orgRng.end == $F(myField).length)
        return "";
    
    sel.setRange(orgRng.start,orgRng.end+1);
    var nextChar = sel.create().text;
    
    sel.setRange(orgRng.start,orgRng.end);
    return nextChar;
}

/**
* Moves cursor specified number of characters (negative to move backwards).
* @param {input} myField: field in which to move cursor.
* @param {int} count: number of charachters to move cursor.
*/
function MoveCursor(myField,count)
{
    var sel = new Selection(myField);
    var rng = sel.create();
    
    
    rng.start += count;
    if(rng.start < 0)
    {
        rng.start = 0;
    }
        
    if(rng.start > $F(myField).length)
    {
        rng.start = $F(myField).length;
    }
    
    sel.setRange(rng.start,rng.start);
}

/**
* Gets the curent position of the currsor.
* @param {input} myField: field in which to find cursor position.
* @returns where if the field the cursor is at
* @type int
*/
function getCursorPosition(myField)
{
    var rng = new Selection(myField).create();
    return rng.start;
}

/**
* Sets the curent position of the currsor.
* @param {input} control: field in which to set cursor position.
* @param {int} caret_position: position to set the cursor.
*/
function setCursorPosition(control, caret_position){
    new Selection(control).setRange(caret_position, caret_position);        
}

/**
* Same as getCursorPosition.
* @param {input} myField: field in which to find cursor position.
* @returns where if the field the cursor is at.
* @type int
* @see #getCursorPosition
*/
function getCaretPosition(myField)
{
    return getCursorPosition(myField);
}

/**
* Same as setCursorPosition
* @param {input} control: field in which to set cursor position.
* @param {int} caret_position: position to set the cursor.
* @see #setCursorPosition
*/
function setCaretPosition(control, caret_position){
    setCursorPosition(control, caret_position);      
}

/**
* Move cursor to end of field
* @param {input} myField: the cursor will be a the end of this field.
*/
function moveCursorToEnd(myField)
{
   var selection = new Selection(myField);
   selection.setRange(myField.value.length, myField.value.length);
}

/**
* Same as moveCursorToEnd
* @param {input} myField: the cursor will be a the end of this field.
* @see #moveCursorToEnd
*/
function moveCaretToEnd(myField)
{
   moveCursorToEnd(myField);
}

/**
* Move cursor to beginning of field
* @param {input} control: the cursor will be a the beginning of this field.
*/
function moveCursorToStart(control){
    setCursorPosition(control, 0);
}

/**
* Same as moveCursorToStart
* @param {input} control: the cursor will be a the beginning of this field.
* @see #moveCursorToStart
*/
function moveCaretToStart(control){
    moveCursorToStart(control);
}

/**
* Delete highlighted text/ Backspace
* @param {input} myField: delete the text from this field.
*/
function deleteAtCursor(myField)
{
    var selection = new Selection(myField);
    
    // get the range
    var rng = selection.create();
    
    // if the range start is more than 0 then move the start back one to increase the selection area
    if(rng.start > 0){
        rng.start -=1;
    }
    
    // set the selection
    selection.setRange(rng.start,rng.end);
    
    
    rng.setText('');
}

/**
* Insert value where the cursor is.
* @param {input} myField: Insert the text into this field.
* @param {string} myValue: Value to insert.
*/
function insertAtCursor(myField, myValue) 
{  
    var rng = new Selection(myField).create();
    rng.setText(myValue);
    new Selection(myField).setRange(rng.start+1,rng.start+1);
}

/**
* finds the position of the object passed in, and then returns 
* a two element array where 0=offsetLeft and 1=offsetTop
* recursive up two generations.
* @param {element} obj: element (or elements id) of which to find top left corner.
* @returns Array holding [left,top] of the element passed in.
* @type int[2]
*/
function findPos(obj) 
{
    if(typeof(obj) == 'string')
    { obj = $(obj); }
    
    var curleft = curtop = 0;
    if (obj.offsetParent) 
    {
        curleft = obj.offsetLeft
        curtop = obj.offsetTop
        for(var p = 0; p < 2; p++)
        {
            obj = obj.offsetParent;
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        }
    }
    return [curleft,curtop];
}

/**
* finds the position of the object passed in, and then returns 
* a two element array where 0=offsetLeft and 1=offsetTop
* recursive up generations till no object parent is found.
* @param {element} obj: element (or elements id) of which to find top left corner.
* @returns Array holding [left,top] of the element passed in.
* @type int[2]
*/
function findPosFull(obj) 
{
    if(typeof(obj) == 'string')
    { obj = $(obj); }
    
    var curleft = curtop = 0;
    if (obj.offsetParent) 
    {
        curleft = obj.offsetLeft
        curtop = obj.offsetTop
        while(obj.offsetParent)
        {
            obj = obj.offsetParent;
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        }
    }
    return [curleft,curtop];
}

/**
* Case insensitive search and replace
* @param {string} str: original string to search in.
* @param {string} oldVal: value to replace.
* @param {string} newVal: value to replace with.
* @returns string with newVal having replaced every instance of oldVal
* @type string
*/
function globalReplace(str,oldVal,newVal)
{
    return eval('str.replace(/' + oldVal + '/gi, "' + newVal + '");');
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////  Event Manipulation
/////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Add a function to be called on the window.onload event
* @param {function} func: function reference (or anonymous)
*/
function addLoadEvent(func) 
{
    var oldonload = window.onload;
    if (typeof window.onload != 'function') 
    {
        window.onload = func;
    } 
    else 
    {
        window.onload = function() 
        {
            if (oldonload) 
            {
                oldonload();
            }
            if(typeof func == 'function')
            { func(); }
            else
            { func; }
        }
    }
}


/**
* use this event to programatically subscribe to any event of any object
* simply pass in the objectName, the eventName you wish to subscribe to
* and the handler function
* @param {string} objectName: id of the control
* @param {string} eventName: name of the event (eg. 'onKeyPress', 'onLoad', etc)
* @param {function} handler: function reference (or anonymous)
*/
function addEventHandler(objectName,eventName,handler)
{
    var obj = $(objectName);
    var oldOnLoad = null;
    var oldFunc;
    
    eval('oldFunc = obj.' + eventName + ';');
    
    if (typeof oldFunc != 'function') 
    {eval('obj.' + eventName + ' = ' + handler);} 
    else 
    {eval('obj.' + eventName + ' = function() {if (oldFunc) {oldFunc();}handler();}');}
}

/**
* Cross browser suppport for events
* @param {event} e: event
* @returns curent event
* @type event
*/
function ensureEvent(e)
{
    if(!e){e = window.event;}
    
    return e;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////  Dom Parsing Helpers
/////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Get all elements of a form
* the first form of the document is used if no form is passed in
* @param {form} form: (optional)form to get elements from
* @returns array of elements
* @type element[]
*/
function getAllFormElements(form)
{
    if(form == null)
    {
        return document.forms[0].elements;
    }
    return form.elements
}

/**
* Get all elements that match *_id or = id and puts them in an array
* @param {string} id: Server id to look for on the client
* @returns array of elements
* @type element[]
*/
function getElementsByServerId(id)
{
    var elements = getAllFormElements(theForm);
	var retval = new Array();
	
	var index = 0;
	for (index = 0; index < elements.length; index++)
	{
		//var temp = elements[index].id
		if(endsWith(elements[index].id,id))
		{
		    retval[retval.length] = $(elements[index]);
		}
		//if(temp == 'ctl00_Main_Search_pnlSearchCriteria')
		//{alert('found');}
//		if(temp.length > id.length)
//		{
//			if(temp.substring(temp.length - id.length - 1, temp.length) == '_' + id)
//			{
//				retval[retval.length] = $(elements[index]);
//			}
//		}
//		else
//		{
//			if(temp == id)
//			{
//				retval[retval.length] = $(elements[index]);
//			}
//		}
	}
	
	return retval;
}

/**
* Calls $F (get value) using the first result returned by getElementsByServerId
* requires prototype.js.
* @param {string} fieldID: Server id to look for on the client
* @returns value of element specified by ServerID
* @type string
*/
function getFieldValue(fieldID)
{
    var tmp = getElementsByServerId(fieldID);
	if(tmp.length > 0)
	{
	    return $F(tmp[0]);
	}
}

/**
* Cross Browser support for getting the DomDocument
* @class Cross Browser support for DomDocument
* @constructor
* @returns string representation of the DomDocument
* @type DomDocument
* @throws Error if unable to find DOMDocument
* @throws Error if unable to parse document
*/
function getDomDocument()
{
	var adapter = '';
	if ('undefined' != typeof ActiveXObject) {
		adapter = 'MS';
	} else if ('undefined' != typeof document
		&& document.implementation
		&& document.implementation.createDocument
		&& 'undefined' != typeof DOMParser)
	{
		adapter = 'default';
	}
	switch (adapter) {
		case 'MS':
			return new (function () {
			    /**
                * creates an instance of the DomDocument
                * @returns ActiveX DOMDocument
                * @type ActiveXObject
                */
				this.createDocument = function () {
					var names = ["Msxml2.DOMDocument.6.0",
						"Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument",
						"MSXML.DOMDocument", "Microsoft.XMLDOM"];
					for (var key in names) {
						try {
							return new ActiveXObject(names[key]);
						} catch (e) {}
					}
					throw new Error('Unable to create DOMDocument');
				};
				/**
                * XML string representation of the document
                * @param {DomDocument} doc: document to serialize
                * @returns xml representation of the DomDocument
                * @type string
                */
				this.serialize = function (doc) {
					return doc.xml;
				};
				/**
                * loads a DomDocument from XML string representation
                * @param {string} xml: xml representation to deserialize
                * @returns navigable DomDocument from xml
                * @type DomDocument
                */
				this.parseXml = function (xml) {
					var doc = this.createDocument();
					if (!doc.loadXML(xml)) {
						throw new Error('Parse error');
					}
					return doc;
				};
			})();
		case 'default':
			return new (function () {
				/**
                * creates an instance of the DomDocument
                * @returns default DOMDocument
                * @type DomDocument
                */
				this.createDocument = function () {
					return document.implementation.createDocument("", "", null);
				};
				/**
                * XML string representation of the document
                * @param {DomDocument} doc: document to serialize
                * @returns xml representation of the DomDocument
                * @type string
                */
				this.serialize = function (doc) {
					return new XMLSerializer().serializeToString(doc);
				};
				/**
                * loads a DomDocument from XML string representation
                * @param {string} xml: xml representation to deserialize
                * @returns navigable DomDocument from xml
                * @type DomDocument
                */
				this.parseXml = function (xml) {
					var doc = new DOMParser().parseFromString(xml, "text/xml");
					if ("parsererror" == doc.documentElement.nodeName) {
						throw new Error('Parse error');
					}
					return doc;
				};
			})();
		default:
			throw new Error('Unable to select the DOM adapter');
	}
};

/**
* loads a DomDocument from XML string representation
* @param {string} xml: xml representation to deserialize
* @returns navigable DomDocument from a xml string
* @type DomDocument
*/
function parseXMLFromString(sXml)
{
	var doc = getDomDocument().parseXml(sXml);
	return doc;
}

/**
* parses Xml to get the value from a node.
* @param {DomDocument} Tags: xml DomDocument to get node from
* @param {int} index: index of Tags to search children for TagName
* @param {string} TagName: name of the node to get value from
* @returns value found within given node
* '' if node not found.
* @type string
*/
function GetNodeValue(Tags, index, TagName)
{
	if(Tags[index] && Tags[index].getElementsByTagName(TagName)[0] && Tags[index].getElementsByTagName(TagName)[0].firstChild)
	{
		return Tags[index].getElementsByTagName(TagName)[0].firstChild.nodeValue;
	}
	return '';
}

/**
* Loads a table element and populates rows and columns
* from the xml data<br>
* example XML format:<br>
* {<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;TableID&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ColumnName&gt;Row 1 Column 1 Data&lt;/ColumnName&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ColumnName&gt;Row 1 Column 2 Data&lt;/ColumnName&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ColumnName&gt;Row 2 Column 1 Data&lt;/ColumnName&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ColumnName&gt;Row 2 Column 2 Data&lt;/ColumnName&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;/TableID&gt;<br>
* }
* @param {string} xml: xml to build table from 
* Optional pass in the xml DomObject directly
* @returns Table element
* @type element
*/
function buildHTMLTable(xml)
{
	if(typeof(xml) == 'string')
	{
		xml = parseXMLFromString(xml);
	}
	
	var docRoot = xml.firstChild;//xml.getDocumentElement();
	var tbl = document.createElement("table");
	tbl.id = docRoot.nodeName;
	tbl.style.backgroundColor = 'White';
    var tblBody = document.createElement("tbody");
    tbl.appendChild(tblBody);
        
    for(rowIndex = 0; rowIndex < docRoot.childNodes.length; rowIndex++)
    {
        var rowNode = docRoot.childNodes[rowIndex];
        //Create Header
        if(rowIndex == 0)
        {
            var trHeader = document.createElement("tr");
            trHeader.className = "headerRow";
            tblBody.appendChild(trHeader);
            
            for(colIndex = 0; colIndex < rowNode.childNodes.length; colIndex++)
            {
                var colNode = rowNode.childNodes[colIndex];
                var td = document.createElement("td");
                trHeader.appendChild(td);
                td.innerText = colNode.nodeName;
            }
        }
        
        var tr = document.createElement("tr");
        if(rowIndex%2 == 0)
        {
            tr.className = "oddRow";
        }
        tblBody.appendChild(tr);
        
        for(colIndex = 0; colIndex < rowNode.childNodes.length; colIndex++)
        {
            var colNode = rowNode.childNodes[colIndex];
            var td = document.createElement("td");
            tr.appendChild(td);
            td.innerHTML = colNode.text;
        }
    }
	
	if(docRoot.childNodes.length == 0)
	{
	    var trEmpty = document.createElement("tr");
        tblBody.appendChild(trEmpty);
        
        var td = document.createElement("td");
        trEmpty.appendChild(td);
        td.innerText = "No rows returned!";
    }
	
	return tbl;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////  select objects
/////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Loads a select element text and (optional) values
* from the xml data<br>
* example XML format:<br>
* {<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;root&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Option&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Text&gt;Text1&lt;/Text&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Value&gt;Value1&lt;/Value&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Option&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Option&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Text&gt;Text2&lt;/Text&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Value&gt;Value2&lt;/Value&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Option&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;/root&gt;<br>
* }
* @param {string} select: Element id (optional: element object)
* of select to load
* @param {string} xml: Xml string (optional: xml Dom)
* of data to load into select
*/
function loadSelect(select, xml)
{
	if(typeof(select) == 'string')
	{
		select = $(select);
	}
	if(typeof(xml) == 'string')
	{
		xml = parseXMLFromString(xml);
	}
	clearSelect(select);
	
	var xmlOption = xml.getElementsByTagName('Option');
	for(var index = 0; index < xmlOption.length; index++)
	{
		var optn = document.createElement("OPTION");
		optn.text = GetNodeValue(xmlOption, index, 'Text');
	    optn.value = GetNodeValue(xmlOption, index, 'Value');
	    if(optn.text.length > 0)
			select.options.add(optn);
	}
}

/**
* clears all options from select element
* @param {string} sel: Element id (optional: element object)
* of select to load
*/
function clearSelect(sel)
{
	if(typeof(sel) == 'string')
	{
		sel = $(sel);
	}
	
	for (var index=sel.options.length-1; index>=0; index--)
	{
		sel.options[index] = null;
	}
	sel.selectedIndex = -1;
}

/**
* run the filter on select element from text in text element
* @param {string} selectID: Select Element id (optional: element object)
* @param {string} txtID: Text Input Element id (optional: element object)
* @private
*/
function applyFilter(selectID,txtID)
{
    var visible = $(selectID);
    var before = $F(visible);
    var hdn = $('hdn_' + selectID);
    var txt = $(txtID);
    clearSelect(visible);
    
    for(var index = 0; index < hdn.options.length; index++)
    {
        var optn = document.createElement("OPTION");
        optn.text = hdn.options[index].text;
        optn.value = hdn.options[index].value;
        if(optn.text.toUpperCase().indexOf(txt.value.toUpperCase()) > -1)
            visible.options.add(optn);
    }
    
    for(var index = 0; index < visible.options.length; index++)
    {
        var optn = visible.options[index];
        if(before == optn.value)
        {
            optn.selected = true;
            break;
        }
    }
}


/**
* initilize the hidden filter select
* this creates a hidden select and loads it with all the options
* that exist in the select object and sets up requried events.
* @param {string} select: Select Element id (optional: element object)
* @param {string} txt: Text Input Element id (optional: element object)
* @param {function} onChangeName: Optional function to run after filter
* is run
*/
function initSelectFilter(select,txt,onChangeName)
{
    var visible = $(select);
    var txt = $(txt);
    var hdn = $('hdn_' + visible.id)
    if(hdn == null)
    {
        //First Run
        hdn = document.createElement('select');
        hdn.id = 'hdn_' + visible.id;
        hdn.style.display = 'none';
    
        visible.up().appendChild(hdn);
        if(txt != null) { addEventHandler(txt,'onkeyup','function() { filterSelect("' + visible.id + '","' + txt.id + '","' + onChangeName + '"); }') }
    }
    
    clearSelect(hdn);
    
    for(var index = 0; index < visible.options.length; index++)
    {
        var optn = document.createElement("OPTION");
        optn.text = visible.options[index].text;
        optn.value = visible.options[index].value;
        if(optn.text.length > 0)
            hdn.options.add(optn);
    }
}

var filterTimer;
var timerRunning = false;

/**
* Runs at keyup of txt to filter a select list
* @param {string} selectID: Select Element id
* @param {string} txtID: Text Input Element id
* @param {function} onChangeName: Optional function to run after filter
* is run
* @private
*/
function filterSelect(selectID,txtID,onChangeName)
{
    if(timerRunning)
    {
        clearTimeout(filterTimer)
        timerRunning = false;
    }
    
    filterTimer = setTimeout('var before = $F("' + selectID + '"); applyFilter("' + selectID + '","' + txtID + '"); if(before != $F("' + selectID + '") && ' + onChangeName + ' != null) { ' + onChangeName + '();}',500);
    timerRunning = true;
}

/**
* Trades places fo the two Items in a select list
* @param {string} item1: Option Element id (optional: element object)
* @param {string} item2: Option Element id (optional: element object)
*/
function swapNodes(item1,item2) 
{
    item1 = $(item1);
    item2 = $(item2);
    
    if(item1 == item2)
    { return; }
    // We need a clone of the node we want to swap
    var itemtmp = item1.cloneNode(1);

    // We also need the parentNode of the items we are going to swap.
    var parent = item1.parentNode;

    // First replace the second node with the copy of the first node
    // which returns a the new node
    item2 = parent.replaceChild(itemtmp,item2);

    //Then we need to replace the first node with the new second node
    parent.replaceChild(item2,item1);

    // And finally replace the first item with it's copy so that we
    // still use the old nodes but in the new order. This is the reason
    // we don't need to update our Behaviours since we still have 
    // the same nodes.
    parent.replaceChild(item1,itemtmp);

    // Free up some memory, we don't want unused nodes in our document.
    itemtmp = null;
}

/**
* Set the Select element selected option by Value
* @param {string} select: Select Element id (optional: element object)
* @param {string} value: value of the option to mark as selected.
*/
function setSelectedValue(select, value)
{
    select = $(select);
    
    for(var j=0;j<select.options.length;j++)
    {
        if(select.options[j].value == value)
        {
            select.selectedIndex = j;
        }
    }
}

/**
* Set the Select element selected option by text
* @param {string} select: Select Element id (optional: element object)
* @param {string} text: text of the option to mark as selected.
*/
function setSelectedText(select,text)
{
    for(var j=0;j<select.options.length;j++)
    {
        if(select.options[j].text == text)
        {
            select.selectedIndex = j;
        }
    }
}


// returns an array of the <select> elements selected options values
function getSelectedValues(selectID){
    var select = $(selectID);
    var selVals = new Array();
    
    for(var j=0; j < select.length; j++)
    {
        if(select.options[j].selected)
        {
            selVals.push(select.options[j].value);
        }
    }
    
    return selVals;
}

// returns an array of the <select> elements selected options text
function getSelectedText(selectID){
    var select = $(selectID);
    var selText = new Array();
    
    for(var j=0; j < select.length; j++)
    {
        if(select.options[j].selected)
        {
            selText.push(select.options[j].text);
        }
    }
    
    return selText;
}

// returns an array of the <select> elements selected options items as { text: String, value: String }
function getSelectedItems(selectID){
    var select = $(selectID);
    var selText = new Array();
    
    for(var j=0; j < select.length; j++)
    {
        if(select.options[j].selected)
        {
            selText.push({value: select.options[j].value, text: select.options[j].text});
        }
    }
    
    return selText;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////  Hide and Show Draggables
/////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* hides the draggable object
* @param {string} obj: draggable id (optional: draggable object)
*/
function hideDraggable(obj)
{
    //obj Object or ID of Draggable Object to Hide
    if(typeof(obj) == 'string')
	{
		obj = $(obj);
	}
	
    var index = 0;
    for(index = 0; index < obj.childNodes.length; index++)
    {
        obj.childNodes[index].style.display = 'none';
    }
    
    obj.height = 0;
}

/**
* show the draggable object
* @param {string} obj: draggable id (optional: draggable object)
* @param {string} idsNotToShow: (Optional) '^' delimited list of ID's not to show
* @param {string} height: (Optional) height for draggable object if left blank default height used
*/
function showDraggable(obj,idsNotToShow, height)
{
    if(typeof(obj) == 'string')
	{
		obj = $(obj);
	}
	if(idsNotToShow == null)
	{
	    idsNotToShow = '_fIeLdS_sHoUlD_nOt_Be_NaMeD_tHiS';
	}
	
    var index = 0;
    var hdnarr = idsNotToShow.split('^');
    for(index = 0; index < obj.childNodes.length; index++)
    {
        var Show = true;
        for(var i2 = 0; i2 < hdnarr.length; i2++)
        {
            if(hdnarr[i2] == obj.childNodes[index].id)
            {
                Show = false;
            }
        }
        
        if(Show)
        {
            obj.childNodes[index].style.display = '';
        }
    }
    
    if(height != null)
    {
        alert(height);
        obj.style.height = height;
    }
    else
    {
        obj.style.height = '';
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////  AjaxExpandingRecursiveTree
/////////////////////////////////////////////////////////////////////////////////////////////////////

/** 
* Default location for TreeBranch Page
* @final
* @type string
*/
var treeBranchURL = 'TreeBranch.aspx';

/**
* get the root nodes and set up events functions for tree object
* @param {string} elementToPopulate: id of the element to place the tree
* @param {string} className: Qualified class name of objects to load into the tree
* @param {string} textPropertyName: Property on the class from which to take the text for the tree
* @param {string} lnkOnClickFunction: (Optional) function to call when Item is clicked
* @param {string} lnkOnContextClickFunction: (Optional) function to call when Item is right clicked
* @param {string} treeBranchURLOverride: (Optional) override the default treeBranch url
*/
function initializeTree(elementToPopulate,className,textPropertyName,lnkOnClickFunction,contextAttributeValue, treeBranchURLOverride)
{
    if(treeBranchURLOverride) { treeBranchURL = treeBranchURLOverride; }
    getBranch(elementToPopulate,'NULL',className,textPropertyName,lnkOnClickFunction,contextAttributeValue)
}

/**
* toggle the tree branch (visible: hidden)
* @param {string} sendingImg: image object that was clicked
* @param {string} elementToPopulate: id of the element to place the tree branch
* @param {string} className: Qualified class name of objects to load into the tree branch
* @param {string} textPropertyName: Property on the class from which to take the text for the tree
* @param {string} parentID: id of the tree branch from which to find children
* @param {string} lnkOnClickFunction: (Optional) function to call when Item is clicked
* @param {string} lnkOnContextClickFunction: (Optional) function to call when Item is right clicked
* @private
*/
function toggleTree(sendingImg,elementToPopulate,className,textPropertyName,parentID,lnkOnClickFunction,contextAttributeValue)
{
    if(IsValidPattern(sendingImg.src,'^.*plus.gif$'))
    {
        sendingImg.src = "images/minus.gif";
        sendingImg.alt = "Collapse";
        $(elementToPopulate).style.display = 'inline';
        
        getBranch(elementToPopulate,parentID,className,textPropertyName,lnkOnClickFunction,contextAttributeValue)
    }
    else
    {
        sendingImg.src = "images/plus.gif";
        sendingImg.alt = "Expand";
        $(elementToPopulate).style.display = 'none';
    }
}

/**
* load the tree branch from the server based on Parent ID
* @param {string} elementToPopulate: id of the element to place the tree branch
* @param {string} className: Qualified class name of objects to load into the tree branch
* @param {string} parentID: id of the tree branch from which to find children
* @param {string} textPropertyName: Property on the class from which to take the text for the tree
* @param {string} lnkOnClickFunction: (Optional) function to call when Item is clicked
* @param {string} lnkOnContextClickFunction: (Optional) function to call when Item is right clicked
* @private
*/
function getBranch(elementToPopulate,parentID,className,textPropertyName,lnkOnClickFunction,contextAttributeValue)
{
    var params = "";
    params += 'ParentID=' + parentID;
    params += '&ClassName=' + className;
    params += '&TextPropertyName=' + textPropertyName;
    params += '&LnkOnClickFunction=' + lnkOnClickFunction;
    params += '&ContextAttributeValue=' + contextAttributeValue;
            
    ajaxUpdate(elementToPopulate,treeBranchURL,params,_getBranchSuccess);
}

function _getBranchSuccess()
{
    if(typeof(getBranchSuccess) == 'function'){ getBranchSuccess(); }
}


/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////  JSON
/////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* get a Json Object from elements of a given css classname within a given container
* @param {string} container: id of the element (optional: draggable object) to build the Json object from
* @param {string} className: css classname on inputs to gather values from
*/
function buildJSON(container, className)
{
    //build a JSON object from all child inputs with the given className
    
    if(typeof container == 'string')
    {
        container = $(container);
    }
    
    var UserInputs = container.select('.' + className);
    
	function myObj(){};
	UserInputs.each(function(s){ if($(s) && $(s).id.length > 0) { eval('myObj.prototype.' + $(s).id + ' = "' + $F(s) + '";');} });
	//alert(Object.toJSON(new myObj()));
	return Object.toJSON(new myObj());
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////  XML
/////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* load inputs from xml string<br>
* example XML format:<br>
* {<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;root&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Option&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Name&gt;ElementID1&lt;/Name&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Value&gt;Value1&lt;/Value&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Option&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Option&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Name&gt;ElementID2&lt;/Name&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Value&gt;Value2&lt;/Value&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Option&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;/root&gt;<br>
* }
* @param {string} xml: xml string with id's and values
*/
function loadFormFromXML(xml)
{
    var xml = parseXMLFromString(xml);

    var xmlOption = xml.getElementsByTagName('Option');
    for(var index = 0; index < xmlOption.length; index++)
    {
        var ElemName = GetNodeValue(xmlOption, index, 'Name');
        var Value = GetNodeValue(xmlOption, index, 'Value');
        //alert('ID: ' + ElemName + '\r\nValue: ' + Value);

        var element = $(ElemName);
        //try formbuilder extensions
        if(element == null) { element = $(ElemName + '_txt'); }
        if(element == null) 
        {
            var arr = getElementsByServerId(ElemName + '_chk')
            if(arr.length > 0) { element = arr[0]; }
        }
        if(element == null)
        {
            var arr = getElementsByServerId(ElemName + '_ddl')
            if(arr.length > 0) { element = arr[0]; }
        }
        if(element == null)
        {
            //alert('Property ' + ElemName + ' was not set'); 
            continue;
        }
        
        if(element.visible() && !element.isDisabled)
        { 
            try{
                element.focus(); 
            }
            catch (ex){
                // don't do anything here
            }
        }
        
        $S(element, Value);
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////  Ect
/////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Trims whitespace from beginning and ending of a string
* @param {string} str: string to trim
* @return string with no leading or trailing whitespaces
* @type string
*/
function trim(str) {
	var	str = str.replace(/^\s\s*/, ''),
		ws = /\s/,
		i = str.length;
	while (ws.test(str.charAt(--i)));
	return str.slice(0, i + 1);
}

String.prototype.trim = function(){
    return trim(this);
}


/**
* Check to see if string starts with a string2Match
* @param {string} string2Test: string to check beginning
* @param {string} string2Match: string that beginning must match
* @return true if matches, false if doesn't
* @type bool
*/
function startsWith(string2Test,string2Match)
{
    var regExPattern = "^" + string2Match + ".*";
    var regEx = new RegExp(regExPattern);
    
    if(string2Test.match(regEx))
    {
        return true;
    }
    else
    {
        return false;
    }
}

/**
* Check to see if string ends with a string2Match
* @param {string} string2Test: string to check end
* @param {string} string2Match: string that end must match
* @return true if matches, false if doesn't
* @type bool
*/
function endsWith(string2Test,string2Match)
{
    var regExPattern = ".*" + string2Match + "$";
    var regEx = new RegExp(regExPattern);
    
    if(string2Test.match(regEx))
    {
        return true;
    }
    else
    {
        return false;
    }
}

/**
* Check to see if string contains with a string2Match
* @param {string} string2Test: string to check contains
* @param {string} string2Match: string that string2Test must contain
* @return true if matches, false if doesn't
* @type bool
*/
function contains(string2Test,string2Match)
{
    var regExPattern = ".*" + string2Match + ".*";
    var regEx = new RegExp(regExPattern);
    
    if(string2Test.match(regEx))
    {
        return true;
    }
    else
    {
        return false;
    }
}

/**
* Check to see if string starts with a regExPattern
* @param {string} string2Test: string to check match
* @param {string} regExPattern: string pattern that string2Test must match
* @return true if matches, false if doesn't
* @type bool
*/
function matches(string2Test,regExPattern)
{
    var regEx = new RegExp(regExPattern);
    
    if(string2Test.match(regEx))
    {
        return true;
    }
    else
    {
        return false;
    }
}

/**
* Creates a DivWindow with all properties on the object passed in
* @param {object} object: object to see properties of
*/
function $O(object)
{
    var div =divWindow('object_inspector','Object Details');
    var innerDiv = $('object_inspector_content');
    innerDiv.innerHTML = '';
    for(property in object)
    {
        if(property == "innerHTML")
        {
            innerDiv.innerHTML += 'escaped ' + property + ':: ' + object.innerHTML.escapeHTML() + '<br />';
        }
        
        innerDiv.innerHTML += property + ':: ' + eval('object.' + property) + '<br />';
    }
}

/**
* Creates a floating draggable div with close button
* 
*  ID's you can call
*  ID               The ID you passed in will be the Containing Div's id
*  ID_content       The ID of the div that will contain the content
*  ID_handle        The ID of the table row used to move the draggable
*  ID_closeImage    The ID of the image used to close the divWindow
*  ID_loadingImage  The ID of the image used to wait for the loading of the content
*  ID_iframe        (Optional) The ID of the Iframe if src parameter was used
* @param {string} id: id of the Div to make a div window out of.
* div will be created if doesn't already exist.
* @param {string} title: text that will show in the title bar
* @param {string} src: (Optional) if included it will polulate the ID_contentdiv with an 
*  iframe pointed to the given src.
*  This is for new divs only. not re-displaying existing divs 
*  (iframe only created when this parameter is populated.)
* @return div that is the div window
* @type element
*/
function divWindow(id, title, src)
{
    
    //src is optional if included it will polulate the ID_contentdiv with an iframe pointed to the given src
    //  This is for new divs only. not re-displaying existing divs
    //  
    
    var div = $(id);
    if(div == null)
    {
        var htmlString = '<div id="'+ id +'" class="divWindow" style="position:absolute; z-index:100000">';
        htmlString += '    <table cellspacing="0px" border="0px">';
        htmlString += '        <tbody>';
        htmlString += '              <tr id="' + id + '_handle" class="divWindowHeader">';
        htmlString += '                  <td>' + title + '</td>';
        htmlString += '                  <td style="padding-top: 0px; vertical-align: top; text-align: right;">';
        htmlString += '                      <img src="/images/close.png" style="cursor:hand;" onclick="$(\'' + id + '\').hide()" />';
        htmlString += '                  </td>';
        htmlString += '              </tr>';
        htmlString += '              <tr>';
        htmlString += '                  <td colspan="2">';
        htmlString += '                      <div id="' + id + '_content" style="min-height: 300px; overflow: auto;">';
        
        if(src != null && src.length > 0)
        {
            htmlString += '              <iframe id="' + id + '_iframe" style="height: 100px; width: 100%;" frameborder="0px" marginwidth="0px" src="'+ src +'"></iframe>';
        }
        else
        {
            htmlString += '              <img id="' + id + '_loadingImage" src="/images/loading.gif" />';
        }
        
        htmlString += '                      </div>';
        htmlString += '                  </td>';
        htmlString += '              </tr>';
        htmlString += '        </tbody>';
        htmlString += '    </table>';
        htmlString += '</div>';
        
        $(document.body).insert(htmlString);
        div = $(id);
    }
    else
    {
        div.style.display = 'block';
    }
    
    
    if((typeof Draggable) == 'function')
    {
        new Draggable(div.id, {handle:div.id + "_handle", snap:[5,5]});    
    }
    
    return div;
}

/**
* Pads a string with a character untill it is the requested length
* usage paddedString(4,'String','0',true);
* equivilent to paddedString(4,'String');
* @param {int} finishLength: final length to pad to
* @param {string} str: string that needs padding
* @param {char} character: (Optional) Character to pad with (default 0)
* @param {bool} padLeft: (Optional) pad left side of original string (default true)
* @return string padded with char
* @type string
*/
function paddedString(finishLength,str,character,padLeft)
{
	if(padLeft == null)
	{
		padLeft = true;
	}
	if(character == null || character.length < 1)
	{
		character = '0';
	}
	if(character.length > 1)
	{
		character = character.substring(0,1);
	}
	if(str == null)
	{
		str = '';
	}
	str += '';
	if(finishLength == null)
	{
		finishLength = 0;
	}
	
	while(str.length < finishLength)
	{
		if(padLeft)
		{
			str = character + str;
		}
		else
		{
			str = str + character;
		}
	}
	return str;
}

/**
* gets a string representation of current date (Browser)
* @return string representation of current date
* @type string
*/
function nowToString()
{
	var date = new Date();
	return paddedString(2,date.getMonth()) + '/' + paddedString(2,date.getDate()) + '/' + date.getFullYear() + ' ' + paddedString(2,date.getHours()) + ':' + paddedString(2,date.getMinutes()) + ':' + paddedString(2,date.getSeconds());
}

/**
* takes a foat value and displays it in Common US Dollar notation
* @param {float} value: value to display as Currency
* @param {string} symbol: Currency Symbol to use default ('$')
* @param {float} accuracy: accuracy to use in displaying currency default (2) max(10)
* @return string representation of US Dollars
* @type string
*/
function formatAsMoney(value, symbol, accuracy)
{
    if(symbol == null)
    { symbol = '$'; }
    if(accuracy == null)
    { accuracy = 2; }
    
    var money = parseFloat(value)
    //money = Math.round(100 * (money))/100;
    //needed more precision when total amount less than $0.01
    
    var decimalIndex = String(money).indexOf('.');
    var length = String(money).length;
    var retString = symbol + ' ' + String(money);
    if(decimalIndex < 0)
    {
        retString +=  ".";
    }
    
    retString += "0000000000";
    return retString.substring(0, decimalIndex + 3 + accuracy);
}

var checkingForDeletedFalseEvalScript = '';
var humanReadableIDValue = ''
var checkingForDeleted = false;
/**
* Checks with server to see if object with Human Readable Identifier
* exists deleted in the database
* for use with formbuilder pages
* @param {string} prop: Human Readable Identifier property of class
* @param {string} falseEvalScript: (Optional) script to eval if item not reactivated
*/
function existsDeleted(prop,falseEvalScript)
{
    if(!checkingForDeleted)
    {
        //prevent multiple clicks
        checkingForDeleted = true;
        setTimeout('checkingForDeleted = false;',5000);

        checkingForDeletedFalseEvalScript = falseEvalScript;

        var className = 'UserInputControl';

        var UserInputs = $('body').select('.' + className);
        UserInputs.each(function(s){ if($(s).id.indexOf(prop + '_') == 0) { humanReadableIDValue = $F(s); } });

        ServerFunction('NewExistsDeletedNotActive|' + humanReadableIDValue, null);
    }
}

/**
* Server callback from call to see if item exists on DB
* for use with formbuilder pages
* @param {string} args: 'True' or 'False' ('True' means it can be reactivated)
* @param {string} context: (Optional) context passed to server
* @private
*/
function NewExistsDeletedNotActive(args, context)
{
    if(args == 'True')
    {
        if(confirm(humanReadableIDValue + ' exists marked as deleted.\r\n Would you like to reactivate it rather than create a new one?'))
        {
            window.location.href = 'default.aspx?screen=Reactivate&TypeTableName=InventoryItem&CurrentValue='+ humanReadableIDValue + '&Redirect=default.aspx?screen=' + getQueryStringValue('screen');
        }
        else
        {
            setTimeout('eval(\'' + checkingForDeletedFalseEvalScript + '\');',10);
        }
    }
    else
    {
        setTimeout('eval(\'' + checkingForDeletedFalseEvalScript + '\');',10);
    }
    checkingForDeletedFalseEvalScript = '';
    humanReadableIDValue = '';
}

/**
* Set any element input or select control
* for select lists tries value first then text
* @param {string} element: ID or obj to populate value
* @param {string} value: value to set on element
* @throw nothing
*/
function $S(element, value)
{
    if(typeof element == 'string')
    {
        element = $(element);
    }
    
    if (element == null)
    { return; }
    
    switch(element.tagName)
    {
        case "CHECKBOX":
            if(getBool(value))
            { element.checked = true; }
            else
            { element.checked = false; }
            return;
        case "SELECT":
            element.selectedIndex = -1;
            for (var index=element.options.length-1; index>=0; index--)
	        {
		        if(element.options[index].value == value)
		        {
		            element.options[index].selected = true;
                    return;
                }
	        }
	        for (var index=element.options.length-1; index>=0; index--)
	        {
		        if(element.options[index].text == value)
		        {
		            element.options[index].selected = true;
                    return;
                }
	        }
	        if(element.options[0])
	        {
	            element.options[0].selected = true;
	        }
            return;
        case "INPUT":
            if(element.type.toUpperCase() == "CHECKBOX")
            {
                if(getBool(value))
                { element.checked = true; }
                else
                { element.checked = false; }
            }
            else
            {
                element.value = value;
            }
            return;
        default:
            element.value = value;
            return;
    }
}

/**
* Get value from any element input or select control
* calls prototypes $F() but catches errors
* @param {string} element: ID or obj to populate value
* @return the value of the object
* @type object
* @throw nothing
*/
function $G(element)
{
    try
    {
        return $F(element);
    }
    catch(ex)
    {
        return '';
    }
}

/*
* Get value from a RadioGroup by name
* @param {element} el: The parent form for the Radio Group
* @param {string} radioGroup: The name of the Radio Group
* @return the value of the Radio Group
* @type string
*/
function $RF(el, radioGroup) 
{
	if($(el).type && $(el).type.toLowerCase() == 'radio') 
	{
		var radioGroup = $(el).name;
		var el = $(el).form;
	} 
	else if ($(el).tagName.toLowerCase() != 'form') 
	{
		return false;
	}
 
	var checked = $(el).getInputs('radio', radioGroup).find(
		function(re) 
		{
			try
			{
				if(re.checked)
					return re.value;
			//return re.checked;
			}
			catch(e)
			{
				debug(e.message);
			}
		}
	);
	return (checked) ? $F(checked) : null;
}

/*
* Finds the Radio Group of the radio button passed as el.  Then sets the Radio button
* in the Radio Group that matches the value.
* @param {element} el: One of the Radio Buttons in the Radio Group that needs to be set
* @param {string} value: The value in the Radio Group that should be selected
* @return indication of successful selection
* @type bool
*/
function selectRadioButtonValue(el, value) {
    try
    {
        if($(el).type && $(el).type.toLowerCase() == 'radio') 
        {
            var radioGroup = $(el).name;
            var el = $(el).form;
        } 
        else if ($(el).tagName.toLowerCase() != 'form') 
        {
            return false;
        }
 	    var checked = false;
        checked = $(el).getInputs('radio', radioGroup).find(
            function(re) 
            {
        	    try
        	    {
	        	    if(re.value == value)
	        	    {
	        		    re.checked = true;
	        		    return true;
	        	    }
        	    }
		   	    catch(e)
		   	    {
		   		    debug(e.message);
		   	    }
            }
        );
    }
    catch(e)
    {
	    debug(e.message);
    }
    return checked;
}

/**
* hide lookup button for read only fields
* for use with form builder pages (or similar form)
* @param {string} element: ID or obj to populate value
* @throw nothing
*/
function hideLookupButton(element)
{
    if(typeof element == 'string')
    {
        element = $(element);
    }
    
    if (element == null)
    { return; }
    
    var btn = element.next();
    if(typeof btn != 'undefined' && btn.tagName == 'BUTTON')
    { btn.hide(); }
}

/**
* Check to See if String represents a boolean Value
* @param {string} str: string to convert to bool
* @return true if string can be matched as such false otherwise
* @type bool
*/
function getBool(str)
{
    str = String(str).toUpperCase();
    if(str == 'Y' || str == 'YES' || str == 'ON' || str == 'CHECKED' || str == 'T' || str == 'TRUE' || str == '1')
    {
        return true;
    }
    return false;
}
                
/**
* Loops through all child elements and removes them
* @param {string} element: ID or obj from which to remove children
*/
function clearChildren(element)
{
    if(typeof element == 'string')
    {
        element = $(element);
    }
    
    var elems = element.childElements()
    for(var index = 0; index < elems.length; index++)
    {
        elems[index].remove();
    }
}

var curStatus = 0;
var m_divStatus_img = null;
var statusImages = new Array();
statusImages[0] = new Image(100,100);
statusImages[0].src = './images/loader/loader-idle.gif';

statusImages[1] = new Image(100,100);
statusImages[1].src = './images/loader/loader.gif';

statusImages[2] = new Image(100,100);
statusImages[2].src = './images/loader/loader-stopped.gif';

/**
* Sets the status graphic.  Once in error status, use resetStatus to return to idle status.
* @param {int} _newStatus: New Desired status 0: idle, 1: processing, 2: error
*/
function setStatusImage(_newStatus)
{
    try{
        if(m_divStatus_img == null){m_divStatus_img = $('divStatus_img');}
        if(m_divStatus_img == null){return;}
        
        if(curStatus < 2)
        { setTimeout("m_divStatus_img.src = statusImages[" + _newStatus + "].src", 300); }
    }catch(ex){
    }
}

/**
* Sets the status graphic back to idle from error.
*/
function resetStatusImage()
{
    curStatus = 1;
    setStatusImage(0);
}

/**
* Builds a context menu that will eval the securitycontext attribute of any anchor
*/
function BuildSecurityContextMenus()
{
	var menuItems = [{
			name: 'Security', className: 'protoMenuItem', callback: function(e){ eval(Event.element(e).securitycontext); }
		}];
			
	new Proto.Menu({selector: 'a[securitycontext]',
					className: 'protoMenu desktop',
					menuItems: menuItems});
}

/**
* Check to see if string is a real number
* @param {string} string2Test: string to check
* @return true if matches, false if doesn't
* @type bool
*/
function isNumeric(string2Test)
{
    var regExPattern = "(^(([0-9]*\\.[0-9]+)|([0-9]*)|(\\.[0-9]+)|(-[0-9]*\\.[0-9]+)|(-[0-9]*)|(-\\.[0-9]+))$)";
    return matches(string2Test,regExPattern);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////  SQL Helper function
/////////////////////////////////////////////////////////////////////////////////////////////////////


/**
* Check for invalid words while building formulas
* @param {string} str: string to parse for invalid words.
* @return true if there are no injection words found
* @type bool
* @throws alert
*/
function checkForInjection(str)
{
    if(IsValidPattern(str.toLowerCase(),'^.* update .*|.* delete .*|.* drop .*|.* create .*|.* alter .*|.* truncate .*$'))
    {
        alert(" Statements that contain 'UPDATE', 'DELETE', 'DROP', 'CREATE', 'ALTER' or 'TRUNCATE' are not excepted");
        return false;
    }
    return true;
}
