// $Id: fw.js,v 1.73 2008/04/28 17:49:32 laushk rlse $ 

/*


  REVISIONS:
  2006-mar-06, 12:00, awf
  Added fnMenuSubit to submit the form via javascript

  2006-apr-05, 10:30, awf
  Added warn("This method does not work in FireFox"); because
  event variable is only available under IE - should be fixed

  2006-apr-24, dean nagy  
  Bug id 550: Modified function checkUncheckCheckBox() to toggle checkboxes but only
              set a radio button.

  2006-jun-07, awf
  Updated enableScreen() to work in firefox
  Replaced tabs with spaces
  
  2006-jun-12, 12:30, awf
  Updated enableScreen() to handle case in firefox where
  the mask div is appended directly to the body
  
  2006-dec-28, 13:00, awf
  Bug0001306: Implement AJAX call to update result set prior to printing barcode
  Updated ajaxUpdateSet() to always request that the set be updated

*/

// Declare and initialize all global variables
var objWinHandle    = null;
var intInterVal     = 50; 
var strURL          = '';
var http_request    = false;
var intDialog       = null;
var requireSync     = new ArrayList();
var formValidations = new Array();

// constants for logging levels
var DEBUG = 0;
var INFO = 1;
var WARN = 2;
var ERROR = 3;
var FATAL = 4;

var LOG_CLASSES = new Array("debug","info","warn","error","fatal");

/*jsdoc
** Function fnCloseWindow( )

** Description:
** Close modal or modalless popup window

** Parameters:
** None

** Return:
** None

*/

function fnCloseWindow(objWin)
{
   if (! objWin)
      objWin = self;
      
   objWin.close();
}

/*jsdoc
** Function fnGetValue( strFieldName )

** Description:
** Retrieve field value

** Parameters:
** string strFieldName - Field name

** Return:
** string _strValue - Field value or blank if field is not found

*/
function fnGetValue(strFieldName)
{
   var _strValue = "";
   
   var _objField = document.getElementsByName(strFieldName);  // Get window name object by field name
      
   if (_objField.length > 0)  // If field is found
      _strValue = _objField[0].value;
   
   return _strValue;
}


/*jsdoc
** Function fnSetEventDisabled( )

** Description:
** Set user clicks element to be disabled for preventing user clicks on the same element before the page loaded

** Parameters:
** None

** Return:
** None

*/
function fnSetEventDisabled()
{
   if (bolMenuEnabled){
      document.body.style.cursor = "wait";   //Set body mouse cursor to wait
      var _objMenu = document.getElementsByTagName("BUTTON");
      for (var i=0; i<_objMenu.length; i++){
         if (_objMenu[i].id.indexOf(MENU) != -1){
            _objMenu[i].disabled = true;
         }
      }
      bolMenuEnabled = false;
   }
}


/*jsdoc
** Function fnSetEventEnabled( )

** Description:
** Restore onclick function back for anchor in case user stop page unloading

** Parameters:
** boolean bolRest - Indicator to reset the function

** Return:
** None

*/
function fnSetEventEnabled()
{
   document.body.style.cursor = "default";   //Set body mouse cursor to default
   var _objMenu = document.getElementsByTagName("BUTTON");
   for (var i=0; i<_objMenu.length; i++){
      if (_objMenu[i].id.indexOf(MENU) != -1 && ! _objMenu[i].getAttribute(ALLOW_DISABLED)){
         _objMenu[i].disabled = false;
      }
   }
   bolMenuEnabled = true;
}

/*jsdoc
** Function fnExeURL( strURL [, strFieldId ])

** Description:
** Executing input URL or function

** Parameters:
** string strURL - Supplied URL or function (prefix with "javascript:")
** string strFieldId - Field ID to retrieve the value

** Return:
** None

*/

function fnExeURL( strURL, strFieldId )
{
   // If feild ID is provided, execute the URL based on field value   

   if (strFieldId){
      strURL = strURL + document.getElementById(strFieldId).value;
      if (strURL.indexOf("?") == -1){
         strURL += "?";
      }
      else{
          strURL += "&";
      }
       if (strURL.toLowerCase().indexOf("http") == -1){
         strURL += URL_PICK_MDE + "=" + PICK;
      }
      var _strWinName = fnGetTime();
//      fnOpenModal(strURL, 0, _strWinName);
   }
   else{
      if (strURL.toLowerCase().indexOf("javascript:") !=-1){ // If given URL is a javascript function
         eval( strURL );
      }
      else{
//       fnSetEventDisabled();
         top.location.href = strURL;
      }
   }

   fnSetEventCancel();

   return false;
}


/*jsdoc
** Function fnSetEventCancel( )

** Description:
** Cancel event to be bubble up the window

** Parameters:
** None

** Return:
** None

*/
function fnSetEventCancel()
{
   if (window.event){
      window.event.cancelBubble = true;
      window.event.returnValue = false;
   }
}

/*jsdoc
** Function fnMenuClose( [intAction, strURL, strSrchTrm] )

** Description:
** Close current window or redirect URL to proper location using state management

** Parameters:
** integer intAction - If action doesn't provided, and pick mode is not main, close the current window 
** string strURL - If URL is not provided, use state management stack array to retrieve URL
** string strSrchTrm - If Search Term is provided, append to the URL

** Return:
** None

*/
function fnMenuClose(intAction, strURL, strSrchTrm)
{
   var _intPickMode = fnGetValue(URL_PICK_MDE);  // Get pick mode
   var _intInterval = intInterVal;  // Initialize timer interval
   
   if (_intPickMode > MAIN && ! intAction){   // Not main mode and no action provided
      fnCloseWindow();   // Close window
      return;
   }

   if (! strURL){
      var strCloseURL = document.getElementById(ID_PREV_CLOSE_URL);   // Get close URL stack key
      if (strCloseURL && strCloseURL.value >= 0){  // If stack key > 0      
        ajaxPopStack(strCloseURL.value,'');      
      } else {
        info('First Item on Stack, no where to go!');      
      }
   }
   else{
      fnExeURL(strURL);
   }
}


/*jsdoc
** Function fnOpenModal( strURL [, bolModal, strName, bolToolBar, intLeftPos, intTopPos, intWidth, intHeight ] )

** Description:
** Open modal or modalless popup window.

** Parameters:
** string strURL - URL to open modal window
** boolean bolModal - window is modal or modalless 1 = yes, 0 = no (default = 1)
** string strName - modal window name
** boolean bolToolBar - show window toolbar 1 = yes, 0 = no (default = 1)
** integer intLeftPos - window left position (default = 60px)
** integer intTopPos - window top position (default = 10px)
** integer intWidth - window width (default = 700px)
** integer intHeight - window height (default = 480px)

** Return:
** None

*/

function fnOpenModal(strURL, bolModal, strName, bolToolBar, intLeftPos, intTopPos, intWidth, intHeight)
{
   _bolModal = 1;
   _strName = "_blank";
   _bolToolBar = 1;
   _intLeftPos = 30;
   _intTopPos = 10;
   _intWidth = 798;
   _intHeight = 480;
   
   if (bolModal || bolModal == 0)
      _bolModal = bolModal;
   if (strName)
      _strName = strName;
   if (bolToolBar || bolToolBar == 0)
      _bolToolBar = bolToolBar;
   if (intLeftPos || parseInt(intLeftPos) <= 0)
      _intLeftPos = intLeftPos;
   if (intTopPos || parseInt(intTopPos) <= 0)
      _intTopPos = intTopPos;
   if (intWidth)
      _intWidth = intWidth;
   if (intHeight)
      _intHeight = intHeight;
   
   _objWin = window.open(strURL, _strName, "status=yes,toolbar=" + _bolToolBar + ",scrollbars=yes,left=" + _intLeftPos + ",top=" + _intTopPos + ",width=" + _intWidth + ",height=" + _intHeight + ",resizable=yes,location=no,menubar=no;titlebar=no,modal=yes");
   
   if (parseInt(_intLeftPos) <= 0){   // If left position is < -1, it's a record unlocking window
      if (! _objWin.closed){
         _objWin.blur();  // Set window focus off
      }
   }
   else{
   
      _objWin.focus();  // Otherwise, focus the window
      addEvent(_objWin,'unload', function() {fnCloseModal();});          
   }   
   
   if (_bolModal){
      objWinHandle = _objWin;   // If it's a modal window, set window handle to the opened window
     fnCheckFocus();
   }
   return _objWin;
}


/*jsdoc
** Function fnCloseModal( )

** Description:
** Close modal popup window

** Parameters:
** None

** Return:
** None

*/

function fnCloseModal()
{
  objWinHandle = null;
  fnCheckFocus();
}


/*jsdoc
** Function fnCheckFocus([bolIsNotFocus])

** Description:
** Check if modal child window is opened, if so, move the window focus to it, and lock the parent window

** Parameters:
** boolean bolIsNotFocus - If it is set, only lock the parent window but not force to move the focus to child window.  Used for users to view the contents of parent window.

** Return:
** None

*/
function fnCheckFocus(bolIsNotFocus)
{
   // The method only support Internet Explorer
   if (window.navigator.userAgent.indexOf("MSIE") == -1){
      return;
   }
   
   else if (objWinHandle != null && ! objWinHandle.closed){
      // If child window is opened and it is modal window, set body capture to null (not to accept any input)
      document.body.setCapture();
      window.onClick = null;
      window.onMouseDown = null;
      window.onMouseUp = null;
      window.onMouseEnter = null;
      window.onMouseOver = null;
      window.onMouseOut = null;
      
      if (! bolIsNotFocus)
         objWinHandle.focus();  // Move focus to child window
   }
   else{
       if (! bolIsNotFocus)
          document.body.releaseCapture();   // Otherwise, release the capture (unlock parent window)
   }
}

/*jsdoc
** Function fnOpenConfirm([ strMsgVar, intLeftPos, intTopPos, intWidth, intHeight ] )

** Description:
** Open a YES/NO Confirmation dialog box, to prompt user for response.

** Parameters:
** string  strMsgVar  - Message variables, or actual message text
** integer intLeftPos - window left position (default = 200px)
** integer intTopPos  - window top position (default = 230px)
** integer intWidth   - window width (default = 480px)
** integer intHeight  - window height (default = 160px)

** Return:
** integer Message return value: Yes (1), No (0), Windowclose (0)

*/
function fnOpenConfirm(strMsgVar, intLeftPos, intTopPos, intWidth, intHeight)
{
   _intLeftPos = 200;
   _intTopPos  = 230;  
   _intWidth   = 580;  
   _intHeight  = 160;  

   if (!strMsgVar) strMsgVar = 'Do you want to proceed?';
  
   return window.confirm(strMsgVar);

// if (window.showModalDialog)
//    debug('Yes I can showModalDialog');
// return fnOpenModal('confirmation.html', intLeftPos, intTopPos, intWidth, intHeight);
}

/*jsdoc
** Function _setForm( strFormId [, strFormAction ] )

** Description:
** setup form for submit 
** Parameters:
** string strFormId - Form Id of the Form to Submit
** string strFormAction - Optional File name | URL | Function to accept/handle the form action if form action is not defined or not used.

** Return:
** None

*/

function _setForm(strFormId, strFormAction)
{  
  var _objForm = document.getElementById(strFormId);

  if(!_objForm) {
    warn('could not find form id ' + strFormId);
    return;
  }
  
  if (strFormAction){
    var _objAction = getChildElementById(_objForm,URL_FORM_ACTION);
    if(!_objAction) {
      warn('could not find form_action');
      return;
    }
    _objAction.value = strFormAction;
  }

  return _objForm;

}


/*jsdoc
** Function _setFormFuseAction( strFormId, strFormAction )

** Description:
** alter the form fuseaction to allow submitting to an alternate Circuit
** Parameters:
** string strFormId - Form Id of the Form to Submit
** string strFormAction - File name | URL | Function to accept/handle 
**                        the form action if form action is not defined or not 
**                        used.
** Return:
** None

*/
function _setFormFuseAction(strFormId, strFuseAction)
{  
  var _objForm = document.getElementById(strFormId);

  if(!_objForm) {
    warn('could not find form id ' + strFormId);
    return;
  }
  
  if (strFuseAction) {
 
    var _objAction = getChildElementById(_objForm, URL_FUSEACTION);
    if(!_objAction) {
      warn('could not find fuseaction');
      return;
    }

    _objAction.value = strFuseAction;
  }

  return _objForm;

}

// IE will not fire tonsubmit event when form is submitted from javascript
// therefore we have to do it manually
function fwSubmit(_objForm)
{
  // must fire onsubmit event manually
  if (!_objForm.onsubmit()) return false;

  // Submit form
  _objForm.submit();
}

// IE will not fire onsubmit event when form is reset from javascript
// therefore we have to do it manually
function fwReset(_objForm)
{
  // must fire onsubmit event manually
  if (!_objForm.onreset()) return false;

  // Submit form
  _objForm.reset();
}

// Submit the form to a particular action
function fnMenuSubmit(_formId, _action, _fuseAction)
{
  _objForm = _setForm(_formId, _action); 
 
  if (_fuseAction) {
    _setFormFuseAction(_formId, _fuseAction);
  }

  // submit form 
  fwSubmit(_objForm);
}

// Reset the form to a particular action
function fnMenuReset(_formId, _action)
{
  _objForm = _setForm(_formId, _action); 
 
  // reset form 
  fwReset(_objForm);
}

// Submit the form to a particular action without firing onSubmit event
// which performs validation on the form
function fnSubmitForm(_formId, _action, _fuseAction)
{
  _objForm = _setForm(_formId, _action); 

  if (_fuseAction) {
    _setFormFuseAction(_formId, _fuseAction);
  }
 
  // submit form with out firing onSubmit event
  _objForm.submit();
}

/*jsdoc
** Function fnMenuSave( strFormId )

** Description:
** Save Form 
** Parameters:
** string strFormId - Form Id of the Form to Submit

** Return:
** None

*/
function fnMenuSave(strFormId)
{  

  // set form for submit
  _objForm = _setForm(strFormId, ACTION_SAVE); 
 
  // submit form 
  fwSubmit(_objForm);
  
}

/*jsdoc
** Function fnPreviousStep( strFormId )

** Description:
** Submit form and goto previous step of form, do not validate 
** Parameters:
** string strFormId - Form Id of the Form to Submit

** Return:
** None

*/

function fnPrevStep (strFormId)
{ 
  // set form for submit
  _objForm = _setForm(strFormId, ACTION_PREV_STEP); 
    
  // PROGRAMMERS NOTE: do not validate on previous step submit

  // Submit form
  _objForm.submit();
}


/*jsdoc
** Function fnNextStep( strFormId )

** Description:
** Submit form and goto next step of form, validate data 
** Parameters:
** string strFormId - Form Id of the Form to Submit

** Return:
** None

*/

function fnNextStep (strFormId)
{ 
  // set form for submit
  _objForm = _setForm(strFormId, ACTION_NEXT_STEP); 
 
  // submit form
  fwSubmit(_objForm);
}


/*jsdoc
** Function fnNextPage( strFormId )

** Description:
** Submit form function and set action to next page
** Parameters:
** string strFormId - Form Id of the Form to Submit

** Return:
** None

*/

function fnNextPage(strFormId)
{  

  // set form for submit
  _objForm = _setForm(strFormId, ACTION_NEXT); 

  // disable screen and show process indicator 
  //disableScreen();

  // submit form
  fwSubmit(_objForm);
   
}

/*jsdoc
** Function fnPreviousPage( strFormId )

** Description:
** Submit form function 
** Parameters:
** string strFormId - Form Id of the Form to Submit

** Return:
** None

*/

function fnPreviousPage(strFormId)
{  

  // set form for submit
  _objForm = _setForm(strFormId, ACTION_PREV); 

  // disable screen and show process indicator
  // disableScreen();

  // submit form
  fwSubmit(_objForm);
   
}


/*jsdoc
** Function fnGotoPage( strFormId, pageNo )

** Description:
** Submit form function 
** Parameters:
** string strFormId - Form Id of the Form to Submit
** string pageNo - page number to goto

** Return:
** None

*/

function fnGotoPage(strFormId, pageNo)
{  
  // set form for submit
  _objForm = _setForm(strFormId, ACTION_GOTO_PAGE); 
  
  // set page no. 
  var _objPageNo = document.getElementById(URL_GOTO_PAGE);
  if(!_objPageNo) {
    warn('could not find Goto Page No');
    return;
  }
  _objPageNo.value = pageNo;

  // disable screen and show process indicator 
  // disableScreen();

  // submit form
  fwSubmit(_objForm); 
   
}

/*jsdoc
** Function sortColumn( _form, _column, _order )
** Description:
** Submit form function 
** Parameters:
**   string 
**   string 
**   number
** Return:
**   None
*/

function sortColumn( _form, _column, _field )
{  
   var _order='asc';
   var _newOrder = new String(_column);

   waitCursor();

   // set form for submit
   _objForm = _setForm(_form, ACTION_SORT); 
   
   _asc = hasClass(_field,'asc');
   
   removeSorts(_objForm);
   addClass(_field,'sorting');     
   
   if (_asc) {
     _order='desc';
   }

  _objOrderBy = getChildElementById(_objForm,URL_ORDER_BY);
  if(!_objOrderBy) {
    warn('could not find Order By');
    defaultCursor();
    return;
  }

  // Replace comma with order comma
  _newOrder = _newOrder.replace(',',' ' + _order + ',');
 
  _objOrderBy.value = _newOrder + ' ' + _order;

  // disable screen and show process indicator  
  // disableScreen();

  // submit form
  fwSubmit(_objForm);
  
  defaultCursor();
 
}

/*jsdoc
** Function fnSelectAll( _form, _flag, _all, _rows)
** Description:
** Submit form function 
** Parameters:
**   string 
**   string 
**   number
** Return:
**   None
*/

function fnSelectAll( _form, _flag, _all, _rows)
{  

  waitCursor();

  // disableScreen();
  
  var _objForm = document.getElementById(_form);

  if(!_objForm) {
    warn('could not find form id ' + _form);
    return;
  }
  
  _objSetId = getChildElementById(_objForm,URL_SET_ID);
  if(!_objSetId) {
    warn('could not find Set Id');
    defaultCursor();
    return;
  }
  
  // Call Ajax to insert set records into database
  ajaxCheckAll(_objSetId.value, _flag);     


  // Check/Uncheck all checks on current page
  var _objAll = document.getElementById(_all);
  _objAll.checked = _flag;
  CheckUncheckAll(_form, _rows, _objAll, ''); 


  // Check and see if Page Menu requires Sync
  var m_count = requireSync.Count();
  for( var i = 0; i < m_count; i++ ) {
    syncChecks(_objAll,requireSync.GetAt(i));
  }

  defaultCursor();
  
  //enableScreen();
 
}

/*jsdoc
** Function fnUpdateSet( _form)
** Description:
** Submit form function 
** Parameters:
**   string 
**   string 
**   number
** Return:
**   None
*/

function fnUpdateSet( _form )
{  
  var _checked = '';
  var _keys = '';

  waitCursor();

  var _objForm = document.getElementById(_form);

  if(!_objForm) {
    warn('could not find form id ' + _form);
    return;
  }
  
  _objSetId = getChildElementById(_objForm,URL_SET_ID);
  if(!_objSetId) {
    warn('could not find Set Id');
    defaultCursor();
    return;
  }

  _objPageId = getChildElementById(_objForm,URL_PAGE_NO);
  if(!_objPageId) {
    warn('could not find Page No');
    defaultCursor();
    return;
  }

  _objUpdId = getChildElementById(_objForm,URL_UPDATE_CHECKS);
  if(!_objUpdId) {
    warn('could not find UPDATE_CHECKS');
    defaultCursor();
    return;
  }

  var _objRowId = document.getElementsByName(URL_ROW_CHECK+'[]');

  if(_objRowId.length == 0) {
    warn('could not find checkbox name '+ URL_ROW_CHECK);
    return;
  }

  var countCheckBoxes = _objRowId.length;
  for(var i = 0; i < countCheckBoxes; i++) {
    _keys += _objRowId[i].value+',';
    if (_objRowId[i].checked)
       _checked += _objRowId[i].value+',';
  }

  // Call Ajax to insert set records into database
  ajaxUpdateSet(_objSetId.value, _objPageId.value, '1',_checked,_keys );

  defaultCursor();
  
}

/*jsdoc
** Function fnUpdateChecks( _form)
** Description:
** Submit form function 
** Parameters:
**   string 
**   string 
**   number
** Return:
**   None
*/

function fnUpdateChecks( _form )
{  
  var _checked = '';
  var _old = '';

  waitCursor();

  var _objForm = document.getElementById(_form);

  if(!_objForm) {
    warn('could not find form id ' + _form);
    return;
  }
  
  _objSetId = getChildElementById(_objForm,URL_SET_ID);
  if(!_objSetId) {
    warn('could not find Set Id');
    defaultCursor();
    return;
  }

  _objUpdId = getChildElementById(_objForm,URL_OLD_CHECKS);
  if(!_objUpdId) {
    warn('could not find OLD_CHECKS');
    defaultCursor();
    return;
  }

  var _objRowId = document.getElementsByName(URL_ROW_CHECK+'[]');

  if(_objRowId.length == 0) {
    warn('could not find checkbox name '+ URL_ROW_CHECK);
    return;
  }

  var countCheckBoxes = _objRowId.length;
  for(var i = 0; i < countCheckBoxes; i++) {
    _old += _objRowId[i].value+',';
    if (_objRowId[i].checked)
       _checked += _objRowId[i].value+',';
  }

  // Call Ajax to insert set records into database
  ajaxUpdateChecks(_objSetId.value, _old, _checked );

  defaultCursor();
  
}

/*********************************************
** removeSorts
*********************************************/
function removeSorts(_objForm)
{

  var ieLIs = getElementsByClass(_objForm,'sort','a');  
  for (var i=0; i<ieLIs.length; i++) {
    removeClass(ieLIs[i],'asc');
    removeClass(ieLIs[i],'desc');
  }
}  


/*jsdoc
** Function fnEditSelections( strFormId, strFuseAction  )

** Description:
** Submit result form for editing selections
** Parameters:
** string strFormId - Form Id of the Form to Submit
** string strFormAction - File name | URL | Function to accept/handle 
**                        the form action if form action is not defined or not 
**                        used.

** Return:
** None

*/
function fnEditSelections(strFormId, strFuseAction, intFuseAction)
{

  // set form for submit
  if (intFuseAction) {
    _objForm = _setForm(strFormId, intFuseAction);
  } else {
    _objForm = _setForm(strFormId, ACTION_EDIT_SELECTION);
  }

  if (strFuseAction) {
    _setFormFuseAction(strFormId, strFuseAction);
  }

  // submit form
  fwSubmit(_objForm);

}

/*jsdoc
** Function fnDisplaySelections( strFormId, strFuseAction )

** Description:
** Submit results form for displaying selections
** Parameters:
** string strFormId - Form Id of the Form to Submit
** string strFormAction - File name | URL | Function to accept/handle 
**                        the form action if form action is not defined or not 
**                        used.

** Return:
** None

*/
function fnDisplaySelections(strFormId, strFuseAction, intFuseAction)
{ 
  // set form for submit
  if (intFuseAction) {
    _objForm = _setForm(strFormId, intFuseAction);
  } else {
    _objForm = _setForm(strFormId, ACTION_DISP_SELECTION);
  }
 
  if (strFuseAction) {
    _setFormFuseAction(strFormId, strFuseAction);
  }

  // submit form
  fwSubmit(_objForm); 
}



/*********************************************
** function: trim
*********************************************/

function trim(s) {
  while (s.substring(0,1) == ' ') {
    s = s.substring(1,s.length);
  }
  while (s.substring(s.length-1,s.length) == ' ') {
    s = s.substring(0,s.length-1);
  }
  return s;
}


/*********************************************
** function: fnLogError
*********************************************/

function fnLogError(_msg,_level)
{
  var logDiv = document.getElementById('notification');
  if (!logDiv) { return false; }

  logDiv.className='showlog';

  var logClass = LOG_CLASSES[_level];

  // append the statement
  var p = document.createElement('p');

  // this is a hack work around a bug in ie
  if (p.getAttributeNode("class")) {
    for (var i = 0; i < p.attributes.length; i++) {
      if (p.attributes[i].name.toUpperCase() == 'CLASS') {
        p.attributes[i].value = logClass;
      }
    }
  } else {
    p.setAttribute("class", logClass);
  } 
  
  // Replace html code with single quote (was changed to store as string in array)
  var _strVar = new String(_msg); // Force parameter to string character
  _strVar = _strVar.replace('&#39;','\'');

  var text = document.createTextNode(_strVar);
  p.appendChild(text);
  logDiv.appendChild(p);
  
  return true;
}

/*********************************************
** function: fnLogClear
*********************************************/

function fnLogClear()
{
  var logDiv = document.getElementById('notification');
  if (!logDiv) { return false; }
    logDiv.className='hidelog';
  
  var ps = logDiv.getElementsByTagName('p');
  var length = ps.length;
  for (var i = 0; i < length; i++) { logDiv.removeChild(ps[length - i - 1]); }
  return true;
  
}

/*********************************************
** function: fnIsBlank
*********************************************/

function fnIsBlank(strStr)
{
  for(var i = 0; i < strStr.length; i++)
  {
     var c = strStr.charAt(i);
     // If charact has space, new line, or tab
     if ((c != ' ') && (c != '\n') && (c != '\t'))
        return false;
  }
  return true;
}

/*********************************************
** function: fnAllNum
*********************************************/

function fnAllNum(strValue)
{
   var _strVar = new String(strValue); // Force parameter to string character

   var _bolAllNum = true;
   var _intStrLen = _strVar.length;  // Get value length
   var _charVar;
   var _intDecCount = 0;  // Decimal count

   for (var i = 0 ; i < _intStrLen ; i++)
   {
      _charVar = _strVar.charAt(i);
      // Check if value only contains number
      if (isFinite(_charVar)){
         _bolAllNum = true;
      }
      // Check if value only has one decimal
      else if (_charVar == '.' && _intDecCount < 1){
         _intDecCount++;
         _bolAllNum = true;
      }
      // Otherwise it is false
      else{
         _bolAllNum = false;
         break;
      }
   } 
   return _bolAllNum;
}

/*********************************************
** function: fnAllInt
*********************************************/

function fnAllInt(strValue)
{
  // Check if all characters are numbers.
  s = strValue.trim();
  var len = s.length;
  var c;
  for (var i = 0; i < len; i++)
  {   
    // Check that current character is number.
    c = s.charAt(i);
    if ( c < "0" || c > "9" ) return false;
  }

  return true;
}


/*********************************************
** function: fnCheckForSpace
*********************************************/

function fnCheckForSpace(strValue)
{

   var _strVar = new String(strValue); // Force parameter to string character

   var _intStrLen = _strVar.length;
   var _bolSpaceFound = false;

   for (var i = 0; i < _intStrLen; i++)
   {
      if (_strVar.charAt(i) == ' ')
      {
         _bolSpaceFound = true;
         break;
      }
   }
   return _bolSpaceFound;
}

/*********************************************
** function: fnCheckForSpecialChars
*********************************************/

function fnCheckForSpecialChars(strValue)
{

   var _strVar = new String(strValue); // Force parameter to string character
   var _strPattern = "^[0-9a-zA-Z_']*$";
   var _regExp = new RegExp(_strPattern, "g");
   var _bolSpclFound = false;

   if (_strVar.search(_strPattern) == -1){
         _bolSpclFound = true;
   }
   return _bolSpclFound;
}

/*********************************************
** function: fnCheckForChar
*********************************************/

function fnCheckForChar(strValue, strChar, bolCaseSens)
{
   var _strValue;
   var _strChar;
   var _intStrLen;
   var _bolCharFound = false;

   // Force arguments to String datatype, adjust to lowercase
   // when case-insenstive comparison requested, and ensure
   // that string to be located is only 1 char long.
   if (bolCaseSens == false)
   {
      _strValue = new String(strValue).toLowerCase();
      _strChar  = new String(strChar).substr(0,1).toLowerCase();
   }
   else
   {
      _strValue = new String(strValue);
      _strChar  = new String(strChar).substr(0,1);
   }

   _intStrLen = _strValue.length;

   for (var i = 0; i < _intStrLen; i++)
   {
      if (_strValue.charAt(i) == _strChar)
      {
         _bolCharFound = true;
         break;
      }
   }

   return _bolCharFound;
}

/*jsdoc
** Function fnCheckDate1( strDate )

** Description:
** Verify date format is not greater than year 3000

** Parameters:
** string strDate - Given date to be verified

** Return:
** True if the given date is less than year 3000

*/
function fnCheckDate1(strDate) {

   if (! fnAllNum(strDate)) {
      return false;
   }
   
   var intUpperLimitYear = 3000;   // Upper year limit set to 3000
   if (parseInt(strDate) >= intUpperLimitYear)
      return false;
   else
      return true;
}

/*jsdoc
** Function fnCheckDate2( strDate )

** Description:
** Verify date format is YYYY-MM-DD

** Parameters:
** string strDate - Given date to be verified

** Return:
** True if the given date format is valid

*/
function fnCheckDate2(strDate) {

   if (strDate.length != 10) {
      return false;
   }
   var strCheck = "1234567890-";  // The string should only contain these characters
   if (strDate.charAt(4) != '-' || strDate.charAt(7) != '-') {  // dashes have to be in position 3 and 8
      return false;
   }
   for( var i = 0; i < strDate.length; i++ ) {
      if (strCheck.indexOf(strDate.charAt(i)) == -1) {  // Verify if date string only contain valid characters
      return false;
      }
   }

   if (fnValid(strDate)) {  // Validate the numbers are within date format
		return true;
   }
   else {
      return false;
   }
}

function fnCheckDate3(strRange)
{
   // make sure the proper (YYYY-YYYY) format is used
   rxpMatch= new RegExp("^[0-9]{4}\\-[0-9]{4}$");
   if (strRange.search(rxpMatch) != -1) {
      //pull out the indevidual years
      startMatch = new RegExp("^[0-9]{4}");  
      endMatch = new RegExp("[0-9]{4}$");  
      startYear = new Number(strRange.match(startMatch)[0]);
      endYear = new Number(strRange.match(endMatch)[0]);
      // and make sure the end year is only one greater than the start year
      if((endYear-startYear) == 1) {
         // passed validation
         return true;
      }
   }
   //did not conform to one of the checks
   //fail validation
   return false;
}


function fnCheckDateTime(strDateTime) {
	var dateTimeParts = strDateTime.split(' ');

	// Validate the Date
	try {
		var dateParts = dateTimeParts[0].split('-');
		var DateValue = new Date();

		year = Number(dateParts[0]);
		month = Number(dateParts[1]);
		day = Number(dateParts[2]);

		if(isNaN(year) || year.toString().length != 4) {
			throw 'Invalid Year';
		}

		if(isNaN(month) || month > 12 || month < 1) {
			throw 'Invalid Month';
		} 			
		
		if(isNaN(day) || day > 31 || day < 1) {
			throw 'Invalid Day';
		}

		DateValue.setFullYear(year, month-1, day);
		if(year != DateValue.getFullYear()) {
			throw 'Invalid Year 2 ' + DateValue.getFullYear();
		}

		if(month != DateValue.getMonth()+1) {
			throw 'Invalid Month 2';
		}

		if(day != DateValue.getDate()) {
			throw 'Invalid Day 2';
		}
	} catch(error) {
		return false;
	}

	// Validate the Time
	try {
		var timeParts = dateTimeParts[1].split(':');

		if(timeParts.length != 3) {
			throw 'Invalid Time';
		}

		timeParts[0] = Number(timeParts[0]);
		timeParts[1] = Number(timeParts[1]);
		timeParts[2] = Number(timeParts[2]);

		if(isNaN(timeParts[0]) ||  timeParts[0] > 23 || timeParts[0] < 0) {
			throw 'Invalid Hour';
		}
	
		if(isNaN(timeParts[1]) ||  timeParts[1] > 59 || timeParts[1] < 0) {
			throw 'Invalid Minute';
		}
	
		if(isNaN(timeParts[2]) ||  timeParts[2] > 59 || timeParts[2] < 0) {
			throw 'Invalid Second';
		}
	}
	catch(error) {
		return false;
	}

	return true;
}


/*
* Validates a postal code
*/
function fnCheckPostalCode(strPostalCode) {
	var postalPattern = /^[A-Z][0-9][A-Z](| )[0-9][A-Z][0-9]$/i;
	var postalRegExp = new RegExp(postalPattern);

	if(strPostalCode.length > 0) {
		if(postalRegExp.test(strPostalCode) == false ) {
			return false;
		}
	}

	return true;
}



/*jsdoc
** Function fnValid( strDate )

** Description:
** Validate given date string is within date format range

** Parameters:
** string strDate - Given date to be validated

** Return:
** True if string is valid
*/
function fnValid(strDate) {
   var _strDate;
   var _strDay;
   var _strMonth;
   var _strYear;
   var _intday;
   var _intMonth;
   var _intYear;
   var _bolFound = false;
   var _strSep = "-";
   var _pos1 = strDate.indexOf(_strSep);
   var _pos2 = strDate.indexOf(_strSep, _pos1+1);
   if (_pos1 == -1 || _pos2 == -1) {
      return false;
   }
   
   _strYear = strDate.substring(0, _pos1);
   _strMonth = strDate.substring(_pos1+1, _pos2);
    _strDay = strDate.substring(_pos2+1);

   if (_strYear.length <4) {
      return false;
   }
   _intday = parseInt(_strDay, 10);
  
   if (isNaN(_intday)) {
      err = 2;
      return false;
   }
   _intMonth = parseInt(_strMonth, 10);
   if (isNaN(_intMonth)) {
      err = 3;
      return false;
      }
   _intYear = parseInt(_strYear, 10);
   if (isNaN(_intYear)) {
      err = 4;
      return false;
   }
   if (_intMonth > 12 || _intMonth < 1) {
      err = 5;
      return false;
   }
   if ((_intMonth == 1 || _intMonth == 3 || _intMonth == 5 || _intMonth == 7 || _intMonth == 8 || _intMonth == 10 || _intMonth == 12) && (_intday > 31 || _intday < 1)) {
      err = 6;
      return false;
   }
   if ((_intMonth == 4 || _intMonth == 6 || _intMonth == 9 || _intMonth == 11) && (_intday > 30 || _intday < 1)) {
      err = 7;
      return false;
   }
   if (_intMonth == 2) {
      if (_intday < 1) {
         err = 8;
         return false;
      }
      if (fnLeapYear(_intYear) == true) {
         if (_intday > 29) {
            err = 9;
            return false;
            }
      }
      else {
         if (_intday > 28) {
            err = 10;
            return false;
               }
         }
   }
   return true;
}

/*jsdoc
** Function fnLeapYear( intYear )

** Description:
** Calculate give year is leap year or not

** Parameters:
** integer intYear - Give year to be calculated

** Return:
** True if give year is leap year
*/
function fnLeapYear(intYear) {
   if (intYear % 100 == 0) {
      if (intYear % 400 == 0) { 
         return true;
      }
   }
   else {
      if ((intYear % 4) == 0) {
         return true;
      }
   }
   return false;
}


/*********************************************
** isFormElement
*********************************************/
function isFormElement(_objForm,_elementId) {
  
  var _return=false;

  for (var i=0; i < _objForm.length; i++) {
    if (_objForm.elements[i].id == _elementId) {
       _return=true;
       break;
    }    
  }

  return _return;
}

/*********************************************
** getChildElementById
*********************************************/
function getChildElementById(_objForm,_elementId) 
{
   return _objForm.elements.namedItem( _elementId );
}

/*********************************************
** fnVerify
*********************************************/
function fnVerify(_formValidation,_formId)
{

   fnLogClear();

   var _objForm;
   var _strMsg;
   var _strEmptyFields = "";
   var _strErrors = "";
   var _intMsgNbr = 0;
   var _objField;
   var _validForm = true;
   var _singleForm =new Array()
   var firstField = false;

   // If use Specified FormId, get Object handle
   if (_formId) {
     _objForm = document.getElementById(_formId);
   }

   for(var i = 0; i < _formValidation.length; i++)
   {
     _strId = _formValidation[i][0];
     _intVal = _formValidation[i][1];
     _strDesc = _formValidation[i][2];

     _objField = document.getElementById(_strId);          

     // This may happen if the program, asks to validate display only fields
     if(!_objField) {
       warn('Could not validate: ' + _strId);
       continue;
     }

     // Remove validate_error class before testing
     removeClass(_objField, "validate_error");

     _strType = _objField.type;

     // If a FormId is passed, Skip validations on fields not found in current Form
     if (_objForm) {         
        if (!isFormElement(_objForm,_strId)) continue;
     }

     //info(_strId + ' type ' + _strType);

     // Handle Radio button / Check box Logic Here
     if (_strType == 'radio' || _strType == 'checkbox') {

       if ((_intVal & FIELD_MANDATORY) == FIELD_MANDATORY)  {
         var _checked = false;
         _objFields = document.getElementsByName(_objField.name);
         for(var j = 0; j < _objFields.length; j++) 
         {
            if (_objFields[j].checked)
              _checked = true;
         }         
         
         if (!_checked) {
           for(var j = 0; j < _objFields.length; j++) 
           {
            addClass(_objFields[j],"validate_error");             
           }
           _validForm = false;
           fnLogError(err_mandatory_field + ': ' +_strDesc,WARN);
         }
       }         

     } else if (_strType == 'select-one') {

       if ((_intVal & FIELD_MANDATORY) == FIELD_MANDATORY)  {
         if (_objField.options[_objField.selectedIndex].value == '') {
             addClass(_objField,"validate_error");             
             _validForm = false;
             fnLogError(err_mandatory_field + ': ' +_strDesc,WARN);
          }
       }

     } else if (_strType == 'select-multiple') {

      if ((_intVal & FIELD_MANDATORY) == FIELD_MANDATORY)  {

        var _selected = false;
        for (var j = 0; j < _objField.options.length; j++) {
          if (_objField.options[j].selected) {
            _selected = true;
          }
        }
        if (!_selected) {
          addClass(_objField,"validate_error");             
          _validForm = false;
          fnLogError(err_mandatory_field + ': ' +_strDesc,WARN);
        }
      }

     } else {

       if ((_intVal & FIELD_MANDATORY) == FIELD_MANDATORY)  {
          if (fnIsBlank(_objField.value)) {        
             addClass(_objField,"validate_error");             
             _validForm = false;
             fnLogError(err_mandatory_field + ': ' +_strDesc,WARN);
          }
       }

       if ((_intVal & FIELD_NUMERIC) == FIELD_NUMERIC)  {
          if (!fnAllNum(_objField.value)) {
             addClass(_objField,"validate_error");             
             _validForm = false;
             fnLogError(err_numeric_field + ': ' + _strDesc,WARN);
          }
       }

       if ((_intVal & FIELD_INTEGER) == FIELD_INTEGER)  {
          if (!fnAllInt(_objField.value)) {
             addClass(_objField,"validate_error");             
             _validForm = false;
             fnLogError(err_integer_field + ': ' + _strDesc,WARN);
          }
       }

       if ((_intVal & FIELD_NO_SPACES) == FIELD_NO_SPACES)  {
          if (fnCheckForSpace(_objField.value)) {
            addClass(_objField,"validate_error");             
             _validForm = false;
            fnLogError(err_no_spaces_field + ': ' + _strDesc,WARN);
          }
       }

       if ((_intVal & FIELD_NO_SPECIAL_CHARS) == FIELD_NO_SPECIAL_CHARS)  {
          if (fnCheckForSpecialChars(_objField.value)) {
            addClass(_objField,"validate_error");             
             _validForm = false;
            fnLogError(err_no_special_chars + ': ' + _strDesc,WARN);
          }
       }

       if ((_intVal & FIELD_NO_SINGLE_QUOTES) == FIELD_NO_SINGLE_QUOTES)  {
          if (fnCheckForChar(_objField.value,"'", false)) {
            addClass(_objField,"validate_error");             
            _validForm = false;
            fnLogError(err_no_single_quotes_field + ': ' + _strDesc,WARN);
          }
       }

       if ((_intVal & FIELD_NO_DOUBLE_QUOTES) == FIELD_NO_DOUBLE_QUOTES)  {
          if (fnCheckForChar(_objField.value,"\"", false)) {
            addClass(_objField,"validate_error");             
            _validForm = false;
            fnLogError(err_no_double_quotes_field + ': ' + _strDesc,WARN);
          }
       }

       if ((_intVal & FIELD_DATE_1) == FIELD_DATE_1)  {
          if (!fnIsBlank(_objField.value) && !fnCheckDate1(_objField.value)) {
            addClass(_objField,"validate_error");             
            _validForm = false;
            fnLogError(err_date_field + ': ' + _strDesc,WARN);
          }
       }

       if ((_intVal & FIELD_DATE_2) == FIELD_DATE_2)  {
          if (!fnIsBlank(_objField.value) && !fnCheckDate2(_objField.value)) {
            addClass(_objField,"validate_error");             
            _validForm = false;
            fnLogError(err_date_field + ': ' + _strDesc,WARN);
          }
       }

       if ((_intVal & FIELD_DATE_3) == FIELD_DATE_3)  {
          if (!fnIsBlank(_objField.value) && !fnCheckDate3(_objField.value)) {
            addClass(_objField,"validate_error");             
            _validForm = false;
            fnLogError(err_date_field + ': ' + _strDesc,WARN);
          }
       }

       if ((_intVal & FIELD_DATE_TIME) == FIELD_DATE_TIME)  {
          if (!fnIsBlank(_objField.value) && !fnCheckDateTime(_objField.value)) {
            addClass(_objField,"validate_error");             
            _validForm = false;
            fnLogError(err_date_field + ': ' + _strDesc,WARN);
          }
       }

       if ((_intVal & FIELD_POSTAL_CODE) == FIELD_POSTAL_CODE)  {
				if (!fnIsBlank(_objField.value) && !fnCheckPostalCode(_objField.value)) {
            addClass(_objField,"validate_error");             
            _validForm = false;
            fnLogError(err_postal_code + ': ' + _strDesc,WARN);
          }
				}

     }

     if (!_validForm && !firstField) firstField = _objField;
   
   }

   if (firstField) setFocus(firstField.name);

   // disable screen and show process indicator 
   // if (_validForm) disableScreen();
   // else            enableScreen();

   if (!_validForm) enableScreen();

   return _validForm;

   // Open message if error if found
   //var _intRC = fnOpenMsg(72, _strMsg);
}

/*********************************************
** addClass
*********************************************/
function addClass(element, className) {    
  if (!hasClass(element, className)) {
    if (element.className) element.className += " " + className;        
    else element.className = className;    
  }
}
   
/*********************************************
** removeClass
*********************************************/
function removeClass(element, className) {    
  var regexp = new RegExp("(^|\\s)" + className + "(\\s|$)");    
  element.className = element.className.replace(regexp, "$2");
}

/*********************************************
** hasClass
*********************************************/
function hasClass(element, className) {    
  var regexp = new RegExp("(^|\\s)" + className + "(\\s|$)");    
  return regexp.test(element.className);
}

/*********************************************
** Used in result lists to enable selection of a checkbox input if the client click the cell alround the checkbox. 
** 
** INPUT:
**   checkBoxId: The ID of the checkbox to enable/disable
**   cellClicked: Pass True if the cell is clicked. Pass False if the Checkbox is clicked (Using the onClick event))
** 
*********************************************/

checkBoxTest = true;
function checkUncheckCheckBox(checkBoxId, cellClicked)
{
  if (checkBoxTest){
    if (cellClicked){
      obj = document.getElementById(checkBoxId);
      if (obj.type == "checkbox"){
       obj.checked = !obj.checked;
    }
      if (obj.type == "radio"){
       obj.checked = 1;
    }
    }else{
     checkBoxTest = false;
  }   
  }
  else 
     checkBoxTest = true;
}      

/*********************************************
** Cand be used to change the content of an html element
** 
** INPUT:
**   strObjId: The ID of an html element
**   sContent: The string that you wish to write into the element
** 
*********************************************/
function changeElementContent(strObjId, sContent)
{
  obj = document.getElementById(strObjId);
  if (obj) {
    obj.innerHTML=sContent;
  }
}

/*********************************************
** waitCursor
*********************************************/
function waitCursor()
{
  document.body.style.cursor = 'wait';
}

/*********************************************
** defaultCursor
*********************************************/
function defaultCursor()
{
  document.body.style.cursor = 'default';
}

/*********************************************
** check if accesskey has been hit 
*********************************************/
function clickAccessKey(_link)
{
  if (window.event && event.altKey) {
     _link.click();
     _parent = _link.parentNode;
 
     if (_parent) {
       if (_link.className == 'dropdown') rollOut(_parent,'down');
       if (_link.className == 'dropacross') rollOut(_parent,'across');
       if (_parent.onmouseover) _parent.onmouseover();
     }
  }
}


/*********************************************
** Disable Screen after submit is clicked 
*********************************************/
function disableScreen()
{
  // if screen already disabled then do not disable again
  if (document.getElementById('FW_mask')) return false;

  // show process indicator to user beside button that was clicked
  showProcessIndicator();

  // create div tag to mask all buttons on screen
  // PROGRAMMERS NOTE: see fw.css for more styling of mask
  var maskDiv=document.createElement("DIV");
  maskDiv.id = 'FW_mask';  
  maskDiv.style.display = 'block';

  // width: 100% does not work for doc type strict so so width here in CSS
  if (document.body.clientWidth) maskDiv.style.width = document.body.clientWidth;
  if (document.body.clientHeight) maskDiv.style.height = document.body.clientHeight;

  document.body.appendChild(maskDiv);
  
  // mask can not cover dropdowns (select boxes) as they are
  // handled by the os instead of the browser.
  // so disable them manually
  // disableDropdowns(true);

}

// enable and disable dropdowns (select boxes) on page
function disableDropdowns(_enable)
{
  
  var selects = document.getElementsByTagName('SELECT');
  for (var i=0; i<selects.length; i++)
    selects[i].disabled=_enable; 
}

// enable screen if error has occured
function enableScreen()
{
  var maskDiv = document.getElementById('FW_mask');
  
  if (!maskDiv)
  {
    return; 
  }

  var isIE = maskDiv.removeNode;
  var isMozilla = maskDiv.parent;
  
  if (isIE)
  {
    maskDiv.removeNode(true);
  }
  else if (isMozilla)
  {
    maskDiv.parent.removeChild(maskDiv);
  }
  else
  {
    document.body.removeChild(maskDiv);
  }

  hideProcessIndicator();
}

// show process indicator animated gif beside button that was clicked
function showProcessIndicator()
{

  var processInd = document.getElementById('FW_processInd');

  if (processInd) 
  {
    processInd.style.visibility = 'visible';

    // IE stops animations on form submit, so we need to reassign
    // the gif animation source after submission is complete in order
    // to see the animation.
    setTimeout('refreshProcessIndicator()', 200);
  }
}

// hide process indicator
function hideProcessIndicator()
{
  var processInd = document.getElementById('FW_processInd');
  if (processInd) processInd.style.visibility = 'hidden';
}

// refresh process indicator to workaround IE bug
function refreshProcessIndicator()
{
  var processInd = document.getElementById('FW_processInd');
  if (processInd) processInd.src = processInd.src;
}

/* Automatically renable screen after non html page is loaded 
 * NOTE: do not use this function for normal enabling of screen, use enableScreen
 * PROGRAMMERS NOTE: this function is written for instances when a post returns a PDF/RTF instead 
 *                   of an HTML page.
 */                   
function enableScreenAfterDownload()
{
  // must add function dynamically so it fires at appropriate time
  document.onreadystatechange = function() {
	//	if(document.readyState=="interactive") {
  		setTimeout(wrapperEnableScreenAfterDownload, 2000);
//		}
	}
}

/*
 * Wrapper function to enable screen
 * PROGRAMMERS NOTE: should only be called from enableScreenAfterDownload
 */
function wrapperEnableScreenAfterDownload()
{
  // if readystate is interactive then enable screen
	document.onreadystatechange=null;
	enableScreen();
	document.body.style.cursor='default';
}



/*********************************************
** ArrayList
*********************************************/
function ArrayList()
{
  this.aList = []; //initialize with an empty array
}

/*********************************************
** ArrayList.prototype.Count
*********************************************/
ArrayList.prototype.Count = function()
{
  return this.aList.length;
}

/*********************************************
** ArrayList.prototype.Add
*********************************************/
ArrayList.prototype.Add = function( object )
{
  return this.aList.push( object ); //Object are placed at the end of the array
}

/*********************************************
** ArrayList.prototype.GetAt
*********************************************/
ArrayList.prototype.GetAt = function( index ) //Index must be a number
{
  if( index > -1 && index < this.aList.length )
    return this.aList[index];
  else
    return undefined; //Out of bound array, return undefined
}

/*********************************************
** ArrayList.prototype.Clear
*********************************************/
ArrayList.prototype.Clear = function()
{
  this.aList = [];
}

/*********************************************
** ArrayList.prototype.RemoveAt
*********************************************/
ArrayList.prototype.RemoveAt = function ( index ) // index must be a number
{
  var m_count = this.aList.length;

  if ( m_count > 0 && index > -1 && index < this.aList.length )
  {
    switch( index )
    {
      case 0:
        this.aList.shift();
        break;
      case m_count - 1:
        this.aList.pop();
        break;
      default:
        var head   = this.aList.slice( 0, index );
        var tail   = this.aList.slice( index + 1 );
        this.aList = head.concat( tail );
        break;
     }
  }
}

/*********************************************
** ArrayList.prototype.Insert
*********************************************/
ArrayList.prototype.Insert = function ( object, index )
{
  var m_count       = this.aList.length;
  var m_returnValue = -1;

  if ( index > -1 && index <= m_count )
  {
    switch(index)
    {
      case 0:
        this.aList.unshift(object);
        m_returnValue = 0;
        break;
      case m_count:
        this.aList.push(object);
        m_returnValue = m_count;
        break;
      default:
        var head      = this.aList.slice(0, index - 1);
        var tail      = this.aList.slice(index);
        this.aList    = this.aList.concat(tail.unshift(object));
        m_returnValue = index;
        break;
    }
  }

  return m_returnValue;
}

/*********************************************
** ArrayList.prototype.IndexOf
*********************************************/
ArrayList.prototype.IndexOf = function( object, startIndex )
{
  var m_count       = this.aList.length;
  var m_returnValue = - 1;

  if ( startIndex > -1 && startIndex < m_count )
  {
    var i = startIndex;

    while( i < m_count )
    {
      if ( this.aList[i] == object )
      {
        m_returnValue = i;
        break;
      }

      i++;
    }
  }

  return m_returnValue;
}

/*********************************************
** ArrayList.prototype.LastIndexOf
*********************************************/
ArrayList.prototype.LastIndexOf = function( object, startIndex )
{
  var m_count       = this.aList.length;
  var m_returnValue = - 1;

  if ( startIndex > -1 && startIndex < m_count )
  {
    var i = m_count - 1;

    while( i >= startIndex )
    {
      if ( this.aList[i] == object )
      {
        m_returnValue = i;
        break;
      }

      i--;

    }
  }

  return m_returnValue;
}

/*********************************************
** Extend the string class with a pad function
** type : 0 = left, 1 = right, 2 in both
*********************************************/
String.prototype.pad = function(length, char, type)
{
	return char || (char = " "), (length -= this.length) > 0 ? (char = new Array(Math.ceil(length / char.length)
		+ 1).join(char)).substr(0, type = !type ? length : type == 1 ? 0 : Math.ceil(length / 2))
		+ this + char.substr(0, length - type) : this;
}

// pad left side of string
String.prototype.lpad = function(length, char)
{
  return this.pad(length, char, 0);
}

// pad right side of string
String.prototype.rpad = function(length, char)
{
  return this.pad(length, char, 1);
}

// pad both sides of string
String.prototype.bpad = function(length, char)
{
  return this.pad(length, char, 2);
}


/*********************************************
** Extend the string class with a trim function
** type : 0 = left, 1 = right, 2 in both
*********************************************/
// trim spaces from both ends of string
String.prototype.trim = function()
{
  var str = this.ltrim();
  return str.rtrim();
}

// trim spaces left side of string
String.prototype.ltrim = function()
{
  return this.replace(/^\s+/g, ''); 
}

// trim spaces from right side of string
String.prototype.rtrim = function()
{
  return this.replace(/\s+$/g, '');
}

