// --------------------
//   global variables 
// --------------------

// list of names of months and days of the week
var CURRENT_TIME = new Date();
var MONTH_NAME=["January", "February", "March", "April", "May", "June","July", "August", "September", "October", "November", "December"];
var WEEKDAY_NAME=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];

var hiddenMagicName = "PJMR";
var hiddenActionName = "ACTION_REQUESTED";
var hiddenActionCategoryName = "ACTION_CATEGORY";
var hiddenClassName = "DXGenClassName";
var hiddenRequestIDName = "PJ_REQ_ID";
var realSubmit;
var magicTargetName = "PJMRRC";
var magicParamName = "PJMRP1";
var hiddenOpHttpId = "opid";
var jsPageLock = false;
// WOW 6.5.04.05 - default WOW form name
var formName = 'theForm';

// %%ROWSTYLE milliseconds to wait for a double click after a single click (JE/25/2007)
// no longer used (JE 11/30/2007)
//var intClickTimeout = 250;

/**
 * Helper method used when debugging
 * @since WOW 6.5.04
 */
function debug(sSource, sMessage) {
	// WOW 6.5.04.15 - added JS debug method
	var valid = true;
	
	// to turn off debugging for a given source, just add
	// the source to the following if check
	if (sSource == 'Main' || sSource == null || sSource == 'Ajax' || sSource == 'Clicking') {
		valid = false;
	}
	
	if (valid && sSource && sSource.indexOf ('Ajax') >= 0) {
		// poping up the alert window can cause issues with Ajax code, so instead write messages to the log (JE 03/06/2007)
		setTimeout(function() { throw new Error("[debug] " + sMessage); }, 0);
	}
	else if (valid) {
		alert(sMessage);
	}
}

function isPageLocked() {
  return jsPageLock;
}
function unLockPage() {
  jsPageLock = false;
}
function lockPage() {
  jsPageLock = true;
}

function loadPage(uri) {
 location = uri;
}

function displayError(message) {
	if (message != null && message.length > 0) {
		alert(message);
	}
}

function runWOWOperation(opid) {
	getElement("opid").value = opid;
	getForm().submit();
}

function performMagic(magicId) {
	return performMagic(magicId, null);
}

function performMagic(magicId, targetWindow, properties) {
	if (isPageLocked()) {
		return false;
	}
	
    getElement(hiddenMagicName).value=magicId;
    if (targetWindow != null) {
    	// WK 090804 - changed to == instead of = for targetName comparison as all popups were opening in same window, also
    	// changed popup to popupnewwindow as popup was already being used by a customer
    	// (KGetting 1/17/2008) - fix extra blank window when a new window is desired (_BLANK)
		var targetName = targetWindow.toUpperCase();
		if (targetName == "_BLANK") {
			targetName = "popupnewwindow";
		}
		if (properties) {
			// let's ensure the target window is open & has the properties applied
//			openWindow ('about:blank', targetWindow, properties);
			window.open('', targetName, properties);
		}

	  	originaltarget = getForm().target;
			getForm().target = targetName;
			getForm().submit();
			getForm().target = originaltarget;
	}
	else {
		// WOW 6.5.04.13
	  	// lock page to prevent double click
	  	lockPage();
	  
	  	getForm().submit();

     	// unlock page later on to allow future MRs (from back button, etc)
     	setTimeout('unLockPage()', 500);
 
	}
	getElement(hiddenMagicName).value="";
	return false;
}

function performWindowMagic(sMagicKey, sTarget, sProperties) {
	if (isPageLocked()) {
		return false;
	}
	// (KGetting 1/17/2008) - fix extra blank window when a new window is desired (_BLANK)
//	opened = openWindow('about:blank', sTarget, sProperties);  // PerformMagic handles this.
	return performMagic (sMagicKey, sTarget, sProperties);	// Add the properties pararmeter
}

function performActionCategory(actionCategoryId, actionId) {
	return performActionCategory(actionCategoryId, actionId, null);
}

function performActionCategory(actionCategoryId, actionId, targetWindow) {
	if (isPageLocked()) {
		return false;
	}
	getElement(hiddenActionCategoryName).value = actionCategoryId;
	return performAction(actionId, targetWindow);
}

function performAction(actionId) {
	return performAction(actionId, null);
}

function performAction(actionId, targetWindow, properties) {

	if (isPageLocked()) {
		return false;
	}
	
	getElement(hiddenMagicName).value="";
	getElement(hiddenActionName).value=actionId;
	
	if (targetWindow != null) {
	
	if (properties) {
		// let's ensure the target window is open & has the properties applied
		openWindow ('about:blank', targetWindow, properties);
	}
	originaltarget = getForm().target;
		getForm().target = targetWindow;
		getForm().submit();
		getForm().target = originaltarget;
	}
	else {
	   // WOW 6.5.04.13
	   // lock page to prevent double click
	   lockPage();
	   getForm().submit();
	   // unlock page later on to allow future MRs (from back button, etc)
	   setTimeout('unLockPage()', 500);
	}
	getElement(hiddenActionName).value="";
	return false;
}

function performNewWindowAction(actionId, targetWindow, windowWidth, windowHeight) {
	if (isPageLocked()) {
		return false;
	}

	wHandle = window.open ('about:blank', targetWindow, 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,width='+ windowWidth + ',height=' + windowHeight);
	if (!wHandle.opener)
    		wHandle.opener = self;
	return performAction (actionId, targetWindow);
}

function performNewWindowMagic(magicId, targetWindow, width, height) {
	if (isPageLocked()) {
		return false;
	}

	openWindowUsingProperties("", targetWindow, width, height, false, false, false, false, false, false, false, false);

	return performMagic (magicId, targetWindow);
}

function doMagic(magicId, targetObjectKey, magicParams) { 
	if (isPageLocked()) {
		return false;
	}

     getElement(magicTargetName).value=targetObjectKey; 
     getElement(magicParamName).value=magicParams; 
     return performMagic(magicId, null);
}

function doMagic(magicId, targetObjectKey, magicParams, targetWindow) { 
	if (isPageLocked()) {
		return false;
	}

     getElement(magicTargetName).value=targetObjectKey; 
     getElement(magicParamName).value=magicParams; 
     return performMagic(magicId, targetWindow); 
}

function getElementById(elementid) {
	return document.getElementById(elementid);
}

function getElement(elementName) {
	return getForm().elements[elementName];
}

function getForm() {
	// WOW 6.5.04.04
	return document.forms[formName];
}

function setRequestID(reqID) {
	getElement(hiddenRequestIDName).value = reqID;
}
	



// code to disable the return key for the submit buttons
function keyPress (e) {
// method altered on 12-5-2003 by JE to allow the return button to kick off searches
// when a parameter input field has focus, and to support mozilla
        var keycode;
        var source;
        // ie
        if (window.event) {
                keycode = window.event.keyCode;
        }
        // netscape
        else if (e) {
                keycode = e.which;
        }
        else {
                return true;
        }


        // keycode for the enter key is 13
        if (keycode == 13) {
                if (window.event || e) {
                        var source;


                        if (window.event) {
                                // ie
                                source = window.event.srcElement;
                        }


                        if (e) {
                                // mozilla
                                source = e.target;
                        }


                        if (source.type && source.type == 'textarea') {
                                // allow enter on text area
                                return true;
                        }
                        
                        // allow the source to decide if the key press should be processed %%JAVA-AC (JE 04/19/2007)
                        if (source.isAllowKeyPress) {
                        	if (!source.isAllowKeyPress (e)) {
                        		// hack to let the autocompleter process the event
                        		if (source.autocompleter && document.body.onkeyup) {
                        			document.body.onkeyup(e);
                        		}
                        		return false;
                        	}
                        }
                        
                        // if the source is a text field then find the button corresponding to that
                        // text field and click it (12/05/2003 JE)
                        if (source.name) {
                                underscore = source.name.indexOf ('_');
                                // when the textfield name is something like ¤1234567_0 the corresponding button
                                // name is ¤1234567
                                if (underscore > 0) {
                                        targetButton = getElement (source.name.substring (0, underscore));


                                        if (targetButton && targetButton.type && targetButton.type == 'button') {
                                                targetButton.click();
                                        }
                                }
                        }
                }
                return false;
        }


        return true ;
}


document.onkeypress = keyPress;


/**
 * Open a new window with the given url, target, and properties.  Below is a list
 * of properties a window may have.  Width and height are ints, and the rest are
 * either 'yes' or 'no'.
 * 
 *  width ------- window width
 *  height        window height
 *  toolbar ----- show toolbar
 *  location      show location bar (address bar)
 *  directories - show directors (bookmarks / links)
 *  status        show status bar
 *  menubar ----- show menu bar
 *  scrollbars    show scroll bars
 *  resizable --- allow resizing
 *  copyhistory   copy history (back & forward - previsouly visited pages
 * 
 * Properties must be in the format <property name>=<yes | no> with a comma in
 * between each property.  (e.g. "width=300,height=300,toolbar=yes,scrollbars=no")
 *
 * @param sUrl         location of the new window
 * @param sTarget      name of the new window the url should load in
 * @param sProperties  properties of the new window (see other
 *                     openWindow method for different properties)
 */
function openWindow(sUrl, sTarget, sProperties) {
  newWin = window.open(sUrl, sTarget, sProperties);
	if (!newWin.opener)
		newWin.opener = self;

	newWin.focus();
	return false;
}

 
/**
 * Gets 'yes' or 'no' depending upon the boolean passed in.
 * 
 * return yes or no
 */
function getYesOrNo(bValue) {
  if (bValue) {
    return "yes";
  }
  else {
    return "no";
  }
}


/**
 * Open a new window with the given url, target, and properties.
 *
 * @param sUrl          location of the new window
 * @param sTarget       name of the new window the url should load in
 * @param iWidth        window width
 * @param iHeight       window height
 * @param bToolbar      show toolbar
 * @param bLocation     show location bar (address bar)
 * @param bDirectories  show directors (bookmarks / links)
 * @param bStatus       show status bar
 * @param bMenubar      show menu bar
 * @param bScrollbars   show scroll bars
 * @param bResizable    allow resizing
 * @param bCopyHistory  copy history (back & forward - previsouly visited pages
 */
function openWindowUsingProperties(sUrl, sTarget, iWidth, iHeight, bToolbar, bLocation, bDirectories, bStatus, bMenubar, bScrollbars, bResizable, bCopyHistory) {

  var sProperties = "";

  // ********** width **********
  if (iWidth != null) {
    if (sProperties != "") {
      sProperties += ",";
    }

    sProperties += ("width=" + iWidth);
  }

  // ********** height **********
  if (iHeight != null) {
    if (sProperties != "") {
      sProperties += ",";
    }

    sProperties += ("height=" + iHeight);
  }

  // ********** toolbar **********
  if (bToolbar != null) {
    if (sProperties != "") {
      sProperties += ",";
    }

    sProperties += ("toolbar=" + getYesOrNo(bToolbar));
  }

  // ********** location **********
  if (bLocation != null) {
    if (sProperties != "") {
      sProperties += ",";
    }

    sProperties += ("locationr=" + getYesOrNo(bLocation));
  }

  // ********** directories **********
  if (bDirectories != null) {
    if (sProperties != "") {
      sProperties += ",";
    }

    sProperties += ("directories=" + getYesOrNo(bDirectories));
  }

  // ********** status **********
  if (bStatus != null) {
    if (sProperties != "") {
      sProperties += ",";
    }

    sProperties += ("status=" + getYesOrNo(bStatus));
  }

  // ********** menubar **********
  if (bMenubar != null) {
    if (sProperties != "") {
      sProperties += ",";
    }

    sProperties += ("menubar=" + getYesOrNo(bMenubar));
  }

  // ********** scrollbars **********
  if (bScrollbars != null) {
    if (sProperties != "") {
      sProperties = sProperties + ",";
    }

    sProperties += ("scrollbars=" + getYesOrNo(bScrollbars));
  }

  // ********** resizable **********
  if (bResizable != null) {
    if (sProperties != "") {
      sProperties += ",";
    }

    sProperties += ("resizable=" + getYesOrNo(bResizable));
  }

  // ********** copyhistory **********
  if (bCopyHistory != null) {
    if (sProperties != "") {
      sProperties += ",";
    }

    sProperties += ("copyhistory=" + getYesOrNo(bCopyHistory));
  }

  openWindow(sUrl, sTarget, sProperties);
}

/**
 * Gets users confirmation before carrying out a
 * delete action.
 */
function confirmDelete() {
	return confirmDelete(null, false);
}
function confirmDelete(sMessage) {
	return confirmDelete(sMessage, false);
}
/**
 * Gets users confirmation before carrying out a
 * delete action.  If a message is provided, then that
 * message is used when prompting the user.
 *
 * @param sMessage  message to use when prompting the usser.
 */
function confirmDelete(sMessage, bIsJoin) {
	if (sMessage == null || sMessage == "") {
		if (bIsJoin) {
			sMessage = "This will effect multiple database files.  Are you sure you wish to delete this?";
		}
		else {
			sMessage = "Are you sure you wish to delete this?";
		}
	}
	if (confirm(sMessage)) {
		return true;
	}

	return false;
}

/**
 * Shows the specified exception data in a new window
 */
function showException (data) {
	ewin = window.open ('about:blank', 'exceptionData', 'menubar=no,status=no,width=800,height=800,resizable=yes,scrollbars=yes,menubar=no');
	ewin.document.write('<html><head><title>Exception Data</title></head><body><h3>Exception Stacktrace:</h3><br/>');
	ewin.document.write(data);
	ewin.document.write('</body></html>');
	ewin.document.close();
}

function popUpImage(sImg, iWidth, iHeight) {
	var x,y;
	x=(screen.width - iWidth) / 2;
	y=(screen.height - iHeight) / 2;

	var winProps = "scrollbars=0,toolbar=0,status=0,menubar=0,resizeable=0,location=0,directories=0";
	winProps += ",width=" + iWidth + ",height=" + iHeight;
	
	if (navigator.appName.indexOf("Microsoft")>=0) {
		winProps += "";
	}
	else {
		winProps += ",screenx=" + x + ",screeny=" + y;
	}

	var popUp = window.open(sImg, "Image", winProps);
	popUp.focus();
	
	return false;
}
/**
 * Used to get the next or previous row collection of possible values for a field.
 */
function changePossibleValues(sValue, sNextMagicKey, sPrevMagicKey) {
  if (sValue == '*PJ_NEXT') {
    return performMagic(sNextMagicKey);
  }
  else if (sValue == '*PJ_PREV') {
    return performMagic(sPrevMagicKey);
  }
  return true;
}
function doAction(magicId, magicParams, targetWindow) { 
	if (isPageLocked()) {
		return false;
	}

     getElement(magicParamName).value=magicParams; 
     return performMagic(magicId, targetWindow); 
}
function doAction(magicId, magicParams, targetWindow, windowProperties) { 
	if (isPageLocked()) {
		return false;
	}

	 getElement(magicParamName).value=magicParams; 
     return performMagic(magicId, targetWindow, windowProperties); 
}
function insertTab(event,obj) {
	var tabKeyCode = 9;
	if (event.which) // mozilla
		var keycode = event.which;
	else // ie
		var keycode = event.keyCode;
	if (keycode == tabKeyCode) {
		if (event.type == "keydown") {
			if (obj.setSelectionRange) {
				// mozilla
				var s = obj.selectionStart;
				var e = obj.selectionEnd;
				obj.value = obj.value.substring(0, s) + 
					"\t" + obj.value.substr(e);
				obj.setSelectionRange(s + 1, s + 1);
				obj.focus();
			} else if (obj.createTextRange) {
				// ie
				document.selection.createRange().text="\t"
				obj.onblur = function() { this.focus(); this.onblur = null; };
			} else {
				// unsupported browsers
			}
		}
		if (event.returnValue) // ie ?
			event.returnValue = false;
		if (event.preventDefault) // dom
			event.preventDefault();
		return false; // should work in all browsers
	}
	return true;
}

function clearFields (fields) {
	for (i = 0; i < fields.length; i++) {
		f = getElement(fields[i]);
		if (f.type == 'text') {
			f.value = '';
		}
		if (f.type == 'select-one') {
			f.options[0].selected = true;
		}
	}
	return false;
}
/**
 * @since WOW 6.5.04
 */
function addToOptionList(OptionList, OptionValue, OptionText) {
	// WOW 6.5.04.05 replace PVs from Ajax
   // Add option to the bottom of the list
   o = new Option(OptionText, OptionValue);
   OptionList[OptionList.length] = o;
   
  // if (selected)
    //  o.selected = selected;
}
/**
 * Sets the value of the specified field.  This method is intended to be used only to set
 * the values of fields which appear in results tables or row details - not hidden inputs or
 * parameter values.  It is currently used by the PVSearch code
 *
 * @param inputName The name of the HTML input whose value will be set
 * @param fieldValue The new value for the field input
 */
function setFieldInputValue (inputName, fieldValue) {
	getForm().elements[inputName].value = fieldValue;
}

/**
 * Executes a MR on a form other than the default form
 *
 * @param newFormName The name of the form which will be submitted
 * @param mrid The ID of the magic request to execute
 * @since WOW 6.5.04
 */
function performFormMagic(newFormName, mrid) {
	// WOW 6.5.04.04
	var oldForm = formName;
	formName = newFormName;
	performMagic(mrid);
	formName = oldForm;
}

/**
 * Collapses or expands out a fieldset
 *
 * @param source The TR containing the field set header (which the user just clicked on)
 * @param showsrc The source of the image to be displayed when the field set is being shown
 * @param hidesrc The source of the image to be displayed when the field set is being hidden
 */
function toggleFieldSet (source, showsrc, hidesrc) {
	// get ID of the image, hidden field, header cell, and field set footer
	imgID = source.id.replace(/header/g, "img");
	inputID = source.id.replace(/header/g, "state");
	footerID = source.id.replace(/header/g, "footer");
	cellID = source.id + "Cell";
	
	// this is the image whose source depends on the expanded/collapsed state
	img = getElementById (imgID);
	
	// this is the hidden input which is used to maintain the expanded/collapsed state
	input = getElementById (inputID);
	
	// this is the field set footer
	footer = getElementById (footerID);
	
	// this is the TD within the field set header TR
	headerCell = getElementById (cellID);
	
	if (source.className.indexOf ('collapsed') < 0) {	
		// change CSS of field set header
		source.className = source.className.replace(/expanded/g, "collapsed");
		
		// we don't want hidding the field set to alter the width of the other displayed elements, so we have to
		// ensure that the current calculated width becomes the explictly set width
		if (headerCell.clientWidth) {
			headerCell.style.width = headerCell.clientWidth + 'px';
		}
		
		// set field value so the field set state will be maintained
		input.value = "collapsed";
		
		if (img) {
			// change image in header
			img.src = hidesrc;
		}
		
		// change CSS of field set footer
		if (footer) {
			footer.className = footer.className.replace(/expanded/g, "collapsed");
		}
		
		// change CSS of each TR in the field set
		for (i = 1; i < 1000; i++) {
			// get next TR to hide
			trID = source.id.replace(/header/g, "r"+i);
			tr = getElementById (trID);
			if (tr) {
				tr.className = tr.className.replace(/expanded/g, "collapsed");
			}
			else {
				break;
			}
		}
	}
	else {
		// change CSS of field set header
		source.className = source.className.replace(/collapsed/g, "expanded");
		
		// restore dynamic width calculation
		headerCell.style.width = 'auto';
		
		// set field value so the field set state will be maintained
		input.value = "expanded";
		
		if (img) {
			// change image in header
			img.src = showsrc;
		}
		
		// change CSS of field set footer
		if (footer) {
			footer.className = footer.className.replace(/collapsed/g, "expanded");
		}
		
		// change CSS of each TR in the field set
		for (i = 1; i < 1000; i++) {
			// get next TR to show
			trID = source.id.replace(/header/g, "r"+i);
			tr = getElementById (trID);
			if (tr) {
				tr.className = tr.className.replace(/collapsed/g, "expanded");
			}
			else {
				break;
			}
		}
	}
}

/**
 * Collapses or expands out a results table or a details display
 * %%CO (JE 05/15/2007)
 *
 * @param source The HTML table containing the results title (which the user just clicked on)
 */
function toggleResults (source) {
	// get ID of the hidden field and results table
	inputID = source.id.replace(/title/g, "state");
	tableID = source.id.substring (0, source.id.lastIndexOf ('-'));
	
	// %%CO tweak results id has "table" in it, unlike the details (JE 06/09/2009)
	//tableID = source.id.substring (0, source.id.lastIndexOf ('-'));
	suffix = "";
	if (source.id.indexOf('results') > -1) {
		suffix = "-table";
	}
	tableID = source.id.substring (0, source.id.lastIndexOf ('-')) + suffix;
	
	// this is the hidden input which is used to maintain the expanded/collapsed state
	input = getElementById (inputID);
	
	// this is the field set footer
	results = getElementById (tableID);
	
	if (results.className.indexOf ('collapsed') < 0) {	
		// change CSS of title
		source.className = source.className.replace(/expanded/g, "collapsed");
		
		// set field value so the collapsed state will be maintained
		input.value = "collapsed";
		
		// change CSS of results
		if (results) {
			results.className = results.className.replace(/expanded/g, "collapsed");
		}
	}
	else {
		// change CSS of title
		source.className = source.className.replace(/collapsed/g, "expanded");
		
		// set field value so the collapsed state will be maintained
		input.value = "expanded";
		
		// change CSS of results
		if (results) {
			results.className = results.className.replace(/collapsed/g, "expanded");
		}
	}
}

/**
 * Collapses or expands out a fieldset
 *
 * @param source The DIV containing the field set header (which the user just clicked on)
 * @param showsrc The source of the image to be displayed when the field set is being shown
 * @param hidesrc The source of the image to be displayed when the field set is being hidden
 */
function toggleDIVFieldSet (source, showsrc, hidesrc) {
	// get ID of the image, hidden field, inner div, and field set footer
	imgID = source.id.replace(/header/g, "img");
	inputID = source.id.replace(/header/g, "state");
	footerID = source.id.replace(/header/g, "footer");
	divID = source.id.replace(/header/g, "inner");

	// the inner div containing the field set
	div = getElementById (divID);
	
	// this is the image whose source depends on the expanded/collapsed state
	img = getElementById (imgID);
	
	// this is the hidden input which is used to maintain the expanded/collapsed state
	input = getElementById (inputID);
	
	// this is the field set footer
	footer = getElementById (footerID);
	
	if (source.className.indexOf ('collapsed') < 0) {	
		// change CSS of field set header
		source.className = source.className.replace(/expanded/g, "collapsed");
		
		// set field value so the field set state will be maintained
		input.value = "collapsed";
		
		if (img) {
			// change image in header
			img.src = hidesrc;
		}
		
		// change CSS of field set footer
		if (footer) {
			footer.className = footer.className.replace(/expanded/g, "collapsed");
		}
		
		// change CSS of DIV
		div.className = div.className.replace(/expanded/g, "collapsed");
	}
	else {
		// change CSS of field set header
		source.className = source.className.replace(/collapsed/g, "expanded");
		
		// set field value so the field set state will be maintained
		input.value = "expanded";
		
		if (img) {
			// change image in header
			img.src = showsrc;
		}
		
		// change CSS of field set footer
		if (footer) {
			footer.className = footer.className.replace(/collapsed/g, "expanded");
		}
		
		// change CSS of DIV
		div.className = div.className.replace(/collapsed/g, "expanded");
	}
}

// JS Map implementation %%SAC (JE 05/23/2007)
function Map() {
  this.map  = new Object();
  // Map API
  this.add = function( k,o ){
    this.map[k] = o;
  }
  this.put = function( k,o ){
    this.map[k] = o;
  }
  this.remove = function( k ){
    delete this.map[k];
  }
  this.get = function( k ){
    return k==null ? null : this.map[k];
  }
  this.first = function(){
    return this.get( this.nextKey() );
  }
  this.next = function( k ){
    return this.get( this.nextKey(k) );
  }
  this.nextKey = function( k ){
    for (i in this.map) {
      if ( !k ) return i;
      if (k==i) k=null; /*tricky*/
    }
    return null;
  }
}

function checkAll(sName) {
	var fields = document.getElementsByName(sName);
	
	if (fields && fields.length > 0) {
		// loop through elements and check
		for (var i = 0; i < fields.length; i++) {
			fields[i].checked = true;
		}					 
	}
}
					 
function uncheckAll(sName) {
	var fields = document.getElementsByName(sName);
	
	if (fields && fields.length > 0) {
		// loop through elements and check
		for (var i = 0; i < fields.length; i++) {
			fields[i].checked = false;
		}					 
	}
}
function runOp(iOpId) {
	var hiddenE = getElement(hiddenOpHttpId);
	if (hiddenE) {
		hiddenE.value = iOpId;
		getForm().submit();
	}
	return false;
}

function createCookie(sName, sValue, iDays) {
	var expires = "";
	if (iDays) {
		var date = new Date();
		// days * hours * minutes * seconds * milliseconds
		date.setTime(date.getTime()+(iDays*24*60*60*1000));
		expires = "; expires=" + date.toGMTString();
	}
	
	document.cookie = sName + "=" + sValue + expires + "; path=/";
}
function readCookie(sName) {
	var start = document.cookie.indexOf(sName + "=");
	if (start != -1) {
		start = start + sName.length+1;
		
		var end = document.cookie.indexOf(";", start);
		if (end == -1) {
			end = document.cookie.length;
		}
		
		return unescape(document.cookie.substring(start, end));
    }
    
	return null;
}

function eraseCookie(sName) {
	createCookie(sName, "", -1);
}

function cookiesAllowed() {
	var name = "CookiesAllowedTest";
	
	// first create a cookie
	createCookie(name, "Are cookies allowed?");
	
	// check if cookie exists
	if (readCookie(name)) {
		// clear cookie after test finishes
		eraseCookie(name);
		return true;
	}
	
	return false;
}
/**
 * Global variable that contiains all the functions to be called
 * after the page is completely loaded.
 * @since WOW 6.5.04
 */
var onLoadFunctionArray = new Array();

/**
 * Adds a function to the list of calls that will be made once
 * the entire page has finished loading.
 * @since WOW 6.5.04
 */ 
function addOnLoadFunction(codeString){
	// WOW 6.5.04.03
	if (codeString) {
		if (codeString.charAt(codeString.length-1) != ';'){
			codeString = codeString + ';';
		}
		onLoadFunctionArray[onLoadFunctionArray.length] = codeString;
	}
}

/**
 * Executes all functions that have been added to the onLoad
 * function array.
 * @since WOW 6.5.04
 */
function executeOnLoadFunctions(){
	// WOW 6.5.04.03
	for (var i=0; i<onLoadFunctionArray.length; i++) {

		var functionCall = onLoadFunctionArray[i];
		if (functionCall) {
			eval(functionCall);
		}
	}
}
/** 
 * Method attached to the onLoad event on the body element.
 */
function bodyOnLoad() {
	// WOW 6.5.04.03
	executeOnLoadFunctions();
}

function editOpNewWindow(mrid, e) {

	// kill event after processing it
	if (!e)  e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	
	return performWindowMagic (mrid, 'OpEdit', 'width=800,height=600,resizable=yes,toolbar=no,scrollbars=yes');
}

// %%ACDE variable for holding information about a submit which was requested by the user but
// could not be executed due to a page lock (JE 05/12/2008)
var lockedOutSubmit = null;

/*
 * Fires the submit request which the user initiated earlier while the page was locked
 */
fireLockedOutSubmit = function() {
	// %%ACDE function added (JE 05/12/2008)
	if (lockedOutSubmit) {
		lockedOutSubmit.funct.apply(null, lockedOutSubmit.args);		
		
		// prevent duplicate submits
		lockedOutSubmit = null;
	}
}

/*
 * Saved the submit request which the user initiated while the page was locked
 */
saveLockedOutSubmit = function(functionObject, argumentsArray) {
	// %%ACDE function added (JE 05/12/2008)
	lockedOutSubmit = {
		funct: functionObject,
		args: argumentsArray
	};
}

/**
 * Keeps track of the currently selected row (the row which has the special CSS selection applied, which isn't always the same as the
 * row whose radio button/checkbox is checked)
 */
// %%ROWSTYLE (JE 10/19/2007)
var cssSelectedRow;

/**
 * Changes the CSS style to indicate that the row is selected or not selected.  Only the CSS class is changed,
 * the checkbox/radio button isn't altered
 *
 * @param row the TR element to select
 * @param style the style which indicates selection
 */
trCSSSelect = function(row, style) {
	// %%ROWSTYLE (JE 11/02/2007)
	
	// if selected row is clicked, unselect it
	unselect = row == cssSelectedRow;
	
	if (!unselect) {
		if (!row.originalClassName)
			// store current style of row
			row.originalClassName = row.className;
	
		// set new style on row
		row.className = style;
	}
	
	// revert previously selected row
	if (cssSelectedRow) {
		cssSelectedRow.className = cssSelectedRow.originalClassName;
		if (!unselect && cssSelectedRow.onmouseout) {
			cssSelectedRow.onmouseout();
		}
	}
	
	// save currently selected row
	cssSelectedRow = unselect ? null : row;
}

/**
 * The specifiec row becomes selected.  If it is already selected it remains selected.  Only the CSS is affected, never the
 * radio button/checkbox.
 */
ensureTRCSSSelect = function(row, style) {
	// %%ROWSTYLE (JE 11/02/2007)
	if (row != cssSelectedRow) {
		trCSSSelect(row, style);
	}
}

/**
 * Function called when a row in a table is selected/unselected.  Both the radio button/checkbox as well as the CSS style are affected
 *
 * @param row the TR element to select
 * @param style the style which indicates selection
 */
trSelect = function(row, style) {
	// %%ROWSTYLE (JE 10/19/2007)
	
	// play sound
	//setTimeout("evalSound('rowSelSnd-" + row.key + "')", 0);
	evalSound('rowSelSnd-' + row.key);
	
	// if selected row is clicked, unselect it
	unselect = row == cssSelectedRow;
	
	// find the selection input so we can adjust that to indicate the row's new status
	if (row.inputId) {
		selInput = getElementById(row.inputId);
		if (selInput) {
			selInput.checked = !unselect;
		}
	}
		
	// change CSS
	trCSSSelect(row, style);
}

/**
 * Function for highlight/unhighlighting a row in a table
 *
 * @param row - the TR element to highlight
 * @param style - the highlighting style.  When this is null is means to unhighlight the row
 */
trHLight = function(row, style) {
	// %%ROWSTYLE (JE 10/19/2007)
	if (row == cssSelectedRow) {
		// row is already selected, so do nothing
		return;
	}
	if (style) {
		if (!row.originalClassName)
			// save original style
			row.originalClassName = row.className;
			
		// set highlighted style
		// but keep original style as well in case highlight style is not defined (JE 10/23/2007)
		// putting in both styles causes problems in IE so it is best to just use a single style (JE 11/27/2007)
		row.className = style;// + ' ' + row.originalClassName;
	}
	else {
		// restore original style
		row.className = row.originalClassName;
	}
}

/**
 * onclick event handler for table rows which may be selected
 *
 * @param clickee The row which was clicked
 * @param param The CSS style to use for selected rows
 * @param inputId The ID of the selection input (radio button/checkbox) for the row
 * @param e The triggering event
 */
rowSel = function(clickee, style, inputId, e) {

	// %%ROWSTYLE (JE 10/24/2007)
	// Examine the event and do NOT select the row if the user clicked on an input or a link or an image,
	// this is because clicking in a text input or on a MR shouldn't select the row
  	var targ;
	if (!e) var e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;

	testStr = targ.toString();
	
	// do NOT select row from a click on an image or anchor or select
	// also do not select when an option in a SELECT element is clicked (JE 02/13/2009)
	if (testStr.indexOf ("Option") > -1 || testStr.indexOf ("Image") > -1 || testStr.indexOf ("Anchor") > -1 || testStr.indexOf ("Select") > -1) {
  		return true;
	}
	
	// Test for anchor.  It is better to use the constructor property, but that is not supported by all browsers (JE 11/14/2007)
	if ((targ.constructor && targ.constructor.toString().indexOf ("Anchor") > -1) || testStr.indexOf('http://') == 0) {
		// do not do selection when an anchor is clicked
		return true;	
	}
	
	// do NOT select row from a click on an input, unless it was the special selection input, denoted with "sel=true"
	if (testStr.indexOf ("Input") > -1) {
		if ("true" != targ.getAttribute("sel"))
			return true;
		else {
			// did we just select a row that was already selected?
			if (targ.checked && clickee == cssSelectedRow) {
				// if so do nothing
				return true;
			}
			// did we just unselect a row that was already not selected?
			if (!targ.checked && clickee != cssSelectedRow) {
				// if so do nothing
				return true;
			}
			// get rid of inputId property - we don't need to mess with the input since the user clicked it
			clickee.inputId = null;
		}
	}
	
	else {
		// set id of input on clickee so it will be (un)selected
		clickee.inputId = inputId;
	}  
	
	// move key attribute (defined in TBODY element) into TR element for sound support (JE 11/02/2007)
	clickee.key = clickee.parentNode.getAttribute('key');
	
	// call to proxied click
	//proxiedClick(clickee, 'trSelect', e, style);
	trSelect(clickee, style);
	return true;
}

/**
 * Handles the double click event on a row which should execute that row's default action
 *
 * @param mrid The ID of the magic request to run
 * @param e The JavaScript event (the doubleclick)
 * @param The name of the target window in which the MR should be executed (optional param)
 * @param The properties string for the new window in which the MR should be executed (optional param)
 */
rowDblClick = function(mrid, e, newWindow, properties) {
// %%FDEXP added more parameters to support opening in new window (JE 05/15/2008)
  	var targ;
	if (!e) var e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;
		
	if (targ.toString().indexOf ('Input') > -1) {
		// Do nothing special when an input is double clicked
		return true;
	}
	
	if (newWindow) {
		// %%FDEXP support opening in new window (JE 05/15/2008)
		return performWindowMagic(mrid, newWindow, properties);
	}
	return performMagic(mrid);
}

// %%ACTMENU Holds reference to the context menu (JE 11/30/2007)
var cntxMenu = null;

// %%ACTMENU Is the mouse cursor over the context menu? (JE 11/30/2007)
var overpopupmenu = false;

// %%ACTMENU Counts the number of times the right-click has been handled.  This
// allows WOW to manage which context menu is displayed (JE 11/30/2007)
var cntxMenuCount = 0;

/**
 * Called when the mouse is clicked.  In most cases, a mouse click should
 * close the context menu
 */
function mouseSelect(e) {
	// %%ACTMENU (JE 11/30/2007)
	if (!e) {
		e = window.event;
	}
	
	var obj = (e.target) ? e.target.parentNode : e.srcElement.parentElement;
	
	if( overpopupmenu == false ) {
		closeContextMenu();
		return true ;
	}

	return true;
}

/** Hides the context menu */
function closeContextMenu() {
	// %%ACTMENU (JE 11/30/2007)
	if (cntxMenu) {
		overpopupmenu = false;
		cntxMenu.style.display = "none" ;
		cntxMenu.actions = null;
		cntxMenu = null;
	}
}

/** Called when a row is right clicked, and the context menu should probably be shown */
function itemSelMenu(clickee, e) {
	var adjust = 20;
	
	// %%ACTMENU (JE 11/30/2007)
	if (!e) {
		e = window.event;
		adjust = 10;	// position adjustment is smaller for IE
	}
	
	var obj = (e.target) ? e.target.parentNode : e.srcElement.parentElement;
	
	// maybe the user clicked directly on a TD element, in which case the TR is the parent of the clickee
	menuId = obj.getAttribute('menuId');
	if (menuId == null) {
		// the TR is not the parent of the clickee.  But maybe it is the parent's parent?
		obj = obj.parentNode;
		menuId = obj.getAttribute('menuId');
	}
		
	menu = document.getElementById(menuId);
		
	// calculate scrolling data of window (will be used to determine position to show context menu in)
    var scrollLeft = document.body.scrollLeft;
    if (scrollLeft == 0) {
		if (window.pageXOffset)
			scrollLeft = window.pageXOffset;
		else
			scrollLeft = (document.body.parentElement) ? document.body.parentElement.scrollLeft : 0;
	}
	var scrollTop = document.body.scrollTop;
	if (scrollTop == 0) {
		if (window.pageYOffset)
			scrollTop = window.pageYOffset;
		else
			scrollTop = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0;
	}
	
	// prepare to move actions from TR object into menu DIV
	actionArray = new Array();
	nextIndex = 0;
	
	// actionStr is a String of the MR actions, like "PJMR1.0, PJMR2.0, PJMR3.0," which corresponds to the
	// items in the action menu.  If a particular action in the context menu isn't applicable to this
	// row, then the action String contains "-SKIP=".  For example, "PJMR1.0, -SKIP-, PJMR3.0,".  Note that
	// the action string always ends with a comma
	actionStr = obj.getAttribute('actions');
	nextComma = actionStr ? actionStr.indexOf(',') : -1;
	
	// number of menu items since the last menu separator
	sinceLastSeparator = 0;
	
	// array of separator objects
	separators = new Array();
	
	// how many non-separator items were shown?
	itemsShown = 0;
		
	// loop through action string and break it up into individual magic request for each action
	while (nextComma > 0) {
		action = actionStr.substring(0, nextComma);
		actionArray[nextIndex] = action;
		actionStr = actionStr.substring(nextComma + 1, actionStr.length);
		nextComma = actionStr.indexOf(',');
		trElement = getElementById(menu.id + '_TR' + nextIndex);
		
		if (!trElement) {
			// trElement can be null when the display type is set to none, and therefore the
			// action hasn't been rendered in the menu
			continue;
		}
			
		separator = getElementById(trElement.id + 'S');
		if (separator) {
			// save separator in array of separators
			separators[separators.length] = separator;
			
			// set number of items which appear before this separator into separator
			separator.itemsShownBefore = itemsShown;
			
			// locate separator previous to this one
			previousSeparator = (separators.length > 1) ? separators[separators.length - 2] : null;
			
			// find out how many items where shown before the PREVIOUS separator
			itemsBeforePreviousSeparator = (previousSeparator != null) ? previousSeparator.itemsShownBefore : 0;
			
			//if (sinceLastSeparator == 0) {
			if (itemsShown - itemsBeforePreviousSeparator == 0) {
				// There are no visible menu items which are before this separator AND after the previous separator,
				// so this separator should not be visible
				if (separator.className != 'hidden') {
					// we want to hide the separator
					separator.oldClassName = separator.className;
					separator.className = 'hidden';
				}
			}
			else {				
				// this separator really should be visible
				if (separator.className == 'hidden') {
					oldClass = separator.oldClassName;
					if (!oldClass)
						oldClass = '';
					separator.className = oldClass;
				}
			}
		}
		if ('-SKIP-' == action && trElement.className != 'hidden') {
			// we want to hide the menu row corresponding to this action
			trElement.oldClassName = trElement.className;
			trElement.className = 'hidden';
		}
		else if (action != '-SKIP-') {
			itemsShown++;
			if ('hidden' == trElement.className) {
				// undo any hiding from the previous time the menu was shown
				oldClass = trElement.oldClassName;
				if (!oldClass)
					oldClass = '';
				trElement.className = oldClass;
			}
		}
		
		nextIndex++;
	}
			
	if (itemsShown == 0) {
		// there were no visible items in the menu, so do not display it at all
		return false;
	}
	
	// there is still the possibility that there are extra separators at the bottom of the context menu which should
	// not be there
	for (i = separators.length - 1; i >= 0; i--) {
		sep = separators[i];
		if (sep.itemsShownBefore == itemsShown && sep.className != 'hidden') {
			// there are no items below this separator, so hide it right quick
			//alert("Hide sep with items shown before: " + sep.itemsShownBefore);
			sep.oldClassName = sep.className;
			sep.className = 'hidden';
		}
	}

	// set array of actions on menu DIV so it is available if a menu item is clicked on
	menu.actions = actionArray;
	
	// make the menu displayable so that its height can be calculated, but move it out of site until
	// its final position is determined (JE 12/07/2007)
	menu.style.left = "-10000px";
	menu.style.display = "";
	
	// next examine the position of the mouse click compared to the size of the menu and the scrolling
	// info for the screen.  If the user clicked too close to the bottom of the page, we may have to
	// move the menu up (JE 12/07/2007)
	var top = scrollTop + e.clientY;
	var left = scrollLeft + e.clientX;
	
	if (document.body) {
		var mainHeight = 0;
	    if( typeof( window.innerWidth ) == 'number' )
	    	mainHeight = window.innerHeight;
	    else if( document.documentElement && document.documentElement.clientHeight )
	    	mainHeight = document.documentElement.clientHeight;
	    else if( document.body && document.body.clientHeight )
	        mainHeight = document.body.clientHeight;

	    if ( mainHeight < top + menu.clientHeight - scrollTop ) 
	    	top = mainHeight - menu.clientHeight - adjust + scrollTop;
	    	
		var mainWidth = 0;
	    if( typeof( window.innerWidth ) == 'number' )
	    	mainWidth = window.innerWidth;
	    else if( document.documentElement && document.documentElement.clientWidth )
	    	mainWidth = document.documentElement.clientWidth;
	    else if( document.body && document.body.clientWidth )
	        mainWidth = document.body.clientWidth;

	    if ( mainWidth < left + menu.clientWidth - scrollLeft ) 
	    	left = mainWidth - menu.clientWidth - adjust + scrollLeft;
	}    
        
	// adjust display properties of the menu
	menu.style.left = left + 'px';
	menu.style.top = top + 'px';
	cntxMenu = menu;
	e.handled = true;
	menu.menuCount = cntxMenuCount + 1;
	
	// select row so user can see which exact row was clicked on
	ensureTRCSSSelect(obj, menu.getAttribute('rowCSS'));
	return false ;
}

/**
 * Cancels the right click if it was already handled by bringing up a custom context menu
 */
defaultContextMenu = function (e) {
	cntxMenuCount++;
	if (cntxMenu && cntxMenu.menuCount == cntxMenuCount)
		return false;

	// %%ACTMENU (JE 10/25/2007)
	if (!e) {
		e = window.event;
	}
	
	if (e && e.handled)
		return false;
	
	return true;
}

/**
 * Called when an action menu item is hovered over
 */
acthon = function(item) {
	// %%ACTMENU (JE 10/25/2007)
	item.className = item.className + '-hlight';
}

/**
 * Called when an action menu item ceases being hovered over
 */
acthoff = function(item) {
	// %%ACTMENU (JE 10/25/2007)
	item.className = item.className.replace(/-hlight/g, '');
}

/**
 * Called when a menu item in an action context menu is clicked
 */
performMenuMagic = function(index) {
	// %%ACTMENU (JE 11/02/2007)
	if (cntxMenu && cntxMenu.actions && cntxMenu.actions[index]) {
		toReturn = performMagic(cntxMenu.actions[index]);
		setTimeout('closeContextMenu()', 100);
		return toReturn;
	}
}

/**
 * Called when a menu item in an action context menu is clicked to open in a new window
 */
performWindowMenuMagic = function(index, target, properties) {
	// %%ACTMENU (JE 11/19/2007)
	if (cntxMenu && cntxMenu.actions && cntxMenu.actions[index]) {
		toReturn = false;
		if (!properties || properties == '') {
			toReturn = performMagic(cntxMenu.actions[index], target);
		}
		else {
			toReturn =  performMagic(cntxMenu.actions[index], target, properties);
		}
		setTimeout('closeContextMenu()', 100);
		return toReturn;
	}
}
		

/* %%ACTMENU Event handlers related to the action menu (JE 10/25/2007) */
document.onmousedown 	= mouseSelect;
document.oncontextmenu 	= defaultContextMenu;

/* %%CSOUND add sound support (JE 11/02/2007) */
function evalSound(soundobj) {
  var thissound=document.getElementById(soundobj);
  if (thissound)
  try {
  	thissound.Play();
  }
  catch (ex) {
  	debug('Main', 'unable to play sound from object ' + thissound);
  }
}    


function hideDiv(id) {
	//safe function to hide an element with a specified id
	if (document.getElementById) { // DOM3 = IE5, NS6
		document.getElementById(id).style.display = 'none';
	}
	else {
		if (document.layers) { // Netscape 4
			document.id.display = 'none';
		}
		else { // IE 4
			document.all.id.style.display = 'none';
		}
	}
}

function showDiv(id) {
	//safe function to show an element with a specified id
		  
	if (document.getElementById) { // DOM3 = IE5, NS6
		document.getElementById(id).style.display = 'block';
	}
	else {
		if (document.layers) { // Netscape 4
			document.id.display = 'block';
		}
		else { // IE 4
			document.all.id.style.display = 'block';
		}
  }
} 
// WOW 6.5.05.31 - (KGetting 4/17/2008) - Checks for Caplock.  Should work for all browsers.   
// Add onKeyPress="checkCapsLock( event )" to password fields.  
// This warns user that Capslock is on.
function checkCapsLock( e ) {
	var myKeyCode=-1;
	var myShiftKey=false;
	var ev = e ? e : window.event;
	if (!ev) {
		return;
	}
	
	// Get key pressed
	if (ev.which) {
		myKeyCode = ev.which;
	} else if (ev.keyCode) {
		myKeyCode = ev.keyCode;
	}
	// Get shift key status
	if (ev.shiftKey) {
		myShiftKey = ev.shiftKey;
	} else {
		myShiftKey = !!(ev.modifiers & 4);
	}
	
	// Upper case letters are seen without depressing the Shift key, therefore Caps Lock is on
	if ((( myKeyCode >= 65 && myKeyCode <= 90 ) && !myShiftKey ) ||
	 ( ( myKeyCode >= 97 && myKeyCode <= 122 ) && myShiftKey )) {
		alert('Caps Lock is On.\n\nTo prevent entering your password incorrectly,\nyou should press Caps Lock to turn it off.');
	} 
}
/**
* WK 11-16-2009 ~ copied openWindow method to change behavior not to return false. when using <a href="javascript:openNewWindow(...)"></a>
* the return false causing blank window with word false.
* @param sUrl
* @param sTarget
* @param sProperties
* @return
*/
function openNewWindow(sUrl, sTarget, sProperties) {
	newWin = window.open(sUrl, sTarget, sProperties);
	if (!newWin.opener)
		newWin.opener = self;

	newWin.focus();
}

blankSelectedFields = function(span, e) {
	if (!e) {
		e = window.event;
	}
	
	// test for control-delete
	if (e.keyCode == 46 && (e.metaKey || e.ctrlKey) && span.className.length > 0) {
		// get 1st CSS class of span
		className = span.className;
		spaceIndex = className.indexOf(' ');
		if (spaceIndex > -1)
			className = className.substring(0, spaceIndex);
			
		// extract field name from id of span		
		fieldName = span.id.substring(0, span.id.length - className.length);
		
		// undo special style
		span.className = '';
		
		paramEl = getElement(magicParamName);
		
		// add delimiter if the param already has values 
		if (!paramEl.value == '') {
			paramEl.value += '|';
		}
		
		// set field name into param so the action will know that this blank value means
		// to actually blank out the value of the fields and not to leave them as is
		paramEl.value += fieldName;
		
		// support for checkboxes
		if (span.childNodes.length > 1) {
			span.childNodes[1].checked = false;
		}
		if (span.childNodes.length > 0) {
			if (span.childNodes[0].type == 'text')
				// wipe out value in text field
				span.childNodes[0].value = '';
			if (span.childNodes[0].type && span.childNodes[0].type.length > 5 && span.childNodes[0].type.substring(0, 6) == 'select') {
				// select NONE value from drop down
				for (i = 0; i < span.childNodes[0].options.length; i++) {
					if (span.childNodes[0].options[i].value == "") {
						span.childNodes[0].selectedIndex = i;
						break;
					}
				}
			}
		}
	}
}

/**
 * Tests if a field's value is allowed for a PV operation action (such as Add, Edit, or Details)
 *
 * @param fieldName The name of the field
 * @param badValues An array of values which are not allowed
 */
isPVActionValueOk = function(fieldName, badValues) {
	// %%PVADDEDIT function added (JE 08/12/2010)
	f = getElement(fieldName);
	if (!f)
		f = getElementById(fieldName);
	if (!f)
		return true;
		
	val = f.options[f.selectedIndex].value;
	if (val.match("^\\*PJ_"))
		// this is a special PJ control value
		return false;
	if (badValues) {
		for (i = 0; i < badValues.length; i++) {
			if (badValues[i] == val)
				// the value is in the list of bad values
				return false;
		}
	}
	return true;
}

/* %%PARAM_CONFIG %%JS_MESSAGING functions for updating message via JavaScript (JE 03/26/2009)*/
showMessage = function(msg, style) {
	outerTable = getElementById('msg-outer');
	if (outerTable) {
		outerTable.style.display = 'block';
	}
	innerTable = getElementById('msg-inner');
	if (innerTable) {
		newRow = document.createElement("TR");
		newCell = document.createElement("TD");
		newCell.innerHTML = msg;
		newCell.align = 'left';
		newCell.className = "message-user";
		if (style)
			newCell.className = style;
		newRow.appendChild(newCell);
		innerTable.tBodies[0].appendChild(newRow);
	}
}

showErrorMessage = function(msg) {
	showMessage(msg, 'message-error');
}

showUserMessage = function (msg) {
	showMessage(msg, 'message-user');
}

clearAllMessages = function() {
	innerTable = getElementById('msg-inner');
	if (innerTable == null)
		return;
	for (i = innerTable.tBodies[0].childNodes.length - 1 ;  i >= 1; i--) {
		innerTable.tBodies[0].removeChild(innerTable.tBodies[0].childNodes[i]);
	}
}
