// -----------------------------------------------------------------------
// This file is part of AROUNDMe
//
// Copyright (C) 2003, 2005 Barnraiser
// http://www.barnraiser.org/
// info@barnraiser.org
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option) any
// later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with program; see the file COPYING. If not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
// -----------------------------------------------------------------------

//puts browser window at top (out of frames) - stops bug with registering from inside hotmail frame.

if (self != top){
   if (document.images) top.location.replace(document.location.href);
   else top.location.href = document.location.href;
}




var myWindow;

function launchPopupWindow(page, name, customise, alignrightwidth) {
  if(myWindow && !myWindow.closed) {
      myWindow.close();
  }

  var winMargin = 10;

  if (alignrightwidth) {
    customise = customise + ',left='+((parseInt(screen.availWidth)-alignrightwidth)-winMargin);
    customise = customise + ',top='+winMargin;
  }

  myWindow = window.open(page,name,customise);
  myWindow.focus();
}




function objShowHide(id, state) {
  if (document.getElementById) {
    document.getElementById(id).style.display = state;
  }
  else {
    if (document.layers) {
      document.id.visibility = state;
    }
    else { // IE 4
      document.all.id.style.display = state;
    }
  }
}


function disable_object(elem_id)
  {
  document.getElementById(elem_id).disabled=true
  }

/**
 * Copyright (c)2005-2007 Matt Kruse (javascripttoolbox.com)
 *
 * Dual licensed under the MIT and GPL licenses.
 * This basically means you can use this code however you want for
 * free, but don't claim to have written it yourself!
 * Donations always accepted: http://www.JavascriptToolbox.com/donate/
 *
 * Please do not link to the .js files on javascripttoolbox.com from
 * your site. Copy the files locally to your server instead.
 *
 */
// Constructor
function CheckBoxGroup() {
  this.controlBox=null;
  this.controlBoxChecked=null;
  this.maxAllowed=null;
  this.maxAllowedMessage=null;
  this.masterBehavior="all";
  this.formRef=null;
  this.checkboxWildcardNames=new Array();
  this.checkboxNames=new Array();
  this.totalBoxes=0;
  this.totalSelected=0;
  // Public methods
  this.setControlBox=CBG_setControlBox;
  this.setMaxAllowed=CBG_setMaxAllowed;
  this.setMasterBehavior=CBG_setMasterBehavior;  // all, some
  this.addToGroup=CBG_addToGroup;
  // Private methods
  this.expandWildcards=CBG_expandWildcards;
  this.addWildcardCheckboxes=CBG_addWildcardCheckboxes;
  this.addArrayCheckboxes=CBG_addArrayCheckboxes;
  this.addSingleCheckbox=CBG_addSingleCheckbox;
  this.check=CBG_check;
  }

CheckBoxGroup.$VERSION = 1.01;

// Set the master control checkbox name
function CBG_setControlBox(name) { this.controlBox=name; }

// Set the maximum number of checked boxes in the set, and optionally
// the message to popup when the max is reached.
function CBG_setMaxAllowed(num,msg) {
  this.maxAllowed=num;
  if (msg!=null&&msg!="") { this.maxAllowedMessage=msg; }
  }

// Set the behavior for the checkbox group master checkbox
//  All: all boxes must be checked for the master to be checked
//  Some: one or more of the boxes can be checked for the master to be checked
function CBG_setMasterBehavior(b) { this.masterBehavior = b.toLowerCase(); }

// Add checkbox wildcards to the checkboxes array
function CBG_addToGroup() {
  if (arguments.length>0) {
    for (var i=0;i<arguments.length;i++) {
      this.checkboxWildcardNames[this.checkboxWildcardNames.length]=arguments[i];
      }
    }
  }

// Expand the wildcard checkbox names given in the addToGroup method
function CBG_expandWildcards() {
  if (this.formRef==null) {alert("ERROR: No form element has been passed.  Cannot extract form name!"); return false; }
  for (var i=0; i<this.checkboxWildcardNames.length;i++) {
    var n = this.checkboxWildcardNames[i];
    var el = this.formRef[n];
    if (n.indexOf("*")!=-1) { this.addWildcardCheckboxes(n); }
    else if(CBG_nameIsArray(el)) { this.addArrayCheckboxes(n); }
    else { this.addSingleCheckbox(el); }
    }
  }


// Add checkboxes to the group which match a pattern
function CBG_addWildcardCheckboxes(name) {
  var i=name.indexOf("*");
  if ((i==0) || (i==name.length-1)) {
    var searchString= (i)?name.substring(0,name.length-1):name.substring(1,name.length);
    var els = this.formRef.elements;
    var l = els.length;
    for (var j=0;j<l;j++) {
      var currentElement = els[j];
      if (currentElement.type && currentElement.type=="checkbox" && currentElement.name) {
        var currentElementName=currentElement.name;
        var partialName = (i)?currentElementName.substring(0,searchString.length) : currentElementName.substring(currentElementName.length-searchString.length,currentElementName.length);
        if (partialName==searchString) {
          if(CBG_nameIsArray(currentElement)) this.addArrayCheckboxes(currentElement);
          else this.addSingleCheckbox(currentElement);
          }
        }
      }
    }
  }

// Add checkboxes to the group which all have the same name
function CBG_addArrayCheckboxes(name) {
  if((CBG_nameIsArray(this.formRef[name])) && (this.formRef[name].length>0)) {
    for (var i=0; i<this.formRef[name].length; i++) { this.addSingleCheckbox(this.formRef[name][i]); }
    }
  }

function CBG_addSingleCheckbox(obj) {
  if (obj != this.formRef[this.controlBox]) {
    this.checkboxNames[this.checkboxNames.length]=obj;
    this.totalBoxes++;
    if (obj.checked) {
      this.totalSelected++;
      }
    }
  }

// Runs whenever a checkbox in the group is clicked
function CBG_check(obj) {
  var checked=obj.checked;
  if (this.formRef==null) {
    this.formRef=obj.form;
    this.expandWildcards();
    if (this.controlBox==null || obj.name!=this.controlBox) {
      this.totalSelected += (checked)?-1:1;
      }
    }
  if (this.controlBox!=null&&obj.name==this.controlBox) {
    if (this.masterBehavior=="all") {
      for (i=0;i<this.checkboxNames.length;i++) { this.checkboxNames[i].checked=checked; }
      this.totalSelected=(checked)?this.checkboxNames.length:0;
      }
    else {
      if (!checked) {
        obj.checked = (this.totalSelected>0)?true:false;
        obj.blur();
        }
      }
    }
  else {
    if (this.masterBehavior=="all" && this.controlBox!=null) {
      if (!checked) {
        this.formRef[this.controlBox].checked=false;
        this.totalSelected--;
        }
      else { this.totalSelected++; }
      if (this.controlBox!=null) {
        this.formRef[this.controlBox].checked=(this.totalSelected==this.totalBoxes)?true:false;
        }
      }
    else {
      if (!obj.checked) { this.totalSelected--; }
      else { this.totalSelected++; }
      if (this.controlBox!=null) {
        this.formRef[this.controlBox].checked=(this.totalSelected>0)?true:false;
        }
      if (this.maxAllowed!=null) {
        if (this.totalSelected>this.maxAllowed) {
          obj.checked=false;
          this.totalSelected--;
          if (this.maxAllowedMessage!=null) { alert(this.maxAllowedMessage); }
          return false;
          }
        }
      }
    }
  }

function CBG_nameIsArray(obj) {
  return ((typeof obj.type!="string")&&(obj.length>0)&&(obj[0]!=null)&&(obj[0].type=="checkbox"));
  }



** 
 * Copyright (c)2005-2008 Matt Kruse (javascripttoolbox.com)
 * 
 * Dual licensed under the MIT and GPL licenses. 
 * This basically means you can use this code however you want for
 * free, but don't claim to have written it yourself!
 * Donations always accepted: http://www.JavascriptToolbox.com/donate/
 * 
 * Please do not link to the .js files on javascripttoolbox.com from
 * your site. Copy the files locally to your server instead.
 * 
 */
// Global objects to keep track of DynamicOptionList objects created on the page
var dynamicOptionListCount=0;
var dynamicOptionListObjects = new Array();

// Init call to setup lists after page load. One call to this function sets up all lists.
function initDynamicOptionLists() {
ÊÊ// init each DynamicOptionList object
ÊÊfor (var i=0; i<dynamicOptionListObjects.length; i++) {
ÊÊÊÊvar dol = dynamicOptionListObjects[i];

ÊÊÊÊ// Find the form associated with this list
ÊÊÊÊif (dol.formName!=null) { 
ÊÊÊÊÊÊdol.form = document.forms[dol.formName];
ÊÊÊÊ}
ÊÊÊÊelse if (dol.formIndex!=null) {
ÊÊÊÊÊÊdol.form = document.forms[dol.formIndex];
ÊÊÊÊ}
ÊÊÊÊelse {
ÊÊÊÊÊÊ// Form wasn't set manually, so go find it!
ÊÊÊÊÊÊ// Search for the first form element name in the lists
ÊÊÊÊÊÊvar name = dol.fieldNames[0][0];
ÊÊÊÊÊÊfor (var f=0; f<document.forms.length; f++) {
ÊÊÊÊÊÊÊÊif (typeof(document.forms[f][name])!="undefined") {
ÊÊÊÊÊÊÊÊÊÊdol.form = document.forms[f];
ÊÊÊÊÊÊÊÊÊÊbreak;
ÊÊÊÊÊÊÊÊ}
ÊÊÊÊÊÊ}
ÊÊÊÊÊÊif (dol.form==null) {
ÊÊÊÊÊÊÊÊalert("ERROR: Couldn't find form element "+name+" in any form on the page! Init aborted"); return;
ÊÊÊÊÊÊ}
ÊÊÊÊ}

ÊÊÊÊ// Form is found, now set the onchange attributes of each dependent select box
ÊÊÊÊfor (var j=0; j<dol.fieldNames.length; j++) {
ÊÊÊÊÊÊ// For each set of field names...
ÊÊÊÊÊÊfor (var k=0; k<dol.fieldNames[j].length-1; k++) {
ÊÊÊÊÊÊÊÊ// For each field in the set...
ÊÊÊÊÊÊÊÊvar selObj = dol.form[dol.fieldNames[j][k]];
ÊÊÊÊÊÊÊÊif (typeof(selObj)=="undefined") { alert("Select box named "+dol.fieldNames[j][k]+" could not be found in the form. Init aborted"); return; }
ÊÊÊÊÊÊÊÊ// Map the HTML options in the first select into the options we created
ÊÊÊÊÊÊÊÊif (k==0) {
ÊÊÊÊÊÊÊÊÊÊif (selObj.options!=null) {
ÊÊÊÊÊÊÊÊÊÊÊÊfor (l=0; l<selObj.options.length; l++) {
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊvar sopt = selObj.options[l];
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊvar m = dol.findMatchingOptionInArray(dol.options,sopt.text,sopt.value,false);
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊif (m!=null) {
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊvar reselectForNN6 = sopt.selected;
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊvar m2 = new Option(sopt.text, sopt.value, sopt.defaultSelected, sopt.selected);
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊm2.selected = sopt.selected; // For some reason I need to do this to make NN4 happy
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊm2.defaultSelected = sopt.defaultSelected;
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊm2.DOLOption = m;
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊselObj.options[l] = m2;
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊselObj.options[l].selected = reselectForNN6; // Reselect this option for NN6 to be happy. Yuck.
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊ}
ÊÊÊÊÊÊÊÊÊÊÊÊ}
ÊÊÊÊÊÊÊÊÊÊ}
ÊÊÊÊÊÊÊÊ}
ÊÊÊÊÊÊÊÊif (selObj.onchange==null) {
ÊÊÊÊÊÊÊÊÊÊ// We only modify the onChange attribute if it's empty! Otherwise do it yourself in your source!
ÊÊÊÊÊÊÊÊÊÊselObj.onchange = new Function("dynamicOptionListObjects["+dol.index+"].change(this)");
ÊÊÊÊÊÊÊÊ}
ÊÊÊÊÊÊ}
ÊÊÊÊ}
ÊÊ}
ÊÊ// Set the preselectd options on page load 
ÊÊresetDynamicOptionLists();
}

// This function populates lists with the preselected values. 
// It's pulled out into a separate function so it can be hooked into a 'reset' button on a form
// Optionally passed a form object which should be the only form reset
function resetDynamicOptionLists(theform) {
ÊÊ// reset each DynamicOptionList object
ÊÊfor (var i=0; i<dynamicOptionListObjects.length; i++) {
ÊÊÊÊvar dol = dynamicOptionListObjects[i];
ÊÊÊÊif (typeof(theform)=="undefined" || theform==null || theform==dol.form) {
ÊÊÊÊÊÊfor (var j=0; j<dol.fieldNames.length; j++) {
ÊÊÊÊÊÊÊÊdol.change(dol.form[dol.fieldNames[j][0]],true); // Second argument says to use preselected values rather than default values
ÊÊÊÊÊÊ}
ÊÊÊÊ}
ÊÊ}
}

// An object to represent an Option() but just for data-holding
function DOLOption(text,value,defaultSelected,selected) {
ÊÊthis.text = text;
ÊÊthis.value = value;
ÊÊthis.defaultSelected = defaultSelected;
ÊÊthis.selected = selected;
ÊÊthis.options = new Array(); // To hold sub-options
ÊÊreturn this;
}

// DynamicOptionList CONSTRUCTOR
function DynamicOptionList() {
ÊÊthis.form = null;// The form this list belongs to
ÊÊthis.options = new Array();// Holds the options of dependent lists
ÊÊthis.longestString = new Array();// Longest string that is currently a potential option (for Netscape)
ÊÊthis.numberOfOptions = new Array();// The total number of options that might be displayed, to build dummy options (for Netscape)
ÊÊthis.currentNode = null;// The current node that has been selected with forValue() or forText()
ÊÊthis.currentField = null;// The current field that is selected to be used for setValue()
ÊÊthis.currentNodeDepth = 0;// How far down the tree the currentNode is
ÊÊthis.fieldNames = new Array();// Lists of dependent fields which use this object
ÊÊthis.formIndex = null;// The index of the form to associate with this list
ÊÊthis.formName = null;// The name of the form to associate with this list
ÊÊthis.fieldListIndexes = new Object();// Hold the field lists index where fields exist
ÊÊthis.fieldIndexes = new Object();// Hold the index within the list where fields exist
ÊÊthis.selectFirstOption = true;// Whether or not to select the first option by default if no options are default or preselected, otherwise set the selectedIndex = -1
ÊÊthis.numberOfOptions = new Array();// Store the max number of options for a given option list
ÊÊthis.longestString = new Array();// Store the longest possible string 
ÊÊthis.values = new Object(); // Will hold the preselected values for fields, by field name
ÊÊ
ÊÊ// Method mappings
ÊÊthis.forValue = DOL_forValue;
ÊÊthis.forText = DOL_forText;
ÊÊthis.forField = DOL_forField;
ÊÊthis.forX = DOL_forX;
ÊÊthis.addOptions = DOL_addOptions;
ÊÊthis.addOptionsTextValue = DOL_addOptionsTextValue;
ÊÊthis.setDefaultOptions = DOL_setDefaultOptions;
ÊÊthis.setValues = DOL_setValues;
ÊÊthis.setValue = DOL_setValues;
ÊÊthis.setFormIndex = DOL_setFormIndex;
ÊÊthis.setFormName = DOL_setFormName;
ÊÊthis.printOptions = DOL_printOptions;
ÊÊthis.addDependentFields = DOL_addDependentFields;
ÊÊthis.change = DOL_change;
ÊÊthis.child = DOL_child;
ÊÊthis.selectChildOptions = DOL_selectChildOptions;
ÊÊthis.populateChild = DOL_populateChild;
ÊÊthis.change = DOL_change;
ÊÊthis.addNewOptionToList = DOL_addNewOptionToList;
ÊÊthis.findMatchingOptionInArray = DOL_findMatchingOptionInArray;

ÊÊ// Optionally pass in the dependent field names
ÊÊif (arguments.length > 0) {
ÊÊÊÊ// Process arguments and add dependency groups
ÊÊÊÊfor (var i=0; i<arguments.length; i++) {
ÊÊÊÊÊÊthis.fieldListIndexes[arguments[i].toString()] = this.fieldNames.length;
ÊÊÊÊÊÊthis.fieldIndexes[arguments[i].toString()] = i;
ÊÊÊÊ}
ÊÊÊÊthis.fieldNames[this.fieldNames.length] = arguments;
ÊÊ}
ÊÊ
ÊÊ// Add this object to the global array of dynamicoptionlist objects
ÊÊthis.index = window.dynamicOptionListCount++;
ÊÊwindow["dynamicOptionListObjects"][this.index] = this;
}

// Given an array of Option objects, search for an existing option that matches value, text, or both
function DOL_findMatchingOptionInArray(a,text,value,exactMatchRequired) {
ÊÊif (a==null || typeof(a)=="undefined") { return null; }
ÊÊvar value_match = null; // Whether or not a value has been matched
ÊÊvar text_match = null; // Whether or not a text has been matched
ÊÊfor (var i=0; i<a.length; i++) {
ÊÊÊÊvar opt = a[i];
ÊÊÊÊ// If both value and text match, return it right away
ÊÊÊÊif (opt.value==value && opt.text==text) { return opt; }
ÊÊÊÊif (!exactMatchRequired) {
ÊÊÊÊÊÊ// If value matches, store it until we complete scanning the list
ÊÊÊÊÊÊif (value_match==null && value!=null && opt.value==value) {
ÊÊÊÊÊÊÊÊvalue_match = opt;
ÊÊÊÊÊÊ}
ÊÊÊÊÊÊ// If text matches, store it for later
ÊÊÊÊÊÊif (text_match==null && text!=null && opt.text==text) {
ÊÊÊÊÊÊÊÊtext_match = opt;
ÊÊÊÊÊÊ}
ÊÊÊÊ}
ÊÊ}
ÊÊreturn (value_match!=null)?value_match:text_match;
}

// Util function used by forValue and forText
function DOL_forX(s,type) {
ÊÊif (this.currentNode==null) { this.currentNodeDepth=0; }
ÊÊvar useNode = (this.currentNode==null)?this:this.currentNode;
ÊÊvar o = this.findMatchingOptionInArray(useNode["options"],(type=="text")?s:null,(type=="value")?s:null,false);
ÊÊif (o==null) {
ÊÊÊÊo = new DOLOption(null,null,false,false);
ÊÊÊÊo[type] = s;
ÊÊÊÊuseNode.options[useNode.options.length] = o;
ÊÊ}
ÊÊthis.currentNode = o;
ÊÊthis.currentNodeDepth++;
ÊÊreturn this;
}

// Set the portion of the list structure that is to be used by a later operation like addOptions
function DOL_forValue(s) { return this.forX(s,"value"); }

// Set the portion of the list structure that is to be used by a later operation like addOptions
function DOL_forText(s) { return this.forX(s,"text"); }

// Set the field to be used for setValue() calls
function DOL_forField(f) { this.currentField = f; return this; }

// Create and add an option to a list, avoiding duplicates
function DOL_addNewOptionToList(a, text, value, defaultSelected) {
ÊÊvar o = new DOLOption(text,value,defaultSelected,false);
ÊÊ// Add the option to the array
ÊÊif (a==null) { a = new Array(); }
ÊÊfor (var i=0; i<a.length; i++) {
ÊÊÊÊif (a[i].text==o.text && a[i].value==o.value) {
ÊÊÊÊÊÊif (o.selected) { 
ÊÊÊÊÊÊÊÊa[i].selected=true;
ÊÊÊÊÊÊ}
ÊÊÊÊÊÊif (o.defaultSelected) {
ÊÊÊÊÊÊÊÊa[i].defaultSelected = true;
ÊÊÊÊÊÊ}
ÊÊÊÊÊÊreturn a;
ÊÊÊÊ}
ÊÊ}
ÊÊa[a.length] = o;
}

// Add sub-options to the currently-selected node, with the same text and value for each option
function DOL_addOptions() {
ÊÊif (this.currentNode==null) { this.currentNode = this; }
ÊÊif (this.currentNode["options"] == null) { this.currentNode["options"] = new Array(); }
ÊÊfor (var i=0; i<arguments.length; i++) {
ÊÊÊÊvar text = arguments[i];
ÊÊÊÊthis.addNewOptionToList(this.currentNode.options,text,text,false);
ÊÊÊÊif (typeof(this.numberOfOptions[this.currentNodeDepth])=="undefined") {
ÊÊÊÊÊÊthis.numberOfOptions[this.currentNodeDepth]=0;
ÊÊÊÊ}
ÊÊÊÊif (this.currentNode.options.length > this.numberOfOptions[this.currentNodeDepth]) {
ÊÊÊÊÊÊthis.numberOfOptions[this.currentNodeDepth] = this.currentNode.options.length;
ÊÊÊÊ}
ÊÊÊÊif (typeof(this.longestString[this.currentNodeDepth])=="undefined" || (text.length > this.longestString[this.currentNodeDepth].length)) {
ÊÊÊÊÊÊthis.longestString[this.currentNodeDepth] = text;
ÊÊÊÊ}
ÊÊ}
ÊÊthis.currentNode = null;
ÊÊthis.currentNodeDepth = 0;
}

// Add sub-options to the currently-selected node, specifying separate text and values for each option
function DOL_addOptionsTextValue() {
ÊÊif (this.currentNode==null) { this.currentNode = this; }
ÊÊif (this.currentNode["options"] == null) { this.currentNode["options"] = new Array(); }
ÊÊfor (var i=0; i<arguments.length; i++) {
ÊÊÊÊvar text = arguments[i++];
ÊÊÊÊvar value = arguments[i];
ÊÊÊÊthis.addNewOptionToList(this.currentNode.options,text,value,false);
ÊÊÊÊif (typeof(this.numberOfOptions[this.currentNodeDepth])=="undefined") {
ÊÊÊÊÊÊthis.numberOfOptions[this.currentNodeDepth]=0;
ÊÊÊÊ}
ÊÊÊÊif (this.currentNode.options.length > this.numberOfOptions[this.currentNodeDepth]) {
ÊÊÊÊÊÊthis.numberOfOptions[this.currentNodeDepth] = this.currentNode.options.length;
ÊÊÊÊ}
ÊÊÊÊif (typeof(this.longestString[this.currentNodeDepth])=="undefined" || (text.length > this.longestString[this.currentNodeDepth].length)) {
ÊÊÊÊÊÊthis.longestString[this.currentNodeDepth] = text;
ÊÊÊÊ}
ÊÊ}
ÊÊthis.currentNode = null;
ÊÊthis.currentNodeDepth = 0;
}

// Find the first dependent list of a select box
// If it's the last list in a chain, return null because there are no children
function DOL_child(obj) {
ÊÊvar listIndex = this.fieldListIndexes[obj.name];
ÊÊvar index = this.fieldIndexes[obj.name];
ÊÊif (index < (this.fieldNames[listIndex].length-1)) {
ÊÊÊÊreturn this.form[this.fieldNames[listIndex][index+1]];
ÊÊ}
ÊÊreturn null;
}

// Set the options which should be selected by default for a certain value in the parent
function DOL_setDefaultOptions() {
ÊÊif (this.currentNode==null) { this.currentNode = this; }
ÊÊfor (var i=0; i<arguments.length; i++) {
ÊÊÊÊvar o = this.findMatchingOptionInArray(this.currentNode.options,null,arguments[i],false);
ÊÊÊÊif (o!=null) {
ÊÊÊÊÊÊo.defaultSelected = true;
ÊÊÊÊ}
ÊÊ}
ÊÊthis.currentNode = null;
}

// Set the options which should be selected when the page loads. This is different than the default value and ONLY applies when the page LOADS
function DOL_setValues() {
ÊÊif (this.currentField==null) { 
ÊÊÊÊalert("Can't call setValues() without using forField() first!");
ÊÊÊÊreturn;
ÊÊ}
ÊÊif (typeof(this.values[this.currentField])=="undefined") {
ÊÊÊÊthis.values[this.currentField] = new Object();
ÊÊ}
ÊÊfor (var i=0; i<arguments.length; i++) {
ÊÊÊÊthis.values[this.currentField][arguments[i]] = true;
ÊÊ}
ÊÊthis.currentField = null;
}

// Manually set the form for the object using an index
function DOL_setFormIndex(i) {
ÊÊthis.formIndex = i;
}

// Manually set the form for the object using a form name
function DOL_setFormName(n) {
ÊÊthis.formName = n;
}

// Print blank <option> objects for Netscape4, since it refuses to grow or shrink select boxes for new options
function DOL_printOptions(name) {
ÊÊ// Only need to write out "dummy" options for Netscape4
    if ((navigator.appName == 'Netscape') && (parseInt(navigator.appVersion) <= 4)){
ÊÊÊÊvar index = this.fieldIndexes[name];
ÊÊÊÊvar ret = "";
ÊÊÊÊif (typeof(this.numberOfOptions[index])!="undefined") {
ÊÊÊÊÊÊfor (var i=0; i<this.numberOfOptions[index]; i++) { 
ÊÊÊÊÊÊÊÊret += "<OPTION>";
ÊÊÊÊÊÊ}
ÊÊÊÊ}
ÊÊÊÊret += "<OPTION>";
ÊÊÊÊif (typeof(this.longestString[index])!="undefined") {
ÊÊÊÊÊÊfor (var i=0; i<this.longestString[index].length; i++) {
ÊÊÊÊÊÊÊÊret += "_";
ÊÊÊÊÊÊ}
ÊÊÊÊ}
ÊÊÊÊdocument.writeln(ret);
ÊÊ}
}

// Add a list of field names which use this option-mapping object.
// A single mapping object may be used by multiple sets of fields
function DOL_addDependentFields() {
ÊÊfor (var i=0; i<arguments.length; i++) {
ÊÊÊÊthis.fieldListIndexes[arguments[i].toString()] = this.fieldNames.length;
ÊÊÊÊthis.fieldIndexes[arguments[i].toString()] = i;
ÊÊ}
ÊÊthis.fieldNames[this.fieldNames.length] = arguments;
}

// Called when a parent select box is changed. It populates its direct child, then calls change on the child object to continue the population.
function DOL_change(obj, usePreselected) {
ÊÊif (usePreselected==null || typeof(usePreselected)=="undefined") { usePreselected = false; }
ÊÊvar changedListIndex = this.fieldListIndexes[obj.name];
ÊÊvar changedIndex = this.fieldIndexes[obj.name];
ÊÊvar child = this.child(obj);
ÊÊif (child == null) { return; } // No child, no need to continue
ÊÊif (obj.type == "select-one") {
ÊÊÊÊ// Treat single-select differently so we don't have to scan the entire select list, which could potentially speed things up
ÊÊÊÊif (child.options!=null) {
ÊÊÊÊÊÊchild.options.length=0; // Erase all the options from the child so we can re-populate
ÊÊÊÊ}
ÊÊÊÊif (obj.options!=null && obj.options.length>0 && obj.selectedIndex>=0) {
ÊÊÊÊÊÊvar o = obj.options[obj.selectedIndex];
ÊÊÊÊÊÊthis.populateChild(o.DOLOption,child,usePreselected);
ÊÊÊÊÊÊthis.selectChildOptions(child,usePreselected);
ÊÊÊÊ}
ÊÊ}
ÊÊelse if (obj.type == "select-multiple") {
ÊÊÊÊ// For each selected value in the parent, find the options to fill in for this list
ÊÊÊÊ// Loop through the child list and keep track of options that are currently selected
ÊÊÊÊvar currentlySelectedOptions = new Array();
ÊÊÊÊif (!usePreselected) {
ÊÊÊÊÊÊfor (var i=0; i<child.options.length; i++) {
ÊÊÊÊÊÊÊÊvar co = child.options[i];
ÊÊÊÊÊÊÊÊif (co.selected) {
ÊÊÊÊÊÊÊÊÊÊthis.addNewOptionToList(currentlySelectedOptions, co.text, co.value, co.defaultSelected);
ÊÊÊÊÊÊÊÊ}
ÊÊÊÊÊÊ}
ÊÊÊÊ}
ÊÊÊÊchild.options.length=0;
ÊÊÊÊif (obj.options!=null) {
ÊÊÊÊÊÊvar obj_o = obj.options;
ÊÊÊÊÊÊ// For each selected option in the parent...
ÊÊÊÊÊÊfor (var i=0; i<obj_o.length; i++) {
ÊÊÊÊÊÊÊÊif (obj_o[i].selected) {
ÊÊÊÊÊÊÊÊÊÊ// if option is selected, add its children to the list
 ÊÊÊÊÊÊÊÊÊÊthis.populateChild(obj_o[i].DOLOption,child,usePreselected);
ÊÊÊÊÊÊÊÊ}
ÊÊÊÊÊÊ}
ÊÊÊÊÊÊ// Now go through and re-select any options which were selected before
ÊÊÊÊÊÊvar atLeastOneSelected = false;
ÊÊÊÊÊÊif (!usePreselected) {
ÊÊÊÊÊÊÊÊfor (var i=0; i<child.options.length; i++) {
ÊÊÊÊÊÊÊÊÊÊvar m = this.findMatchingOptionInArray(currentlySelectedOptions,child.options[i].text,child.options[i].value,true);
ÊÊÊÊÊÊÊÊÊÊif (m!=null) {
ÊÊÊÊÊÊÊÊÊÊÊÊchild.options[i].selected = true;
ÊÊÊÊÊÊÊÊÊÊÊÊatLeastOneSelected = true;
ÊÊÊÊÊÊÊÊÊÊ}
ÊÊÊÊÊÊÊÊ}
ÊÊÊÊÊÊ}
ÊÊÊÊÊÊif (!atLeastOneSelected) {ÊÊ
ÊÊÊÊÊÊÊÊthis.selectChildOptions(child,usePreselected);
ÊÊÊÊÊÊ}
ÊÊÊÊ}
ÊÊ}
ÊÊ// Change all the way down the chain
ÊÊthis.change(child,usePreselected);
}
function DOL_populateChild(dolOption,childSelectObj,usePreselected) {
ÊÊ// If this opton has sub-options, populate the child list with them
ÊÊif (dolOption!=null && dolOption.options!=null) {
ÊÊÊÊfor (var j=0; j<dolOption.options.length; j++) {
ÊÊÊÊÊÊvar srcOpt = dolOption.options[j];
ÊÊÊÊÊÊif (childSelectObj.options==null) { childSelectObj.options = new Array(); }
ÊÊÊÊÊÊ// Put option into select list
ÊÊÊÊÊÊvar duplicate = false;
ÊÊÊÊÊÊvar preSelectedExists = false;
ÊÊÊÊÊÊfor (var k=0; k<childSelectObj.options.length; k++) {
ÊÊÊÊÊÊÊÊvar csi = childSelectObj.options[k];
ÊÊÊÊÊÊÊÊif (csi.text==srcOpt.text && csi.value==srcOpt.value) {
ÊÊÊÊÊÊÊÊÊÊduplicate = true;
ÊÊÊÊÊÊÊÊÊÊbreak;
ÊÊÊÊÊÊÊÊ}
ÊÊÊÊÊÊ}
ÊÊÊÊÊÊif (!duplicate) {
ÊÊÊÊÊÊÊÊvar newopt = new Option(srcOpt.text, srcOpt.value, false, false);
ÊÊÊÊÊÊÊÊnewopt.selected = false; // Again, we have to do these two statements for NN4 to work
ÊÊÊÊÊÊÊÊnewopt.defaultSelected = false;
ÊÊÊÊÊÊÊÊnewopt.DOLOption = srcOpt;
ÊÊÊÊÊÊÊÊchildSelectObj.options[childSelectObj.options.length] = newopt;
ÊÊÊÊÊÊ}
ÊÊÊÊ}
ÊÊ}
}

// Once a child select is populated, go back over it to select options which should be selected
function DOL_selectChildOptions(obj,usePreselected) {
ÊÊ// Look to see if any options are preselected=true. If so, then set then selected if usePreselected=true, otherwise set defaults
ÊÊvar values = this.values[obj.name];
ÊÊvar preselectedExists = false;
ÊÊif (usePreselected && values!=null && typeof(values)!="undefined") {
ÊÊÊÊfor (var i=0; i<obj.options.length; i++) {
ÊÊÊÊÊÊvar v = obj.options[i].value;
ÊÊÊÊÊÊif (v!=null && values[v]!=null && typeof(values[v])!="undefined") {
ÊÊÊÊÊÊÊÊpreselectedExists = true;
ÊÊÊÊÊÊÊÊbreak;
ÊÊÊÊÊÊ}
ÊÊÊÊ}
ÊÊ}
ÊÊ// Go back over all the options to do the selection
ÊÊvar atLeastOneSelected = false;
ÊÊfor (var i=0; i<obj.options.length; i++) {
ÊÊÊÊvar o = obj.options[i];
ÊÊÊÊif (preselectedExists && o.value!=null && values[o.value]!=null && typeof(values[o.value])!="undefined") {
ÊÊÊÊÊÊo.selected = true;
ÊÊÊÊÊÊatLeastOneSelected = true;
ÊÊÊÊ}
ÊÊÊÊelse if (!preselectedExists && o.DOLOption!=null && o.DOLOption.defaultSelected) {
ÊÊÊÊÊÊo.selected = true;
ÊÊÊÊÊÊatLeastOneSelected = true;
ÊÊÊÊ}
ÊÊÊÊelse {
ÊÊÊÊÊÊo.selected = false;
ÊÊÊÊ}
ÊÊ}
ÊÊ// If nothing else was selected, select the first one by default
ÊÊif (this.selectFirstOption && !atLeastOneSelected && obj.options.length>0) {
ÊÊÊÊobj.options[0].selected = true;
ÊÊ}
ÊÊelse if (!atLeastOneSelected &&  obj.type=="select-one") {
ÊÊÊÊobj.selectedIndex = -1;
ÊÊ}
}
