/*********************************************************
  File: util.js
  Author: Eric B. Wright  
  Description: JavaScript utility functions for working 
    w/ popup windows, select box options, strings and formfields
  Date Last Updated: August 18, 2003  
**********************************************************/

//moves all selected options from one select box to another (appends to end of dest select)
function moveSelectedOptions(from, to) {
  moveOptions(from, to, false);
}

function moveAllOptions(from, to) {
  moveOptions(from, to, true);
}

function moveOptions(from, to, moveAll) {
  to.selectedIndex = -1;
  with (from) {
    for (var i = 0; i < length; ) {
      if (moveAll || options[i].selected) {
	      copyOption(options[i], to);        			
        options[i] = null; //remove option from select
      } else
        i++;
    }
	  selectedIndex = -1;
  }		
}

//  selects all the options in a select box.
function selectAllOptions(selectObj) {
  var len = selectObj.options.length;

  for(var i=0; i<len; i++)
    selectObj.options[i].selected = true;
}

/* This function will take the contents of a select object and generate a delimited string
   Params:
    
   selectObj - req - select obj to marshall
   delim1 - opt - delimiter to separate option values (if not spec. defaults to comma)
   delmi2 - opt - if specified will double delimit the string to include the text of each option
*/
function getSelectObjectAsDelimitedString(selectObj, delim1, delim2) {
  if (!delim1)
    delim1 = ",";
  var str = "";
  with (selectObj) {
    for (var i = 0; i < options.length; i++) {
      if (i != 0)
        str += delim1;
      str += options[i].value;
      if (delim2)
        str += delim2 + options[i].text;        
    }
  }
  return str;
}

//copies single object object from current select box to destination select box
//returns new copy 
function copyOption(option, dest) {
  dest.options[dest.length] = new Option(option.text, option.value, false, true);
  option = null;	
  return dest.options[dest.length - 1];	
}

function addOption(list, text, value) {
  list.options[list.length] = new Option(text, value);
}

function removeOption(list, idx) {
  list.options[idx] = null;
}

function removeSelectedOptions(list) {  
  with (list) {
    for (var i = 0; i < length; ) {
      if (options[i].selected) {	              			
        options[i] = null; //remove option 
      } else
        i++;
    }
	  selectedIndex = -1;
  }		
}

function listContains(list, value) {
  for (var i = 0; i < list.options.length; i++) 
    if (list.options[i].value == value)
      return true;
  
  return false;
}

//retrieve selected value in select obj
function getSelectedValue(selectObj) {
  return getSelectedOption(selectObj).value;  
}

//retrieve selected value in select obj
function getSelectedText(selectObj) {
  return getSelectedOption(selectObj).text;  
}

//retrieve selected option
function getSelectedOption(selectBox) {    
   with (selectBox) {
      return options[selectedIndex];      
   }
}

// ================================================================ //
//  Advanced functions for moving elements within
//  a select box and across multiple select-boxes.
// ================================================================ //

//  moves up all selected options by 1 position.
function moveUpSelectedOptions(selectObj) {
  var len = selectObj.length;
  if(len <= 1 || selectObj.options[0].selected)
    return;

  for(var i=0; i<len; i++) {
    if(selectObj.options[i].selected) {
      swapOldWithNew(selectObj, i, i-1);
    }
  }
}

//  moves down all selected options by 1 position.
function moveDownSelectedOptions(selectObj) {
  var len = selectObj.length;
  if(len <= 1 || selectObj.options[len-1].selected)
    return;

  for(var i=len-2; i>=0; i--) {
    if(selectObj.options[i].selected) {
      swapOldWithNew(selectObj, i, i+1);
    }
  }
}

//  swap option at old index with option at new index.
function swapOldWithNew(object, oldIndex, newIndex) {
  with(object) {
    var newOption     = options[newIndex];
    options[newIndex] = new Option(options[oldIndex].text, options[oldIndex].value);
    options[oldIndex] = new Option(newOption.text, newOption.value);
    options[newIndex].selected = true;
  }
}

//  copies the option to dest. select box @ specified index.
function copyOptionAtIndex(option, dest, idx) {
  for(var i=dest.length; i>idx; i--)  {
    dest.options[i] = new Option(dest.options[i-1].text, dest.options[i-1].value);
  }
  dest.options[idx] = new Option(option.text, option.value, false, true);
}

// ================================================================ //

function getSelectedRadioIndex(radio) {
  for (var i = 0; i < radio.length; i++) {
    if (radio[i].checked)
      return i;
  }
} 

function getSelectedRadioValue(radio) {
  for (var i = 0; i < radio.length; i++) {
    if (radio[i].checked)
      return radio[i].value;
  }
  return "";
} 

//returns a window of specified url, height, and width centered in the screen. Last param is for additional
//window options
function openCenteredWindowWithOptions(url, name, w, h, options) {      
  var x = getCenteredX(w);
  var y = getCenteredY(h);  
  var atts = "height=" + h + ",width=" + w + ",top=" + y + ",left=" + x + ",screenX=" + x + ",screenY=" + y + ",resizable"
  if (options != null)
    atts += "," + options;
  return window.open(url, name, atts);
}

function resizeWindow(w, h) {
  var x = getCenteredX(w);
  var y = getCenteredY(h);
  window.resizeTo(w, h);
  window.moveTo(x, y);
}

function getCenteredX(w) {
  return Math.round((window.screen.width - w) / 2);
}

function getCenteredY(h) {
  return Math.round((window.screen.height - h) / 2);
}

//returns a window of specified url, height and width centered in the screen
function openCenteredWindow(url, name, w, h) {
  return openCenteredWindowWithOptions(url, name, w, h, null);
}

//  swap selected option with option at specified new index
function doSwap(object, newIndex) {
  with(object) {
//    swapOldWithNew(object, selectedIndex, newIndex);
//    selectedIndex = newIndex; //  move selector
    // create swap vars to old item currently occupying that new index
    var swapText  = options[newIndex].text;
    var swapValue = options[newIndex].value;
    options[newIndex].text = options[selectedIndex].text;
    options[newIndex].value = options[selectedIndex].value;
    options[selectedIndex].text = swapText;
    options[selectedIndex].value = swapValue;
    // move selector
    selectedIndex = newIndex;
  }
  return;
}
	
//determines if select object has a selected item and alerts user if not	
function isSelected(object) {
  with (object) {
	  if (selectedIndex == -1) {
	    alert("No item is selected.");
	    return false;
	  } else {
	    return true;
  	}
	}
}

//moves option in specified select box down one slot based on selected index				
function moveDown(selectObj) {  
  with (selectObj) {	  		
    var lastIndex = length - 1;
    //make sure not last item in list and and item is selected
	  if ((selectedIndex != lastIndex) && (isSelected(selectObj))) {
	    //create new index for option
  	  var newIndex = selectedIndex + 1;	
	    doSwap(selectObj, newIndex);		
  	}
	}
  return;
}		

//moves option in specified select box up one slot based on selected index		
function moveUp(selectObj) {
  with (selectObj) {
    //make sure not first item in list and item is selected
		if ((selectedIndex != 0) && (isSelected(selectObj))) {
		  //create new index for option
			var newIndex = selectedIndex - 1;													
			doSwap(selectObj,newIndex);		
		}
	}			
	return;
}

//determines whether selection has been made on a checkbox object or group of 
//checkbox objects
function selectionMade(checkbox) {    
  if (!checkbox.length) //single checkbox
    return checkbox.checked;
    
  for (i = 0; i < checkbox.length; i++) { //multi checkboxes  
	  if (checkbox[i].checked) 
		  return true;
	}
  return false;
}

//  uncheck all selected elements
function uncheckAll(selectObj)  {
    for(var i=0; i<selectObj.length; i++) {
      selectObj.options[i].selected= false;
    }
}

/*
================================================================
DISABLED - since IE 5.0 doesn't like reg expressions
================================================================
*/


// add trim method to the String object 
/*String.prototype.trim = function() {
  // skip leading and trailing whitespace
  // and return everything in between using regular expressions
  var x = this;
  x = x.replace(/^\s*(.*)/, "$1");
  x = x.replace(/(.*?)\s*$/, "$1");
  return x;
}*/

String.prototype.trim = function() {
  var x = this;
  x = trim(x);
  return x;
}

/*
==================================================================
LTrim(string) : Returns a copy of a string without leading spaces.
==================================================================

   PURPOSE: Remove leading blanks from our string.
   IN: str - the string we want to LTrim
*/
function ltrim(str) {
   var whitespace = new String(" \t\n\r");

   var s = new String(str);

   if (whitespace.indexOf(s.charAt(0)) != -1) {
      // We have a string with leading blank(s)...

      var j=0, i = s.length;

      // Iterate from the far left of string until we
      // don't have any more whitespace...
      while (j < i && whitespace.indexOf(s.charAt(j)) != -1)
         j++;

      // Get the substring from the first non-whitespace
      // character to the end of the string...
      s = s.substring(j, i);
   }
   return s;
}

/*
==================================================================
RTrim(string) : Returns a copy of a string without trailing spaces.
==================================================================

   PURPOSE: Remove trailing blanks from our string.
   IN: str - the string we want to RTrim

*/
function rtrim(str) {
   // We don't want to trip JUST spaces, but also tabs,
   // line feeds, etc.  Add anything else you want to
   // "trim" here in Whitespace
   var whitespace = new String(" \t\n\r");

   var s = new String(str);

   if (whitespace.indexOf(s.charAt(s.length-1)) != -1) {
      // We have a string with trailing blank(s)...

      var i = s.length - 1;       // Get length of string

      // Iterate from the far right of string until we
      // don't have any more whitespace...
      while (i >= 0 && whitespace.indexOf(s.charAt(i)) != -1)
         i--;


      // Get the substring from the front of the string to
      // where the last non-whitespace character is...
      s = s.substring(0, i+1);
   }

   return s;
}

/*
=============================================================
Trim(string) : Returns a copy of a string without leading or trailing spaces
=============================================================

   PURPOSE: Remove trailing and leading blanks from our string.
   IN: str - the string we want to Trim

   RETVAL: A Trimmed string!
*/

function trim(str) {
   return rtrim(ltrim(str));
}

//toggle prompt functions
function toggleDatePrompt(form, fldGroup, off, prompts) {      
  if (!prompts) 
   prompts = new Array("MM", "DD", "YY");  
  togglePrompt(form, fldGroup, off, prompts);
}  
  
function toggleTimePrompt(form, fldGroup, off, prompts) {    
  if (!prompts)
    prompts = new Array("hh", "mm");
  togglePrompt(form, fldGroup, off, prompts);
}  
  
function togglePrompt(form, fldGroup, turnOff, prompts) {      
  if (!isFieldChanged(fldGroup)) {    
    with (form) {    
      for (var i = 0; i < prompts.length;  i++) {                                      
        if (turnOff)                        
          eval(fldGroup + i + ".value = '';"); 
        else 
          eval(fldGroup + i + ".value = '" + prompts[i] + "';");           
      }
    }
  }
}

/*
=============================================================
Functions to keep track of form field changes (Form field names
 must be unique!)
=============================================================
*/
  
function setFieldChanged(fld) {
  if (!document.changed) 
    document.changed = new Array();
  document.changed[fld] = true;
}

function isFieldChanged(fld) {  
  if (!document.changed)
    return false;
  else 
    return document.changed[fld];
}

/*
=============================================================
Functions to add/invoke multiple validators (for modular
  client side form validation)
=============================================================
*/

function addValidator(func) {
  if (!document.validators)
    document.validators = new Array();
  document.validators[document.validators.length] = func;  
}

function invokeAllValidators(form) {
  if (!document.validators) 
    return true;

  with (document)
    for (var i = 0; i < validators.length; i++) 
      if (!validators[i](form))
        return false;

  return true;
}
  
    
/* Auto tab if desired length is met (invoke from onkeypress
   attribute of input field) */
function autoTab(currFld, nextFld, desiredLength) {         
  if (!canAutoTab(currFld.name)) {
  	setAutoTabAllow(currFld.name, true); //enable after first key press
	return;
  }	
  if (currFld.value.length == desiredLength)
    nextFld.focus();
}

/* These two functions are for monitoring field selection.
   If field is selected then disable autotab to allow overwrite
   (invoke from onselect attribute of input field)
 */
function setAutoTabAllow(fld, allow) {
  if (!document.autoTabAllow) 
    document.autoTabAllow = new Array();
  document.autoTabAllow[fld] = allow;
}

function canAutoTab(fld) {  
  if (!document.autoTabAllow)
    return true;
  else 
    return document.autoTabAllow[fld];
}
