/*
 * This function does nothing.  Its purpose is to avoid return values
 * for a href's when calling other javascript calls.
 */
function doNothing() {}

var Nav4 = ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) == 4))

// Find and return an element based on the element's name and
// optionally the document it is found in
function getElementByName(name, doc) { 
  var pIdx, idx;
  var returnElem = null;
  if(!doc) doc=document; 
  if ( (pIdx=name.indexOf("?")) > 0 && parent.frames.length ) {
    doc=parent.frames[name.substring(pIdx+1)].document; name=name.substring(0,pIdx);
  }
  if (!(returnElem = doc[name]) && doc.all) returnElem = doc.all[name]; 
  for (idx=0; !returnElem && (idx < doc.forms.length); idx++) returnElem = doc.forms[idx][name];
  for (idx=0; !returnElem && doc.layers && (idx < doc.layers.length); idx++) returnElem = MM_findObj(name,doc.layers[idx].document); 
  return returnElem;
}

/* openWindow
 * Open a new window that looks like an application window
 * as opposed to browser window. i.e. It does not include
 * a menubar, toolbar, etc.
 */
function openWindow(url, windowName, width, height, status, returnWinHandle) {
  var winAttr = new Array()
  // Set defaults
  winAttr["toolbar"] = 0;
  winAttr["menubar"] = 0;
  winAttr["resizable"] = 1;
  winAttr["scrollbars"] = 1;
  winAttr["width"] = 400;
  winAttr["height"] = 400;
  if (width) winAttr["width"] = width;
  if (height) winAttr["height"] = height;
  if (status) winAttr["status"] = status;
  // Try to center on the user's screen
  var left, top, centerAttr;
  if (Nav4) {
    // Center on the main window.
    winAttr["screenX"] = window.screenX + ((window.outerWidth - winAttr["width"]) / 2);
    winAttr["screenY"] = window.screenY + ((window.outerHeight - winAttr["width"]) / 2) - 30;
  } else {
    // The best we can do is center in screen.
    winAttr["left"] = ((screen.width  - winAttr["width"])  / 2);
    winAttr["top"]  = ((screen.height - winAttr["height"]) / 2) - 30;
  } // end if-else
  // Convert attributes array to a string
  var separator = "";
  var winAttrStr = "";
  for (var attr in winAttr) { 
    winAttrStr += separator+attr+"="+winAttr[attr];
    separator = ",";
  } // end for
  var newWin = window.open(url, windowName, winAttrStr);
  newWin.focus();
  if (returnWinHandle) return newWin;
} // openWindow

function closeWindow(showOpener) {
  if (showOpener && window.opener && !window.opener.closed) window.opener.focus();
  window.close();
} // closeWindow

function trimStr(str) { 
  if ( !str ) { return str; }
  // This will get rid of leading spaces 
  while (str.substring(0,1) == ' ') 
    str = str.substring(1, str.length);
  // This will get rid of trailing spaces 
  while (str.substring(str.length-1,str.length) == ' ')
    str = str.substring(0, str.length-1);
  return str;
} // trimStr

/* updateSelectValues
 * This updates the values in the select box values with the 
 * new values array.
 */
function updateSelectValues ( elem, newValues ) {
  var elemObj = document.getElementById( elem );
  if ( elemObj && newValues ) {
    for ( var i = 0; i < newValues.length; i++ ) {
      elemObj.options[i] = newValues[i];
    }
  }
}

/* getElementValue
 * Gets the value of the form element passed in.
 * For example, if the element is a textfield,
 * the value in the textfield is returned.  If the
 * element is a radio button, the value of the selected
 * button is returned.
 * Returns null if no value exists or the element
 * doesn't exist
 */
function getElementValue(element) {
  var returnVal = null;
  if (element != null) {
    if (element.length && element.length > 1) {
      if (element[0].type == "radio") {
        returnVal = getRadioSelectedValue(element);
      } else if (element.type == "select-one") {
        var vals = selectlistToValueArray(element);
        if (vals.length > 0) {
          returnVal = vals[0];
        } // end if
      } // end if-else
    } else {
      returnVal = element.value;
    } // end if-else
  } // end if
  return returnVal;
} // getElementValue




/* setValue
 * Find the given element and set its value.
 */
function setValue ( elem, value) {
  var elemObj = document.getElementById( elem );
  if ( elemObj ) {
    elemObj.value = value;
  }
}

/* goToUrl
 * Redirects to url. 
 */
function goToUrl( url.html ) {
  if ( url ) {
    window.location.href = url;
    return false;
  }
}

function enableRadioField ( enabledFieldValue, formName, radioGroupName ) {
  var radioGroup = document.forms[formName].elements[radioGroupName];
  if ( radioGroup ) {
    for ( i = 0 ; i <  radioGroup.length ; i++ ) {
      if ( radioGroup[i].value == enabledFieldValue ) {
        radioGroup[i].checked = true;
        break;
      }
    }
  }
}

/* getRadioSelectedIndex
 * Find the enabled radio button and return that index.
 * If it cannot find the radio group or there are no
 * selected values, return -1.
 */
function getRadioSelectedIndex( radioGroup ) {
  var selectedIndex = -1;
  if (radioGroup) {
    if (radioGroup.length == 1) {
      selectedIndex = 0;
    } else {
      for ( i = 0 ; i <  radioGroup.length ; i++ ) {
        if ( radioGroup[i].checked ) { 
          selectedIndex = i;
          break;
        }
      }
    } // end if-else
  }
  return selectedIndex;
}

/* getRadioSelectedValue
 * Find the enabled radio button and return the value for that button.
 * If it cannot find the radio group or there are no
 * selected values, return null.
 */
function getRadioSelectedValue( radioGroup ) {
  var returnVal = null;
  if (radioGroup.length == 1) {
    // A single element radio group cannot be treated as an array
    if (radioGroup.checked) returnVal = radioGroup.value;
  } else {
    // Multiple elements in group -> Treat as array
    var selectedIdx = getRadioSelectedIndex(radioGroup);
    if (selectedIdx != -1) returnVal = radioGroup[selectedIdx].value;
  } // end if-else
  return returnVal;
} // getRadioSelectedValue

/* validateRadioButtons
 */
function validateRadioButtons( formName, radioGroupName, validationInfo ) {
  var errorMsg = "";
  var radioGroup = document.forms[formName].elements[radioGroupName];
  var selectedIndex = getRadioSelectedIndex( radioGroup );
  var obj;
  if ( selectedIndex != -1 ) {
    if ( validationInfo[selectedIndex] ) {
    for ( var fieldName in validationInfo[selectedIndex] ) {
      var logicalName = validationInfo[selectedIndex][fieldName]['name'];
      var valStr = validationInfo[selectedIndex][fieldName]['val'];
      if ( fieldName.indexOf('_') == 0 ) {
        errorMsg += validateSpecialInput( formName, fieldName, valStr, logicalName );
      } else {	
      if ( valStr && logicalName) {
        obj = document.getElementsByName( fieldName );
        if ( obj ) {
          obj = obj[0];
          errorMsg += validateValue(valStr.split('_'), obj, logicalName);
        }
      }
      }
    }
  }
}
  return (showError(errorMsg));
}

// Iterates over all options in the input select list and returns an
// array of values of all the selected options
function selectlistToValueArray(selectlistObj) {
  // Determine the selectlist options that are selected, if any
  var valuesArray = new Array();
  var valuesIdx = 0;
  for (var optionIdx = 0; optionIdx < selectlistObj.length; optionIdx++) {
    var optionObj = selectlistObj[optionIdx];
    if (optionObj.selected) {
      valuesArray[valuesIdx++] = optionObj.value;
    }
  }
  return valuesArray;
}

// validateRules
// Validate all the rules based on the template type information.
function validateRules (tableIds, oneRule, checkRuleCount ) {
  var errorMsg = "";
  var ruleTypeTables;
  var totalRuleCount = 0;

  var oneRuleType;
  for ( var ruleType in RULE_VALIDATION_INFO ) {
    //       alert ( "Ruletype: " + ruleType );
    oneRuleType = document.getElementsByName( ruleType );
    //     alert ( "numrules: " + oneRuleType.length );
    totalRuleCount += oneRuleType.length;
    for ( var ruleIndex = 0; ruleIndex < oneRuleType.length; ruleIndex++ ) {
      var inputElements = oneRuleType[ruleIndex].getElementsByTagName( "input" );    
      //      alert( "input count: " + inputElements.length );
      
      for ( var elemIndex = 0; elemIndex < inputElements.length; elemIndex++ ) {
        var pattern = /\[\d+\]\.(\S+)$/;
        var name=pattern.exec(inputElements[elemIndex].name);
        if ( name ) {
          name = name[1];
	  //  	  alert( name + ":" + inputElements[elemIndex].value );
          var valStr = RULE_VALIDATION_INFO[ruleType]['val'][name];
          if ( valStr ) {
            errorMsg += validateValue( valStr.split('_'), inputElements[elemIndex], RULE_VALIDATION_INFO[ruleType]['name'] + " " + (ruleIndex+1) + ": " +  name);
          }
        }
      }  // for ( var elemIndex = 0; 
    }  // for ( var ruleIndex = 0; ruleIndex < oneRuleType.length;
  }  // for ( var ruleType in RULE_VALIDATION_INFO ) {
//  if ( checkRuleCount && (totalRuleCount == 0 ) ) { errorMsg += 'At least one rule must be specified.'; }
  return (showError(errorMsg));
} // validateRules

/* validateFields
 * Run through the form and validate all necessary fields.
 * It first finds a validation check field (identified
 * by its hidden field type and containing '__').
 * Everything prior to the '__' is the validation info
 * and after is the actual field name to validate.
 */
function validateFields ( formName ) {
  var elements;
  if ( formName ) {
    elements = document.forms[formName].elements;
  } else {
    elements = document.forms[0].elements;
  }
  var errorMsg = "";
  if (elements) {
    var elem;
    for ( var i = 0; i < elements.length; i++ ) {
      elem = elements[i];
      if (elem.type == 'hidden') { 
        var dividerIndex = elem.name.indexOf( '__');
        if (dividerIndex != -1) {
          var valStr = elem.name.substring( 0, dividerIndex );
          var fieldName = elem.name.substring( dividerIndex+2, elem.name.length );
          if (valStr && fieldName) {
              if ( valStr.indexOf( '_' ) == 0 ) {
                errorMsg += validateSpecialInput(formName, valStr, fieldName, elem.value, elements );
              } else {
                errorMsg += validateValue(valStr.split( '_' ),  elements[fieldName], elem.value);
              }
          } // end if
        }  // if ( dividerIndex )
      }  // if ( elem.type == 'hidden' )
    } // for ( var i = 0; i < elements.length; i++ )
  }  // if ( elements )
  return (showError(errorMsg));
}

function showError(errorMsg) {
  if (errorMsg && errorMsg != "") {
    alert(errorMsg);
    errorMsg = "";
    return false;
  } else {
    return true;
  } // end if-else
} // showError

function hasError(errorMsg) {
  return (errorMsg && errorMsg != "");
} // hasError

/* validateSpecialInput
 * This is for validating input that requires special handling.
 * For instance, it allows you to compare two dates and alert
 * when one date occurs before another.
 */
function validateSpecialInput( formName, valType, valStr, name, elements  ) {
  var errorMsg = "";
  if ( valType == "_CompDate" ) {
    errorMsg = performDateComparision( formName, valStr, name );
  } else if ( valType == "_CompVal" ) {
    errorMsg = performValueComparison( elements, valStr, name );
  } 
  return errorMsg;
}

/* validateValue
 * Given the validation information and the name of the
 * field to validate, perform validation.
 */
function validateValue(valArr, formObj, logicalName) {
  var errorMsg = "";
  
  var val;
  if (!formObj || !(val=formObj.value)) {
    if (valArr[1] == 'R') errorMsg += logicalName + ' is required\n';
    return errorMsg;
  } // end if
  
  var errorMsg = "";
//  val = trimStr(val);
  switch ( valArr[0] ) {
  case "I":  errorMsg += checkInt(valArr, val, logicalName); break;
  case "Ic": errorMsg += checkIntList(valArr, val, logicalName, ","); break;
  case "F":  errorMsg += checkFloat(valArr, val, logicalName); break;
  case "D":  errorMsg += checkDate(valArr, val, logicalName); break;
  case "MM": errorMsg += checkMinutes(valArr, val, logicalName); break;
  case "IP": errorMsg += checkIP(valArr, val, logicalName); break;
  case "IPM": errorMsg += checkIPM(valArr, val, logicalName); break;
  case "W":  errorMsg += checkWord(valArr, val, logicalName); break;
  case "EMN":  errorMsg += checkEmailNameAddress(val, logicalName ); break;
  case "EM":  errorMsg += checkEmailAddress(val, logicalName ); break;
  case "MEM":  errorMsg += checkMultipleEmailNameAddress(val, logicalName ); break;
  case "0":  ;
  }
  return errorMsg;
}

function checkInt (valArr, val, logicalName) {
  var errorMsg = "";
  var pattern = /^-?\d+$/;
  if (!pattern.test(val)) { 
    errorMsg += logicalName + ' (' + val + ') must be an integer\n';
    return errorMsg;
  } // end if
  
  val = parseInt(val);
  // check min
  if (valArr[2] && valArr[2] != '?') {
    errorMsg = checkMin(val,parseInt(valArr[2]), logicalName);
    if (errorMsg != "") return errorMsg;
  } // end if
  
  // check max
  if (valArr[3] && valArr[3] != '?') {
    errorMsg = checkMax(val,parseInt(valArr[3]), logicalName);
    if (errorMsg != "") return errorMsg;
  } // end if
  return errorMsg;
} // checkInt

function checkIntList(valArr, val, logicalName, delimiter) {
  var errorMsg = "";
  var intList = val.split(delimiter);
  for (var i = 0; i < intList.length; i++) {
    var intVal = intList[i];
    trimStr(intVal);
    errorMsg += checkInt(valArr, intVal, logicalName);
  } // end for
  return errorMsg;
} // checkIntList

function checkFloat (valArr, val, logicalName) {
  var errorMsg = "";
  var pattern = /^-?\d+\.?\d*$|^-?\d*\.?\d+$/;
  
  if (!pattern.test(val)) { 
    errorMsg = logicalName + ' (' + val + ') must be a numeric value\n';
    return errorMsg;
  } // end if
  
  val = parseFloat( val );
  // check min
  if (valArr[2] && valArr[2] != '?') {
    errorMsg = checkMin(val,parseFloat(valArr[2]), logicalName);
    if (errorMsg != "") return errorMsg;
  } // end if
  
  // check max
  if (valArr[3] && valArr[3] != '?') {
    errorMsg = checkMax(val,parseFloat(valArr[3]), logicalName)
    if (errorMsg != "") return errorMsg;
  } // end if
  return errorMsg;
} // checkFloat

/* checkMin
 * Check that the value is greater than the minimum allowed
 * value. If it is not, then add an error message.
 */
function checkMin ( value, min, logicalName ) {
  var errorMsg = "";
  if (value < min) { 
    errorMsg = logicalName + ' (' + value + ') must be greater than or equal to ' + min + '\n'; 
    if (errorMsg != "") return errorMsg;
  } // end if
  return errorMsg;
} // checkMin

/* checkMax
 * Check that the value is greater than the maximum allowed
 * value. If it is not, then add an error message.
 */
function checkMax ( value, max, logicalName ) {
  var errorMsg = "";
  if (value > max) { 
    errorMsg = logicalName + ' (' + value + ') must be less than or equal to ' + max + '\n'; 
    if (errorMsg != "") return errorMsg;
  } // end if
  return errorMsg;
} // checkMax

/* checkMinutes
 * Check that the given input is a valid minutes format (00-59).
 */
function checkMinutes (valArr, val, logicalName ) {
  var errorMsg = '';
  var error = false;
  var pattern = /(\d\d)/;
  var values = pattern.exec(val);
  if ( !values ) {
     error = true;
  } else {
     if ( values[1] < 0 || values[1] > 59 ) { error = true; }
  }
  if ( error ) { errorMsg = logicalName + ' must be between 00-59\n'; }
  return errorMsg;
}

function checkDate(valArr, val, logicalName ) {
  var errorMsg = "";
  var pattern = /(\d?\d)\/(\d?\d)\/(\d\d\d\d)/;
  var values = pattern.exec(val);
  if (!values) {
    errorMsg = logicalName + ' must be of the form mm/dd/yyyy\n';
    if (errorMsg != "") return errorMsg;
  } else {
    if (values[1] < 1 || values[1] > 12) {
      errorMsg = logicalName + ' month must be between 1 and 12\n';
      if (errorMsg != "") return errorMsg;
    }  // end if
    if (values[2] < 1 || values[2] > 31) {
      errorMsg += logicalName + ' day must be between 1 and 31\n';
      if (errorMsg != "") return errorMsg;
    } // end if
    if (values[3] < 2002 || values[3] > 2012) {
      errorMsg += logicalName + ' year must be between 2002 and 2012\n';
      if (errorMsg != "") return errorMsg;
    } // end if
  } // end if-else

  return errorMsg;
} // checkDate

function checkIP (valArr, val, logicalName) {
  var errorMsg = "";
  var pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
  var results = val.match(pattern);
  if (results == null || results.length == 0) { 
    errorMsg += logicalName + ' (' + val + ') must be a valid IP address (eg. 1.2.3.4)\n';
    if (errorMsg != "") return errorMsg;
  } // end if
  for (var i = 0; i < results.length; i++) {
    var ipNum = results[i];
    if (ipNum < 0 || ipNum > 255) {
      errorMsg += "IP address quad numbers must range from 0 to 255 ("+ipNum+" is invalid)\n";
      break;
    } // end if
  } // end for
  return errorMsg;
} // checkIP

function checkIPM (valArr, val, logicalName) {
  var errorMsg = "";
  var pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d+)$/;
  var results = val.match(pattern);
  if (results == null || results.length == 0) { 
    errorMsg += logicalName + ' (' + val + ') must be a valid IP address with a mask (eg. 1.2.3.4/8)\n';
    if (errorMsg != "") return errorMsg;
  } // end if
  for (var i = 0; i < (results.length - 1); i++) {
    var ipNum = results[i];
    if (ipNum < 0 || ipNum > 255) {
      errorMsg += "IP address quad numbers must range from 0 to 255 ("+ipNum+" is invalid)\n";
      break;
    } // end if
  } // end for
  var mask = results[results.length-1];
  if (mask < 0 || mask > 32) {
    errorMsg += "The mask for an IP address must range from 0 to 32 ("+mask+" is invalid)\n";
  } // end if
  return errorMsg;
} // checkIPM

function checkWord (valArr, val, logicalName) {
  var errorMsg = "";
  if (val != null && val != "") {
    var pattern = /^\w+$/;
    if (!pattern.test(val)) { 
      errorMsg = logicalName + ' (' + val + ') can only contain alphanumeric characters (a-z, 0-9) or under_scores.\n';
      if (errorMsg != "") return errorMsg;
    } // end if
    pattern = /^[a-zA-Z]/;
    if (!pattern.test(val)) { 
      errorMsg = logicalName + ' (' + val + ') must start with a letter (a-z).\n';
      if (errorMsg != "") return errorMsg;
    } // end if
  } // end if
  return errorMsg;
} // checkWord

function checkMultipleEmailNameAddress( val, name) {
   var emailAddrArr = val.split( ',' );
   var errorMsg = "";
   for ( var i =0; i < emailAddrArr.length; i++ ) {
      errorMsg += checkEmailNameAddress( trimStr(emailAddrArr[i]), name );
   }
   return errorMsg;
}

function checkEmailNameAddress(val, name) {
  var errors="";
  errors = checkEmailAddress( val, name );
  if ( errors != "" ) {
   errors = "";
   var pattern = /^([\w_\-\.]+)$/;
   if (!pattern.test(val)) {
     errors += name+  " (" + val + ") contains invalid characters for an email address.\n"; 
   }
  }
  return errors;
}

function checkEmailAddress(val, name) {
  var errors="";
  var pattern = /^([\w_\-\.]+)@(([\w\-]+\.)+)[a-zA-Z]{2,4}$/;
  if (!pattern.test(val)) {
    pattern = /^([\w_\-\.]+)@(\d{1,3}\.){3}\d{1,3}$/;
    if (!pattern.test(val)) {
       // allows root@localhost
        pattern = /^([\w_\-\.]+)@([\w\-]+)$/;
	if ( !pattern.test(val) ) {
          errors += name+  " (" + val + ") does not seem to be an appropriate email address format.\n"; 
        }
    }
  }
  return errors;
}

function performDateComparision ( formName, valStr, name ) {
  var dateFields = valStr.split( '_' );
  var dateNames = name.split( '_' );
  var errorMsg = "";
  if ( dateFields.length == 6 ) {
    startDate = getDate( formName, dateFields[0], dateFields[1], dateFields[2] );
    if ( startDate ) {
	endDate = getDate( formName, dateFields[3], dateFields[4], dateFields[5] );
        if ( endDate && ( (endDate - startDate) < 0 ) ) {
           errorMsg = dateNames[0] + " must be later than the " + dateNames[1] + "\n";
        } 
    }
  }
  return ( errorMsg );
}

function performValueComparison ( elements, fieldNames, name ) {
   var fieldNames = fieldNames.split( '-' );
   var maxObj = elements[fieldNames[0]];
   var minObj = elements[fieldNames[1]];
   var errorMsg = "";
   if ( maxObj && minObj ) {
     if ( ( checkFloat( '', maxObj.value, '' ) == "" ) &&
          ( checkFloat( '', minObj.value, '' ) == "" ) ) {
        if ( (maxObj.value - minObj.value) < 0) {
          var names = name.split( '-' );
          errorMsg = names[0] + " must be greater than or equal to " + names[1] + "\n";
        }
     }
   }
   return errorMsg;
}


function getDate( formName, dateField, hourField, minField ) {
  var dateObj = document.forms[formName].elements[dateField];
  var hourObj = document.forms[formName].elements[hourField];
  var minObj = document.forms[formName].elements[minField];
  var dateInMs;
  if ( dateObj && hourObj && minObj ) {
    var pattern = /(\d?\d)\/(\d?\d)\/(\d\d\d\d)/;
    var values = pattern.exec(dateObj.value);
    if (values) {
      var date = new Date( values[3], values[1] - 1, values[2], hourObj.value, minObj.value );     
      if ( date != "NaN" && date != "Invalid" ) { dateInMs = date.getTime(); }
    }
  }
  return dateInMs;
}

function reloadPage(  ) {
  window.location.href = window.location.href;
  return false;
}
