function makeFigure(imgURL, imgFigNo, imgAlt, imgCaption) {
  imgFigNo = (imgFigNo > null) ? "Fig. " + imgFigNo + ': ' : '';
  if (imgCaption == undefined)
    imgCaption = imgAlt;
    
  document.write('<table align=center class=dashbdr>');
  document.write('<tr><td align=center><img src="' + imgURL + '" alt="' + imgFigNo + imgAlt + '"></td></tr>');
  document.write('<tr align=center><td class=titlefine>' + imgFigNo + imgCaption + '</td></tr>');
  document.write('</table>');
}

function makeFigureA(imgAnchor, imgURL, imgFigNo, imgAlt, imgCaption) {
  if (imgAnchor == undefined) {
    makeFigure(imgURL, imgFigNo, imgAlt, imgCaption);
    return false;
  }

  if (imgCaption == undefined)
    imgCaption = imgAlt;
    
  document.write('<table align=center class=dashbdr>');
  document.write('<tr><td align=center><a target="_new" href="' + imgAnchor + '"><img src="' + imgURL + '" alt="Fig. ' + imgFigNo + ': ' + imgAlt + '"></a></td></tr>');
  document.write('<tr align=center><td class=titlefine><a href="' + imgAnchor + '">Fig. ' + imgFigNo + ': ' + imgCaption + '</a></td></tr>');
  document.write('</table>');
}

function getURLVars() {
  this.urlVars=new Array();
  
  var varArray=new Array();
  if (location.search)
    varArray=window.location.search.substr(1).split('&');
    
  for (var i=0; i<varArray.length; i++)
    this.urlVars[i] = varArray[i].split("=");

  return urlVars;
}

function setURLVars() {
  this.count = 0;
  this.names = [];
  // Instantiate this object as "var n = new setURLVars();"
  // This object will take variables passed to the HTML page in the URL
  // and instantiate them as properties of the object.
  // You can then access the variables using the "this.<varName>" syntax.  NOTE: (no <, >)
  // Parameters: none
  // Requires Funct: getURLVars()
  // Input: url string provided by window location
  //
  // Two default properties exist: 
  // count: number of variables read from the URL
  // names: An array of string names of the variables read from the URL
  // Example: var n = new setURLVars(); alert(n.someVar);
  //
  // Please note: URL variables must be in the form of &<variable name>=<value> (no <, >)
  var varArray=getURLVars();
  
  for (var i=0; i<varArray.length; i++) {  
    this.names[i] = varArray[i][0];
    this.count++;
    eval('this.' + varArray[i][0] + '= ' + unescape(varArray[i][1]) + ';');
  }
}

function delay(gap) { /* gap is in millisecs */
  var then,now; then=new Date().getTime();
  now=then;
  while((now-then)<gap) {
    now=new Date().getTime();
  }
}


// openParams
//
// Takes a string URL and an array of strings, constructs
// a target URL string and opens the string in the current window
// 
// inputs: targetURL = string URL to open
//         paramList = an array (list) of string values to pass to the URL
//
// notes:  Does not do syntax checking--be careful of spaces!
function openParams(targetURL, paramList) {
  var paramString=new String();
  var urlString=new String();
  var amp=new String();
  
  for (var i=0; i<paramList.length; i++) {
    paramString += amp + 'v' + i + '=' + paramList[i];
    amp='&';
  }
  
  urlString=targetURL + '?';
  urlString += paramString;
  
  window.open(urlString);
}
  

// imgMasks object
//
// Builds a table, setting the background image to "theImage".
// The one and only TD of the table is an <img> tag, whose name property is
// the same as the background image's src URL.  The object generates
// a method for swapping images of the <img> tag.
//
// inputs: theImage = string URL of an image file (jpg, gif, etc.)
//         maskArray = an array (list) of string URLs to swap in
//
// methods: next = Round-robin style flip to the next image.
//          setMask(maskNo) = set the current mask to maskNo (integer)
//
// notes:  if parameters are empty, background and mask default to nophoto.jpg
//
function imgMasks(theImage, maskArray) {
  this.bgImage = theImage;
  this.masks = maskArray;
  this.imgObj = null;
  this.curMask = 0;
  this.init = imgMasks_init;
  this.next = function() { this.imgObj.src = this.masks[(++this.curMask%this.masks.length)]; }
  this.setMask = function(maskNo) { this.imgObj.src = this.masks[(maskNo != undefined) ? maskNo : 0]; }
  
  this.init();
}
function imgMasks_init() {
  if (this.bgImage == '')
    this.bgImage = '/images/icons/nophoto.gif';
    
  if (this.masks == '')
    this.masks = ['/images/icons/nophoto.gif'];
    
  var canvas=new String();  
  canvas = '<table border=0 align=center class=dashbdr background="' + this.bgImage + '">';
  canvas += '<tr><td align=center><img border=0 src="' + this.masks[0] + '" name="' + this.bgImage + '"></td></tr>';
  canvas += '</table>';
  document.write(canvas); 
  this.imgObj = document.getElementById(this.bgImage);
}

// Navigate to the URL pointed to by the drop-down box, picker
function goExt(picker) {
    var p = document.getElementById(picker);
    Ext = (p.options[p.selectedIndex].value);
    window.location.href = Ext;
}

// Prevent Enter Key From Submitting
function noSubmitOnEnter(functionString) {
    if (window.event.keyCode == 13) {
      if (functionString > '')
        eval(functionString);
    }

    return !(window.event && window.event.keyCode == 13);

}

// String Testing Functions
function isAlphabetic(val) {
  return (val.match(/^[a-zA-Z]+$/) == val);
}

// Global "constants" for the following functions...
var g_punct='`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/? ';
var g_TLDs='.com.net.org.edu.gov.mil.biz.aero.coop.pro.museum.info.name';

function isPunct(val) {
  if (val.length == 1)
    return (g_punct.indexOf(val) >-1)
  else
    return false;
}

function isEmailAddress(val) {
  var m = val.match(/^([a-zA-Z0-9])+([.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+/);
  if (m == null)
    return false;
  else
    return m[0] == val;
}

function isTLD(val) {
  return (g_TLDs.indexOf(val)>-1);
}

function isInteger(val) {
  return (val.match(/^[0-9]+$/) == val);
}

function isFloat(val) {
  return (val.match(/^[0-9]+\.[0-9]*$/) == val);
}

function isNumber(val) {
  return (isInteger(val) || isFloat(val));
}

function countCaps(val) {
  if (val.length == 0) return 0;
  var c=0;
  var b='';
  for (var i=0; i<val.length; i++) {
    b=val.charAt(i);
    if (b.match(/^[A-Z]$/) == b)
      c++;
  }
  return c;
}

function countLowercase(val) {
  if (val.length == 0) return 0;
  var c=0;
  var b='';
  for (var i=0; i<val.length; i++) {
    b=val.charAt(i);
    if (b.match(/^[a-z]$/) == b)
      c++;
  }
  return c;
}

function countNumbers(val) {
  if (val.length == 0) return 0;
  var c=0;
  var b='';
  for (var i=0; i<val.length; i++) {
    b=val.charAt(i);
    if (b.match(/^[0-9]$/) == b)
      c++;
  }
  return c;
}

function countPunct(val) {
  if (val.length == 0) return 0;
  var c=0;
  var b='';
  for (var i=0; i<val.length; i++) {
    b=val.charAt(i);
    if (g_punct.indexOf(b)>-1)
      c++;
  }
  return c;
}

// Keyboard Trapping Object
//
// Captures keystrokes in the current window and changes the URL to a specified value
//
// Usage:
//   var k=new keytrap;
// Methods:
//   addkey = adds an entry to the list of keys to trap.
//            the "script" is valid Javascript that is eval'd                   Syntax: k.addkey(letter, script);
//   enable = enables key trapping.                                             Syntax: k.enable();
//   disable = disables key trapping.                                           Syntax: k.disable();
// Notes:
//   Because of the way events are processed, you can use only one keytrapper at a time.
var keytrapParent=null;
function keytrap() {
  this.keyset=new Array();
  this.getkey=keytrap_getkey;
  this.addkey=keytrap_add;
  this.isenabled=keytrap_isenabled;
  this.enable=keytrap_enable;
  this.disable=keytrap_disable;
  keytrapParent=this;
}
function keytrap_getkey(keyStroke) {
  isNetscape=(document.layers);
  // Cross-browser key capture routine courtesy
  // of Randy Bennett (rbennett@thezone.net)
  eventChooser = (isNetscape) ? keyStroke.which : event.keyCode;
  which = String.fromCharCode(eventChooser).toLowerCase();

  if (keytrapParent.keyset[which] != null)
    eval(keytrapParent.keyset[which]);
}
function keytrap_add(aKey, someCode) {
  this.keyset[aKey]=someCode;
}
function keytrap_isenabled() {
  return (document.onkeypress != null);
}
function keytrap_enable() {
  document.onkeypress=keytrap_getkey;
}
function keytrap_disable() {
  document.onkeypress=null;
}

// End Keyboard Trapping Object


// Smart Drop Down List Object
//
// Use this object to make your <form>'s drop down list behave more elegantly.
// Features:
//   1. Automatically redirects to the URL specified by the value="" property of your <select> tag
//       whenever the user selects an item in the list.  This is in line with the onChange event.
//   2. Allows the user to use cursor keys to manually select an item in the list, accepting 
//       the selection only on [ENTER].  Many pages use the onChange event to trigger their redirect.  
//       OnChange events happen each time the [DOWN] arrow is pressed, making it impossible to select 
//       an item using the cursor keys.
//   3. Allows for the use of a "submit" type button (or event) outside the form.
//
// Usage:
//   <script>var sddl = new smartDropDownList('theDropDownName');<//script>
//   <FORM action="whatever" method="post" onMouseUp="sddl.mouseUp();">
//     <SELECT name="theDropDownName" id="theDropDownName" onChange="sddl.change();" onFocus="sddl.focus();" onKeyPress="sddl.keyPress(event);">  
//       <OPTION value="" selected>Select One</OPTION> 
//       ...
//     </SELECT>&nbsp;<INPUT type="button" value="Yadda" onClick="sddl.submit();">
//   </FORM>
//
// Methods:
//   mouseUp = trigger when the mouse clicks on the form                              Syntax: sddl.mouseUp();
//   change = trigger when the form changes (click the ddl, select an item, etc.)     Syntax: sddl.change();
//   focus = trigger when the form receives the focus (is clicked on, or highlighted) Syntax: sddl.focus();
//   keyPress = trigger when a key is pressed within the form                         Syntax: sddl.keyPress(); 
//   submit = execute this method when you wish to submit the form                    Syntax: sddl.submit();
//   enable = enables smart submit event                                              Syntax: sddl.enable();
//   disable = disables smart submit event.                                           Syntax: sddl.disable();
// Notes:
//   This can be attached to any number of forms on the page
//   null, empty and undefined values in the <option> tag are ignored (use these to make comments)
//   You can also leave off the <form> tag and replace it with a <span> tag instead
  function smartDropDownList(formname) {
    this.formname = formname;            // access the form thru this _string_
    this.enabled = true;                 // can we go?
    this.hasClicked = false;             // detect a mouseclick
    this.action = '';                    // the javascript to execute on submit
    this.enable = function() { this.enabled = true; }
    this.disable = function() { this.enabled = false; }
    this.isEnabled = function() { return this.enabled; }
    this.submit = sDDL_submit;           // use this method to kick off "submit"
    this.focus = sDDL_focus;             // use this method when the selector gets focus
    this.mouseUp = sDDL_mouseUp;         // this method analyzes mouse clicks
    this.keyPress = sDDL_keyPress;       // this method analyzes keypresses 
    this.change = sDDL_change;           // this method analyzes how the selector changes in the list
  }
  function sDDL_submit() {               // Not really a "submit", it just changes the href
    this.hasClicked=false;               // reset catcher
    if ((this.formname) && (this.enabled)) { // the form is available and active
      var f = document.getElementById(this.formname);
      if ((f.value != "") && (f.value != null) && (f.value != undefined)) {
        if (this.action == '')
          document.location.href=f.value // this could be changed to eval() some code if preferred
        else
          eval(this.action);
      }
    }
  }
  function sDDL_focus() {
    this.hasClicked=false;                // each time we click back on the form, it resets our click catcher
  }

  function sDDL_mouseUp() {
    this.hasClicked = true;               // if a click happens before a change event, we know the user has selected an item
  }
  
  function sDDL_keyPress(e) {             // analyzes the keycode sent to the form.  If CRLF, it "submits"
    var kC = (e.which != null) ? e.which : e.keyCode;           
    if (kC==13)
      this.submit();
  }
  
  function sDDL_change() {                // Every click and keypress on the drop down is a change event
    if (this.hasClicked)                  // This ensures the user is clicking mouse before we just "submit"
    this.submit();
  }

// End Smart Drop Down List Object

function costFormat(costRaw) {
  j = 0;
    var tempCost = '';
    var costOut = '';
    for (i = costRaw.length-1; i >= 0; i--) {
      tempCost += costRaw.charAt(i);
        j++;
        if ((j == 3) && (i != 0)) {
          tempCost += ',';
            j = 0;
        }
    }
    tempCost += '$'
    for (i = tempCost.length-1; i >= 0; i--)
    costOut += tempCost.charAt(i);
    return(costOut);
}

function dateFormat(dateRaw, style) {
  var year = dateRaw.substring(0,4);
  var month = dateRaw.substring(4,6);
  var day = dateRaw.substring(6,8);
  switch (month) {
    case "01" : month = "January"; break;
    case "02" : month = "February"; break;
    case "03" : month = "March"; break;
    case "04" : month = "April"; break;
    case "05" : month = "May"; break;
    case "06" : month = "June"; break;
    case "07" : month = "July"; break;
    case "08" : month = "August"; break;
    case "09" : month = "September"; break;
    case "10" : month = "October"; break;
    case "11" : month = "November"; break;
    case "12" : month = "December"; break;
  }
  switch (style) {
    case "mmmmmddyyyy" : return(month + " " + day + ", " + year); break;
    case "mmmmmyyyy" : return(month + " " + year); break;
  }
}

function extractDate(dateRaw, target) {
  if (dateRaw != null) {
      switch (target) {
          case "year" : return(dateRaw.substring(0,4)); break;
            case "month" : 
              switch (dateRaw.substring(4,6)) {
              case "01" : return("January"); break;
                case "02" : return("February"); break;
            case "03" : return("March"); break;
                case "04" : return("April"); break;
                case "05" : return("May"); break;
                case "06" : return("June"); break;
            case "07" : return("July"); break;
                case "08" : return("August"); break;
                case "09" : return("September"); break;
                case "10" : return("October"); break;
                case "11" : return("November"); break;
                case "12" : return("December"); break;
                };
            break;
            case "monthRaw" : return(dateRaw.substring(4,6)); break;
            case "day" : return(dateRaw.substring(6,8)); break;
        }
    }
    else
      return null;
}    


function countDownURL(theCounter, theTime, theURL) {
// Counts down theTime seconds, displays to theCounter (a named span) and then redirects to theURL
// theCounter: string name of an HTML element on the page that can take .innerHTML changes
// theTime: time in seconds before redirect
// theURL: the URL to redirect to
  document.getElementById(theCounter).innerHTML = theTime;
  if (theTime > 0)
    setTimeout('countDownURL("' + theCounter + '", ' + --theTime + ', "' + theURL + '")', 1000)
  else
    window.location = theURL;
}