/* This file contains utilities for controlling the look and feel of user screens */

/* Global warning timeout to login value */
var timeoutWarningSeconds = null;
var timeoutWarningRemaining = null;
var timeoutForSession = null;
var timeoutIntervalId = null;
var timeoutToLoginId = null;
var timeoutDestination = null;
var buttonsActivated = false;
/*****************************************/
function startTimeoutWarning() {
  timeoutWarningRemaining = timeoutWarningSeconds;
  timeoutIntervalId = window.setInterval( timeWarning, 1000, "JavaScript" );
  window.focus();
}

function setTimeoutWarningSeconds( seconds ) {
  timeoutWarningSeconds = seconds;
}

function clearWarning( servletUrl ) {
  if( timeoutIntervalId != null )
    window.clearInterval( timeoutIntervalId );
  var element = document.getElementById( "refresh" );
  if( element != null ) {
    element.src = "";
    element.src = servletUrl;
  }
  element = document.getElementById( "timeOutWarningId" );
	if( element != null )
		element.style.display = "none";
  startTimeoutToWarning( (timeoutForSession - ( (timeoutWarningSeconds + 1) * 1000)), timeoutWarningSeconds );
  startTimeoutToDestination( timeoutDestination, timeoutForSession );
}

function startTimeoutToDestination( servletUrl, timeInMs ) {
  timeoutDestination = servletUrl;
  timeoutForSession = timeInMs;
  if( timeoutToLoginId != null )
    window.clearTimeout( timeoutToLoginId );
  timeoutToLoginId = window.setTimeout( "javascript:window.location='" + servletUrl + "'", timeInMs, "JavaScript" );
}

function startTimeoutToWarning( timeInMs, secondsToWarn ) {
  setTimeoutWarningSeconds( secondsToWarn );
  window.setTimeout( startTimeoutWarning, timeInMs, "JavaScript" );
}

function timeWarning() {
	try {
		if( timeoutIntervalId == null )
			return;
		var element = document.getElementById( "timeOutWarningId" );
		if( element == null )
			return;
		element.style.display = "block";
		var sec = " second";
		if( timeoutWarningRemaining > 1 )
			sec += "s";
		element.innerHTML = "Logging out in " + (timeoutWarningRemaining--) + sec + ".<BR><u>Click</u> to Cancel.";
		if( timeoutWarningRemaining < 0 ) {
			window.clearInterval( timeoutIntervalId );
			element.style.display = "none";
		}
	}
	catch( ex ) {
		// ignore the error
	}
}

/***************doNothing*****************/
// JAVASCRIPT FUNCTION -- DOES NOTHING (USED FOR THE HREF IN THE CALENDAR CALL)
function doNothing() {
}
/***************doNothing*****************/

/*****************************************/
/* This section manages the toggling for all checkboxes displayed on screen */

// Set All CheckBoxes of a name pattern to the bFlag Value
function ToggleAllByNamePattern( FormObj, list, namePattern, bFlag ) {
  if( FormObj == null )
    return;
  var elements = FormObj.elements;
  var len = elements.length;
  var re = new RegExp( namePattern );
  for( var i = 0; i < len; i++ ) {
    if( elements[i].type == 'checkbox' && elements[i].name.match( re ) != null ) {
      SetCheckBox( elements[i], bFlag );
      if( list != null )
        updateCheckboxValueList( FormObj, list, elements[i] );
    }
  }
}

// Set the CheckBox.checked to the bFlag Value
function SetCheckBox( ObjCheckBox, bFlag ) {
  if( ObjCheckBox == null )
    return;
  if( ObjCheckBox.disabled == true && (ObjCheckBox.checked == true || bFlag) )
    ObjCheckBox.checked = false;
  else if( ObjCheckBox.checked != bFlag )
    ObjCheckBox.checked = bFlag;
}

// Set All CheckBoxes of a given name to the bFlag Value
function ToggleAll( FormObj, list, chkbox, bFlag ) {
  var cbName = chkbox.name;
  if (chkbox.checked)
    checkUncheck(FormObj, cbName, list, true);
  else
    checkUncheck(FormObj, cbName, list, false);
}

function checkUncheck( FormObj, cbName, list, bFlag ) {
  var len = FormObj.elements.length;
  var i=0;
  var ptr;
  for( i=0; i<len; i++) {
    ptr = FormObj.elements[i];
    if( ptr.type == 'checkbox' && ptr.name == cbName ) {
      if( ptr.disabled == true && (ptr.checked == true || bFlag) ) {
        if( ptr.checked == true )
          updateCheckboxValueList(FormObj, list, ptr);
        ptr.checked = false;
      }
      else if( ptr.checked != bFlag ) {
        ptr.checked = bFlag;
        updateCheckboxValueList( FormObj, list, ptr );
      }
    }
  }
}

function updateCheckboxValueList(FormObj, list, checkbox) {
  if( list == null )
    return;
  var selectedValues = list.value;
  var tmpValue = checkbox.value;
  if( tmpValue.length > 0 ) {
    var index = selectedValues.indexOf("<" + tmpValue + ">");
    if (index > -1) {
      var firsthalf = selectedValues.substring(0, index);
      var secondhalf = selectedValues.substring(index + tmpValue.length + 2);
      list.value = firsthalf + secondhalf;
    }
    else {
      list.value += "<" + tmpValue + ">";
    }
  }
}

/* This section manages the swapping of images on mouseover, mouseout, and mousedown events */

var PreLoadedNames = new Array();	// these two are expected to complement each other
var PreLoadedImages = new Array();
// this function will handle any number of arguments - expected to be image pathnames
function PreLoadImages() {
  if( PreLoadImages.arguments == null )
    return;
  var ple = PreLoadedNames.length - 1;	// element idx in the consecutive arrays
  if( ple < 0 )
    ple = 0;
  var cnt = PreLoadImages.arguments.length;
  var args = PreLoadImages.arguments;
  for( var i = cnt; --i > -1; ple++ ) {
    PreLoadedNames[ple] = args[i];
    PreLoadedImages[ple] = new Image();
    PreLoadedImages[ple].src = args[i];
  }
}

function CheckPreLoaded( file ) {
  if( PreLoadedNames != null && PreLoadedNames.length > 0 ) {
    for( var i = PreLoadedNames.length; --i > -1; ) {
      if( PreLoadedNames[i] == file )
        return( PreLoadedImages[i].src );
    }
  }
  return( null );
}

function SwapImage( img, file ) {
  var pl = CheckPreLoaded( file );
  if( pl != null )
    img.src = pl;
  else
    img.src = file;
}

/* Disable and Enable FixedButton objects */

function getButtonsActivated() {
	return buttonsActivated;
}

function setButtonsActivated( bActivated ) {
	buttonsActivated = bActivated;
}

var disabledIdList = null;
var disabledImages = null;

function removeFixedButton( strButtonRowId ) {
  if( strButtonRowId != null ) {
    var element = document.getElementById( strButtonRowId );
    if( element != null ) {
      element.className = "invisible";
    }
  }
}

function replaceFixedButton( strButtonRowId ) {
  if( strButtonRowId != null ) {
    var element = document.getElementById( strButtonRowId );
    if( element != null ) {
      element.className = "buttontable";
    }
  }
}

function DisableFixedButtons( idListName, disImageFile ) {
  var idList = document.getElementsByName( idListName );
  if( idList == null )
    return;
  disabledIdList = new Array();
  disabledImages = new Array();
  var disabledIdx = 0;
  for( var j = idList.length; --j > -1; ) {
    var ids = idList[j].value.split( ' ' );
    for( var i = ids.length; --i > -1; ) {
      var element = document.getElementById( ids[i] );
      if( element != null ) {
        if( element.src != null ) {
          disabledImages[disabledIdx] = element.src;
          SwapImage( element, disImageFile );
        }
        element.disabled = true;
        disabledIdList[disabledIdx++] = ids[i];
      }
    }
  }
}

function EnableFixedButtons( idListName, normImageFile ) {
  if( EnableFixedButtons.arguments != null && EnableFixedButtons.arguments.length == 0 ) {
    // this is to re-enable the buttons that were disabled and then submit was cancelled.
    if( disabledIdList == null || disabledImages == null )
      return;
    for( var k = disabledIdList.length; --k > -1; ) {
      var re = document.getElementById( disabledIdList[k] );
      if( re != null ) {
        if( re.src != null )
          SwapImage( re, disabledImages[k] );
        re.disabled = false;
      }
    }
    disabledIdList = null;
    disabledImages = null;
    return;
  }
  var idList = document.getElementsByName( idListName );
  for( var j = idList.length; --j > -1; ) {
    var ids = idList[j].value.split( ' ' );
    for( var i = ids.length; --i > -1; ) {
      var element = document.getElementById( ids[i] );
      if( element != null ) {
        if( element.src != null )
          SwapImage( element, normImageFile );
        element.disabled = false;
      }
    }
  }
}

/**
 * This function will keep the 'fixedbuttons' class positioned
 * when the body is scrolled.
 * PRE-REQUISITE - the onscroll event of the body tag needs
 *		to call this function.  See HtmlFixedButton.java
 */
function moveButtons() {
  var dv = document.getElementsByTagName( "div" );
  if( dv == null )
    return;
  for( var i = 0, l = dv.length; i < l; i++ ) {
    if( dv[i].className == "fixedbuttons" ) {
      var yPos = (document.all) ? document.body.scrollTop : window.pageYOffset;
      dv[i].style.position = "absolute";
      dv[i].style.pixelLeft = 10;
      dv[i].style.pixelTop = (yPos + 10);
      break;
    }
  }
}
/* end of fixed buttons section */

/* this section substitutes options into a given html select object */

/**
 *	Send in the Id of the Select Element along with
 *        a comma separated string of Name=Value pairs.
 * NOTE: this function treats the 3rd, 4th, 5th and 6th argument as optional
 *	The selectedItems argument is a comma separated string -
 *        it will match to either the name or value.
 *      The sortByValue is a boolean that if true will sort by the value
 *        portion of the options array, otherwise the text portion
 *        will be used.  If this is not present no sort will be attempted
 *      The scale argument when present indicates that number formatting
 *        to the given scale is required on the display (Name) portion
 *        of the Name=Value pairs.
 *      The formatFunction is used to format the display (Name) portion
 *        of the Name=Value pairs.
 */
function SetOptions( selectId, options, selectedItems, sortByValue, scale, formatFunction ) {
  if( selectId == null || options == null )
    return;
  var sel = document.getElementById( selectId );
  if( sel == null )
    return;

  var toSelect = null;
  var cnt = 0;
  if( SetOptions.arguments.length > 2 ) {
    toSelect = new String( SetOptions.arguments[2] ).split( "," );
    cnt = toSelect.length;
  }
  var sortBy = null;
  if( SetOptions.arguments.length > 3 )
    sortBy = SetOptions.arguments[3];

  var selectedIdx = -1;
  sel.options.length = 0;	// clear existing options
  sel.selectedIndex = selectedIdx;

  var pairs = options.split( "," );
  if( pairs == null )
    return;

  var len = pairs.length;
  var newOpts = new Array( len );
  var scl = null;

  if( SetOptions.arguments.length > 4 ) {
    var allNumbers = true;
    scl = SetOptions.arguments[4];
    for( var i = 0; i < len; i++ ) {
      var opt = pairs[i].split( "=" );
      if( opt == null || opt.length < 1 || isNumeric( opt[0] ) == false ) {
        allNumbers = false;
        break;
      }
    }
    if( allNumbers == false )
      scl = null;
  }

  for( i = 0; i < len; i++ ) {
    opt = pairs[i].split( "=" );
    if( opt == null || opt.length < 1 )
      continue;
    var oOption = document.createElement( "OPTION" );
    if( scl != null ) {
      if( formatFunction != null )
        oOption.text = formatFunction( opt[0], scl );
      else
        oOption.text = currencyFormatted( opt[0], scl );
    }
    else if( formatFunction != null )
      oOption.text = formatFunction( opt[0] );
    else
      oOption.text = opt[0];
    if( opt.length >= 2 )
      oOption.value = opt[1];
    else
      oOption.value = opt[0];
    newOpts[i] = oOption;
  }

  if( sortBy != null )
    SelectSort( newOpts, 0, newOpts.length - 1, sortBy );

  if( toSelect != null ) {
    for( i = 0; i < len; i++ ) {
      for( var x = 0; x < cnt; x++ ) {
        if( newOpts[i].text == toSelect[x] || newOpts[i].value == toSelect[x] ) {
          newOpts[i].selected = true;
          if( selectedIdx == -1 )
            selectedIdx = i;
          break;
        }
      }
      sel.add( newOpts[i] );
    }
  }
  else {
    for( i = 0; i < len; i++ )
      sel.add( newOpts[i] );
  }

  if( selectedIdx != -1 )
    sel.selectedIndex = selectedIdx;
}

function CompareSelect( v1, v2, byValue ) {
  var sortLo = byValue ? v1.value : v1.text;
  var sortHi = byValue ? v2.value : v2.text;

  if( sortLo > sortHi )
    return( 1 );
  if( sortLo < sortHi )
    return( -1 );
  return( 0 );
}

function SelectSort( vec, loBound, hiBound, byValue )	{

  /**************************************************************
   This function adapted from the algorithm given in:
   Data Abstractions & Structures Using C++, by
   Mark Headington and David Riley, pg. 586.

   Quicksort is the fastest array sorting routine for
   unordered arrays.  Its big O is n log n.
   **************************************************************/
  var pivot, loSwap, hiSwap, temp, sortLo, sortHi;

  if( byValue == null )
    byValue = false;

  // Two items to sort
  if( hiBound - loBound == 1 ) {

    if( CompareSelect( vec[loBound], vec[hiBound], byValue ) > 0 ) {
      temp = vec[loBound];
      vec[loBound] = vec[hiBound];
      vec[hiBound] = temp;
    }
    return;
  }

  // Three or more items to sort
  pivot = vec[parseInt((loBound + hiBound) / 2)];
  vec[parseInt((loBound + hiBound) / 2)] = vec[loBound];
  vec[loBound] = pivot;
  loSwap = loBound + 1;
  hiSwap = hiBound;

  do {
    // Find the right loSwap
    while (loSwap <= hiSwap && CompareSelect( vec[loSwap], pivot, byValue ) <= 0 )
      loSwap++;

    // Find the right hiSwap
    while( CompareSelect( vec[hiSwap], pivot ) > 0 )
      hiSwap--;

    // Swap values if loSwap is less than hiSwap
    if (loSwap < hiSwap) {
      temp = vec[loSwap];
      vec[loSwap] = vec[hiSwap];
      vec[hiSwap] = temp;
    }
  } while (loSwap < hiSwap);

  vec[loBound] = vec[hiSwap];
  vec[hiSwap] = pivot;


  // Recursively call function...  the beauty of quicksort

  // 2 or more items in first section
  if (loBound < hiSwap - 1)
    SelectSort( vec, loBound, hiSwap - 1, byValue );


  // 2 or more items in second section
  if (hiSwap + 1 < hiBound)
    SelectSort( vec, hiSwap + 1, hiBound, byValue );
}

/* this section returns the value stored in a global cookie ( document.cookie ) */

function GetCookie( name ) {
  var cookies = document.cookie;
  var startIndex = 0;
  while( cookies.length > 0 ) {
    startIndex = cookies.indexOf( name + "=" );
    if( startIndex == -1 )
      return( null );
    if( startIndex == 0 )
      break;
    if( (cookies.charAt( startIndex - 1) == ' ') || (cookies.charAt( startIndex - 1 ) == ';') )
      break;
    cookies = cookies.substring( startIndex + name.length + 1 );
  }
  if( cookies.length == 0 )
    return( null );
  var endIndex = cookies.indexOf( ";", startIndex );
  if( endIndex == -1 )
    endIndex = cookies.length;
  return( unescape( cookies.substring( startIndex + name.length + 1, endIndex ) ) );
}

function SetCookie( name, value ) {
  var argv = SetCookie.arguments;
  var argc = SetCookie.arguments.length;
  var expires = (argc > 2) ? argv[2] : null;
  var path = (argc > 3) ? argv[3] : null;
  var domain = (argc > 4) ? argv[4] : null;
  var secure = (argc > 5) ? argv[5] : false;
  document.cookie = name + "=" + escape( value ) +
  ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
  ((path == null) ? "" : ("; path=" + path)) +
  ((domain == null) ? "" : ("; domain=" + domain)) +
  ((secure == true) ? "; secure" : "");
}

function DeleteCookie( name ) {
  var exp = new Date();
  exp.setTime( exp.getTime() - 1000000000 );  // This cookie is history
  SetCookie( name, "", exp );
}

/* this section is to facilitate the removing of broadcast messages in SOSServlet */

function SetDeleteMessage( divId, msgId ) {	// the id of the div with the message and the column SchedSentNoteId value
  document.getElementById( divId ).style.display="none";
  var exp = new Date();
  exp.setYear( exp.getYear() + 1 );
  var c = GetCookie( "DeleteMessage" );
  if( c == null )
    SetCookie( "DeleteMessage", msgId, exp );
  else
    SetCookie( "DeleteMessage", c + ":" + msgId, exp );
}

/* this section facilitates the hiding or display of the "Active" member info in the Banner frame */

function hidename() {
  var frm = window.parent[0];
  if( frm != null ) {
    var show = frm.document.getElementById( "showname" );
    if( show != null ) {
      show.style.display = "none";
      frm.document.getElementById( "hidename" ).style.display="block";
    }
  }
}

function showname() {
  var frm = window.parent[0];
  if( frm != null ) {
    var show = frm.document.getElementById( "showname" );
    if( show != null ) {
      show.style.display = "block";
      frm.document.getElementById( "hidename" ).style.display="none";
    }
  }
}

/**
 * Show or Hide an element by id
 */
function showOrHide( frameNum, id, hide ) {
	var frm = window.parent[frameNum];
	if( frm != null ) {
		var element = frm.document.getElementById( id );
		if( element == null )
			return;
		if( hide == true )
			element.style.display = "none";
		else
			element.style.display = "block";
	}
}

/* Section assists in controlling the contents of popup help text */
function ShowTip( event, tipObj, text ) {
  if( event == null || tipObj == null || text == null || ShowTip.arguments.length < 3 )
    return;

  var TipVar = document.getElementById( tipObj );//tip was passed in as a string

  if( TipVar == null )
    TipVar = tipObj;	//tip was passed in as an object

  var width = 200;
  if( text.length > 400 )
    width = 250;
  if( text.length > 800 )
    width = 300;
  domTT_activate( TipVar, event, 'content', text, 'type', 'greasy', 'trail', true,
		'fade', 'out', 'direction', 'southwest', 'width', width, 'styleClass', 'domTTClassic' );
}

// find the object on the document - then attempt to focus on it
// strName - name of the object to find
function focusOnName( strName ) {
  if( strName == null )
    return;
  var objs = document.getElementsByName( strName );
  if( objs == null || objs.length > 1 )
    return;
  focusOnObject( objs[0] );
}

// Focus on checked RadioButton or CheckBox in a group or on any non-group object
function focusOnObject( obj ) {
  if( obj == null )
    return;
  if( window.focus != null )
    window.focus();
  if( obj.length == null ) {
    if( obj.focus != null ) {
      var theForm = obj.getAttribute( "form" );
      if( theForm != null && theForm.focus != null )
        theForm.focus();
      if( obj.type != null && obj.type != 'hidden' && obj.disabled != null && obj.disabled == false )
        obj.focus();
    }
  }
  else {
    var len = obj.length;
    if( obj.focus != null ) {
      if( obj.type != null && obj.type != 'hidden' && obj.disabled != null && obj.disabled == false )
        obj.focus();
    }
    for( var i = 0; i < len; i++ ) {
      theForm = obj[i].getAttribute( "form" );
      if( theForm != null && theForm.focus != null )
        theForm.focus();
      var type = new String( obj[i].type ).toLowerCase();
      if( type == 'hidden' )
        continue;
      if( type.match( "^checkbox|radio" ) ) {
        if( obj[i].checked != null && obj[i].checked == true &&
        obj[i].focus != null && obj[i].disabled != null && obj[i].disabled == false ) {
          obj[i].focus();
          break;
        }
      }
      else if( obj[i].focus != null && obj[i].disabled != null && obj[i].disabled == false ) {
        obj[i].focus();
        break;
      }
    }
  }
}

// This function takes a form object and checks to see if any of its element values have been modified since the page loaded.
// return false if all current values match those of the defaults, otherwise true
function formModified( formRef ) {
  for(var i = 0, j = formRef.elements.length; i < j; i++) {
    var myType = formRef.elements[i].type;
    if( myType == 'checkbox' || myType == 'radio' ) {
      if( formRef.elements[i].checked != formRef.elements[i].defaultChecked ) {
        return true;
      }
    }
    else if( myType == 'text' || myType == 'textarea' ) {
      if( formRef.elements[i].value != formRef.elements[i].defaultValue ) {
        return true;
      }
    }
    else if(myType == 'select-one' || myType == 'select-multiple') {
      for (var k = 0, l = formRef.elements[i].options.length; k < l; k++) {
        if( formRef.elements[i].options[k].selected != formRef.elements[i].options[k].defaultSelected ) {
          return true;
        }
      }
    }
    else
      continue;
  }
  return false;
}

/* this section allows for sorting of tables */

var sortBy = [ [-1], ['ASC'] ];	// this will toggle first to Ascending

function DrawTable( tableName ) {
  var j, newTable = "";
  var TableItems = eval( tableName + "TableItems" );

  for( j in TableItems ) {
    var count = 2;
    if( j%2 )
      count = 1;
    TableItems[j] = TableItems[j].replace( /rowcolor[12]/, "rowcolor" + count );
    newTable += TableItems[j];
  }

  document.getElementById(tableName).innerHTML = newTable;

  //if it does not exist, exit
  if( eval( "typeof "+tableName+"docImages"+" == 'undefined'" ) )
    return;

  var docImages = eval( tableName + "docImages" );
  if( docImages == null )
    return;

  var thisImg;
  for( var thisPic in docImages ) {
    thisImg = document.getElementById(docImages[thisPic]);
    thisImg.src = sortImgArray[2].src;
  }

  thisImg = document.getElementById( docImages[sortBy[0]] );
  if( thisImg == null )
    return;
  var whichPic = (sortBy[1] == 'ASC') ? 0 : 1 ;
  thisImg.src = sortImgArray[whichPic].src;
}

function SortTable( tableName, column ) {
  //Figure out if we'll be doing ascending or descending
  if( sortBy[0] == column )	{
    if( sortBy[1] == 'ASC' )
      sortBy[1] = 'DES';
    else
      sortBy[1] = 'ASC';
  }
  else {
    sortBy[0] = column;
    sortBy[1] = 'ASC';
  }

  var TableItems = eval( tableName + "TableItems" );
  //leave the first and last row alone!!
  if( TableItems.length > 3 )
    Quicksort( TableItems, 1, TableItems.length - 2, column );

  DrawTable( tableName );

}

function Quicksort( vec, loBound, hiBound, column ) {

  var pivot, loSwap, hiSwap, temp;

  // Two items to sort
  if (hiBound - loBound == 1)	{
    if ( TableItemIsGreaterThan( vec[loBound], vec[hiBound], column ) )	{
      temp = vec[loBound];
      vec[loBound] = vec[hiBound];
      vec[hiBound] = temp;
    }
    return;
  }

  // Three or more items to sort
  pivot = vec[parseInt((loBound + hiBound) / 2)];
  vec[parseInt((loBound + hiBound) / 2)] = vec[loBound];
  vec[loBound] = pivot;
  loSwap = loBound + 1;
  hiSwap = hiBound;

  do {
    // Find the right loSwap
    while (loSwap <= hiSwap && !(TableItemIsGreaterThan( vec[loSwap], pivot, column )) )
      loSwap++;

    // Find the right hiSwap
    while ( TableItemIsGreaterThan( vec[hiSwap], pivot, column ) )
      hiSwap--;

    // Swap values if loSwap is less than hiSwap
    if (loSwap < hiSwap) {
      temp = vec[loSwap];
      vec[loSwap] = vec[hiSwap];
      vec[hiSwap] = temp;
    }
  } while (loSwap < hiSwap);

  vec[loBound] = vec[hiSwap];
  vec[hiSwap] = pivot;

  // Recursively call function...  the beauty of quicksort

  // 2 or more items in first section
  if (loBound < hiSwap - 1)
    Quicksort(vec, loBound, hiSwap - 1, column);


  // 2 or more items in second section
  if (hiSwap + 1 < hiBound)
    Quicksort(vec, hiSwap + 1, hiBound, column);
}

/* globals for Client Table sort function */
var reIsDate = new RegExp( "^([\\d]{2})\\/([\\d]{2})\\/([\\d]{4})(.*)" );	// is the data a date - MM/DD/YYYY
var reIsNumber = new RegExp( "^[\\-\\d\\.,\\$]+$" );	// is the data a number or amount
var reIsTaxId = new RegExp( "^(([\\d]{3})\\-([\\d]{2})\\-([\\d]{4}))|(([\\d]{2})\\-([\\d]{7}))$" );
var reInput = new RegExp( "<+input[\\S\\s]*?>+", "gi" );	// find input tags to replace with &nbsp;
var reTags = new RegExp( "<+[\\S\\s]*?>+", "gi" );	// find html tags - to replace with '*'
var reNoComma = new RegExp( "[,\\$]", "g" );	// remove comma or Dollar Sign
var reNoDash = new RegExp( "[-]", "g" );	// remove the '-' characters
/* globals for Client Table sort function */

function TableItemIsGreaterThan( item_a, item_b, column ) {
  item_a = item_a.replace( reInput, "&nbsp;" );	// allow input to look like data to make column #'s correct
  item_b = item_b.replace( reInput, "&nbsp;" );	// although it wouldn't work to sort it
  item_a = item_a.replace( reTags, "*" );
  item_b = item_b.replace( reTags, "*" );

  //Split using a regex doesn't have consistant results across browsers (ie drops blank elements)
  var a = item_a.split( "*" );
  var b = item_b.split( "*" );

  //ignore blank columns in the array (this seems odd, but it's exactly what ie was doing)
  var len = a.length;
  var nonBlankIndex = 0;
  for( var i = 0; i < len; i++ ) {
    if( a[i] != "" ){
      a[nonBlankIndex] = a[i];
      b[nonBlankIndex] = b[i];
      nonBlankIndex++;
    }
  }

  var colA = a[column].toLowerCase();
  var colB = b[column].toLowerCase();

  // test for SSN - TaxId first it will also look like a number
  if( reIsTaxId.test( colA ) && reIsTaxId.test( colB ) ) {
    //if they look like SSN or TaxId then make them int
    colA = parseInt( colA.replace( reNoDash, "" ) );
    colB = parseInt( colB.replace( reNoDash, "" ) );
  }
  else if( reIsNumber.test( colA ) && reIsNumber.test( colB ) ) {
    //If they look like numbers, sort like numbers!!
    colA = parseFloat( colA.replace( reNoComma, "" ) );
    colB = parseFloat( colB.replace( reNoComma, "" ) );
  }
  else if( reIsDate.test( colA ) && reIsDate.test( colB ) )	{
    //If they look like dates, sort like dates!! - put the year first
    var match = reIsDate.exec( colA );
    colA = match[3] + "/" + match[1] + "/" + match[2] + " " + match[4];

    match = reIsDate.exec( colB );
    colB = match[3] + "/" + match[1] + "/" + match[2] + " " + match[4];
  }

  if( (colA > colB && sortBy[1] == 'ASC') || (colA < colB && sortBy[1] == 'DES') )
    return( true );
  else
    return( false );
}

/* end sorting tables section */

/* externally load via innerHTML - Activate the APPLET */
function loadObject( divID, html ) {
  var div = document.getElementById( divID );
  if( div == null )
    return;
  div.innerHTML = html;
}

/* save and reposition the scroll bar */

/**
 * Restore the Scroll Bar Coordinates
 * xOffset value to scroll to
 * yOffset value to scroll to
 */
function scrollToCoordinates( xOffset, yOffset ) {
  window.scrollTo( xOffset, yOffset );
}

/**
 * Save the Scroll Bar Coordinates
 * xObject is hidden object to save the xOffset value to
 * yObject is the hidden object to save the yOffset value to
 */
function saveScrollCoordinates( xObject, yObject ) {
  xObject.value = getXScrollOffset();
  yObject.value = getYScrollOffset();
}

/**
 * Get the X Scroll Offset Value from the document
 */
function getXScrollOffset() {
  return( (document.all) ? document.body.scrollLeft : window.pageXOffset );
}

/**
 * Get the Y Scroll Offset Value from the document
 */
function getYScrollOffset() {
  return( (document.all) ? document.body.scrollTop : window.pageYOffset );
}

/* end of save and reposition the scroll bar */

/* Format numbers */

//Function strToCurr()
//Author: Greg Burgess
//Purpose: This function takes one parameter (a string representing a currency amount) which it validates
//formats and returns.
//Takes an optional 2nd argument to specify scale - defaults to 2
//Example strToCurr("12.5")   --> 12.50
//	  strToCurr("12")      --> 12.00
//	  strToCurr("12.59") --> 12.60

function strToCurr( newValue ) {
  var errorCode = false;
  var scale = 2;

  if( strToCurr.arguments.length > 1 )
    scale = strToCurr.arguments[1];

  dolAmount = parseFloat( newValue );
  if( isNaN( dolAmount ) )
    errorCode = true;

  if( errorCode == true ) {
    alert( 'Please enter a valid amount.' );
    if( window.event != null )
      window.event.returnValue = false;
    return( appendZeroToPrecision( 0, scale ) );
  }

  var div = Math.pow( 10, scale );
  var dolAmount = Math.round( dolAmount * div );

  return( currencyFormatted( (dolAmount / div), scale ) );
}

// Format a number to currency format with optional scale (default is 2)
function currencyFormatted( amount ) {
  var scale = 2;
  if( currencyFormatted.arguments.length > 1 )
    scale = currencyFormatted.arguments[1];
  var i = parseFloat( amount );
  if( isNaN( i ) ) {
    i = 0.00;
  }
  i = Math.abs(i);
  var round = appendZeroToPrecision( 0, scale ) + 5;
  var mult = "1";
  for( i = 0; i < scale; mult += "0", i++ );
  mult = 1 + appendZeroToPrecision( 0, scale );
  i = parseInt( (i + round) * 100 );
  i = i / mult;
  var s = new String( i );
  if( s.indexOf( '.' ) < 0 )
    s += '.';
  s = appendZeroToPrecision( amount, scale );

  return( s );
} // function currencyFormatted()

// Format a number to contain commas and be padded to the given scale
function commaFormatted( amount, scale ) {
  var delimiter = ",";
  amount = new String( amount );
  if( amount.indexOf( delimiter ) >= 0 )
    amount = removeCommas( amount );

  var idx = amount.indexOf( '.' );
  if( scale > 0 ) {
    if( idx == 0 )
      amount = "0" + amount;
    if( idx < 0 )
      amount += ".0";
  }
  var amt = parseFloat( amount );
  if( isNaN( amt ) )
    return( appendZeroToPrecision( 0, scale ) );

  var minus = '';
  if( amt < 0 )
    minus = '-';

  var a = amount.split( '.', 2 );
  var d = a[1];
  var i = parseInt( a[0] );

  i = Math.abs( i );
  var n = new String( i );
  a = [];
  while( n.length > 3 )	{
    var nn = n.substr( n.length - 3 );
    a.unshift( nn );
    n = n.substr( 0, n.length - 3 );
  }
  if( n.length > 0 )
    a.unshift( n );

  n = a.join( delimiter );
  if(d && d.length && d.length < 1 || ("" + d) == 'undefined' )
    amount = n;
  else
    amount = n + '.' + d;

  if( scale > 0 )
    amount = appendZeroToPrecision( amount, scale );

  return( minus + amount );
} // function commaFormatted()


function appendZeroToPrecision( amount, scale ) {
  amount = new String( amount );
  if( scale > 0 ) {
    var idx = amount.indexOf( '.' );
    if( idx < 0 )
      amount += ".0";
    for( var i = amount.length - amount.indexOf( '.' ) - 1; i < scale; amount += '0', i++ );
  }
  return( amount );
}

function removeCommas( amount ) {
  amount = new String( amount );
  var a = amount.split( ',' );
  var len = a.length;
  if( len <= 0 )
    return( amount );
  var newAmount = "";
  for( var i = 0; i < len; i++ ) {
    newAmount += a[i];
  }
  return( newAmount );
}

function sumValues( list, cnt ) {  			// this will assume a scale of 2, but will accept an optional scale argument
  var totVal = 0;
  var scale = 2;
  if( sumValues.arguments.length > 2 )
    scale = sumValues.arguments[2];

  var mult = Math.pow( 10, scale );
  for( var x = 0; x < cnt; x++ )
    totVal += Math.round( (list[x] * mult) );
  return( strToCurr( ("" + (totVal / mult)), scale ) );
}

function sumFieldValues( fields, cnt ) {		// this will assume a scale of 2, but will accept an optional scale argument
  var scale = 2;
  if( sumFieldValues.arguments.length > 2 )
    scale = sumFieldValues.arguments[2];

  var values = new Array( cnt );
  for( var x = 0; x < cnt; x++ )
    values[x] = removeCommas( fields[x].value );
  return( sumValues( values, cnt, scale ) );
}

function isNumeric( strValue ) {
  var re = new RegExp( "^-{0,1}[0-9]+$|^-{0,1}[0-9]+\\.[0-9]*$|^-{0,1}[0-9]*\\.[0-9]+$" );
  strValue = removeCommas( strValue );
  return( re.test( strValue ) );
}
/* END Format numbers */
/* String functions extension */
String.prototype.trim = function() {
  return this.replace( /^\s+|\s+$/g, '' );
}

String.prototype.leftTrim = function() {
  return this.replace( /^\s+/g, '' );
}

String.prototype.rightTrim = function() {
  return this.replace( /\s+$/g, '' );
}
/* end of String functions */
