//////////////////////////////////////////////////////////////
// usage GetData(url, vars, targets, defaults, commands) or GetData(arrayRef)
// <span onmousedown="GetData(
// '/cgi-bin/some.pl',                       // 1. URL to fetch.
// ['a=1&b=2', 'form1.name1'],               // 2. Vars to send to URL.
// ['element', 'form.field', 'new.xhr.obj'], // 3. Targets to deliver answers to.
// '<!--<label>-->value<!--</label>-->',     // 4. Default return string (optional).
// ['fn(\'param\', \'param2\')', 'fn2()']    // 5. Commands to run after.
// )">click</span>
//
// 1. A URL on the current domain. eg '/cgi-bin/some.pl?' or './about.txt'
//    If data might change, add "?" to force refresh in IE.
//    Use '' or '#' to disable request to URL and use default return.
//    Default submit method is 'GET'. Add "?P" to force POST.
//
// 2. Vars to send to URL.
//    a. A 'get' string. eg 'a=1&b=2'
//    b. A reference to a form.field value eg 'form1.name1'
//    c. An array of both eg ['a=1&b=2', 'form1.name1', 'form1.name2']
//
//    Access history using special vars: 'BACK=0', 'FWD=0'
//
// 3. Target fields:
//    a. A reference to a form.field eg 'form1.name1'
//    b. A reference to a body ElementId. eg 'area1'
//    c. A reference to an xhrArray object name. eg 'my.hidden.element'
//    d. An array of both eg ['area1', 'form1.address', 'form1.tel']
//    'id:subtype' or 'formname.fieldname:subtype' allows result selection from a multiple value return string
//
//    The target values specify the nameset for the xmlresponse tags and the document targets.
//    For each target, empty xmlresponse tags or no tags clears the target.
//
//    A string value for the target is a special case.
//    It returns the whole xmlresponse if tagged values dont exist.
//    Returns std "File not found.." if URL does not exist.
//    
// 4. Defaults, appended to the returned data string.
//    a. A string. 
//       eg '<!--<form2.rate>-->15<!--</form2.rate>-->'
//       or 'hello world' (applies single string target)
//    b. An array of strings.
//       eg ['<!--<area1>-->Something<!--</area1>-->',
//           '<!--<form1.name1>-->George<!--</form1.name1>-->']
//       Any array value being a valid form.field reference will be substituted.
//       eg ['<!--<area1>-->', 'form1.field1a', '<!--</area1>-->']
//       The array is joined without spaces for processing.
//
//    The URL is expected to return normal html headers plus data.
//
//    Data can be:
//  1. A hash of 'text or html' data within named tags.
//         eg "<!--<area1>-->Area 1 text goes here<!--</area1>-->
//             <!--<form1.name1>-->George<!--</form1.name1>-->"
//    Contents of first match is returned to each specified target formfield or ElementId.
//    Returned values, override any defaults. 
//
//  2. A slab of text or html with no target tags.
//     If tags are not found, then the entire response is used.
//     * This applies only for a single 'non-array' print target.
//
//  Note: 
//     Default string is ignored if URL is defined and 'targets' is a single string.   
//     Default string specifies the value where no tagged response is returned.
//
// 5. Running commands after GetData has completed.
//    a. Local data.
//       GetData calls to local memory are synchronous. GetData call completes first
//       and then processing of inline commands continues.
//       eg GetData('#', 'FWD=0'); style.color='666666'; // colour change is last
//    b. Server data.
//       GetData calls to server data are asyncronous, so processing of inline commands
//       continues, and sometime later, GetData returns its data. 
//       The 'commands' parameter accepts a string, or an array of strings.
//       An input array can be a function returning an array, or an array of strings and/or functions returning strings.
//       Each element is evaluated as code, in the global? context, after GetData has completed.
//       eg GetData('#', 'FWD=0', '', '' , 'document.getElementById(\'xhrfwd\').style.color=\'666666\'')
//          GetData('some.pl', 'a=1&b=2', 'there', '' , 'xhrArray(\'del\', \'hidden\'); toggle(\'activitiespanel\', \'atoggle\', \'A\', \'a\')');
//          GetData('some.pl', 'a=1&b=2', 'there', '' , ['xhrArray(\'del\', \'hidden\')', 'toggle(\'activitiespanel\', \'atoggle\', \'A\', \'a\')']);
//          GetData('some.pl', 'a=1&b=2', 'there', '' , xhrArray(\'read\', \'my.commandsarray\'));
//       
//  Thus:
//   GetData('Some file.txt', '', 'here');
//   GetData('#', '', 'there', 'Put this');
//   GetData('', '', 'there', ['Put this', '<BR>and this']);
//   GetData('', '', 'there', '<!--<there>-->Put this<!--</there>-->');
//   GetData('Some.pl', 'a=1&b=2', ['there', 'perlystuffhere'], '<!--<there>-->Put this<!--</there>-->');
//   <input type="text" name="typehere" onkeyup="GetData('#', '', 'targetid', ['formname.typehere'])"
//   GetData('#', 'BACK=0');    GetData('#', 'FWD=0')
//
//  GetData also accepts a reference to:
//
//   An array of strings and/or arrays.
//    var myArray = new Array('', '', 'there', ['hello', 'world']);
//    GetData(myArray);
//
//   A function returning an array of strings and/or arrays
//    var vars = new Array('a=1&b=2', 'c=3');
//    xhrArray('set', 'urls.test', ['#', vars, 'there']);
//    GetData(xhrArray('read', 'urls.test'));
//
//   A javascript object returning an array of strings and/or arrays
//    GetData(register.urls.test);             // causes error if object not defined
//
//  Note:
//   Define history.fields to enable 'screen capture' based history and xhrstack operation.
//   Define page.busyindicator to enable busy indicator.
//   <SCRIPT LANGUAGE="JavaScript">
//   xhrArray('set', 'history.fields', ['elementId1', 'elementId2'])
//   xhrArray('set', 'history.max', '50');
//   xhrArray('set', 'page.busyindicator', ['elementId', 'onValue', 'offValue']);
//   </SCRIPT>
//   eg xhrArray('set', 'page.busyindicator', ['busyindicator', '<IMG SRC=\'../images/hourglass.gif\' height=\'14\' width=\'9\'>', '<IMG SRC=\'../images/1x1.gif\' height=\'14\' width=\'9\'>']);
//
//////////////////////////////////////////////////////////////

function XHConn() {
 var xmlhttp, bComplete = false;
 try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
 catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
 catch (e) { try { xmlhttp = new XMLHttpRequest(); }
 catch (e) { xmlhttp = false; }}}
 if (!xmlhttp) return null;
 this.connect = function(sURL, sMethod, sVars, fnDone) {
  if (!xmlhttp) return false;
  bComplete = false;
  sMethod = sMethod.toUpperCase();
  try {
   if (sMethod == "GET") {
    xmlhttp.open(sMethod, sURL+"?"+sVars, true);
    sVars = "";
   } else {
    xmlhttp.open(sMethod, sURL, true);
    xmlhttp.setRequestHeader("Method", "POST "+sURL+" HTTP/1.1");
    xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
   }
   xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4 && !bComplete) {
     bComplete = true;
     fnDone(xmlhttp);
    }
   };
   xmlhttp.send(sVars);
// alert('hi'); // test pause before returning
  }
  catch(z) { return false; }
  return true;
 };
 return this;
}

function escApos(instring) {  // as in <form.. value=\'', escApos(this.innerHTML), '\'>
 var escaped = "";
 for (var i = 0; i < instring.length; i++ ) {
  var ch = instring.charAt(i);
  if (ch == "'") {
   escaped += "&apos;";
  } else {
   escaped += ch;
  }
 }
 return escaped;
}


function URLEncode(varstring) {
 // [a-zA-Z0-9] plus RFC2396 Mark characters
 var SAFECHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.!~*'()";
 var HEX = "0123456789ABCDEF";
 var encoded = "";
 for (var i = 0; i < varstring.length; i++ ) {
  var ch = varstring.charAt(i);
  if (ch == " ") {
   encoded += "+";				// x-www-urlencoded, rather than %20
  } else if (SAFECHARS.indexOf(ch) != -1) {
   encoded += ch;
  } else {
   var charCode = ch.charCodeAt(0);
   if (charCode > 255) {
    encoded += "+";
   } else {
    encoded += "%";
    encoded += HEX.charAt((charCode >> 4) & 0xF);
    encoded += HEX.charAt(charCode & 0xF);
   }
  }
 }
 return encoded;
};

function GetData (url, variables, targets, xmlstrings, commands) {

 if (xhrArray('read', 'page.busyindicator')) {
  document.getElementById(xhrArray('read', 'page.busyindicator.0')).innerHTML=xhrArray('read', 'page.busyindicator.1');
 }

 if (typeof(url) == 'object') { // if url is array, use as inputs
  var spec = url;
  url = spec[0];
  variables  = spec[1];
  targets = spec[2];
  xmlstrings = spec[3]
  commands = spec[4];
 }
 var vars = "";
 var vartype = typeof (variables);
 if (vartype == 'string') {
  var variablesstring = variables;
  variables = new Array();
  variables[0] = variablesstring;
 }
 for(var n = 0; n < variables.length; n++) {
  var formvar = variables[n].split(".");
  var thisvarval = variables[n].split("=");
  var thispair = "";
  var thisval = "";
  if (thisvarval[1]) {
   thispair = variables[n];
  } else {
//   if (formvar[1]) {
   if ( (formvar[1]) && 
        ( (document[formvar[0]][formvar[1]].type != 'checkbox') || ((document[formvar[0]][formvar[1]].type == 'checkbox') && (document[formvar[0]][formvar[1]].checked)) )
      ) {
    thisval = URLEncode (document[formvar[0]][formvar[1]].value);
    thispair = formvar[1]+"="+thisval;
   } else { // assume form name is 'form'
//    if (formvar[0]) {
    if ( (formvar[0]) &&
         ( (document.form[formvar[1]].type != 'checkbox') || ((document.form[formvar[1]].type == 'checkbox') && (document.form[formvar[1]].checked)) )
       ) {
     thisval = URLEncode (document.form[formvar[0]].value);
     thispair = formvar[1]+"="+thisval;
    }
   }
  }
  vars += thispair+"&";
 }
 var mymethod = 'GET';
 var undefined;
 var urlsplit = url.split('?'); 
 if (urlsplit[1] != undefined) {
  url = urlsplit[0];
  vars += Math.round(100000*Math.random());
  if (urlsplit[1] == 'P') {
   mymethod = 'POST';
  }
 }
 if (vars.length > 512) {
  mymethod = 'POST';
 }
 var xmlstring = '';
 if (xmlstrings) {
  vartype = typeof (xmlstrings);
  if (vartype == 'string') {
  xmlstring = xmlstrings;
  } else {
   for(var n = 0; n < xmlstrings.length; n++) {
    if (xmlstrings[n]) {
     if (xmlstrings[n].match(/^[-\w]+\.[-\w]+$/))  {
      var xmlvar = xmlstrings[n].split(".");
      if ( typeof document[xmlvar[0]] != "undefined")  {
       if ( typeof document[xmlvar[0]][xmlvar[1]] != "undefined")  { 
        xmlstring += document[xmlvar[0]][xmlvar[1]].value;
       }else {
        xmlstring += xmlstrings[n];
       }
      } else {
       xmlstring += xmlstrings[n];
      }
     } else {
      xmlstring += xmlstrings[n];
     }
    }
   }
  }
 }

 var params = new Array(url, vars, targets, xmlstring);

// new test history, 2007-05-25 use captures if historyfields defined
// works except for toggle problem, need to clear toggle.
// if (typeof(historyfields) == 'object') {
if (xhrArray('read', 'history.fields')) {    // use capture history
 if (vars == 'BACK=0&') {
  if (xhrArray('read', 'history.back')) {
   params = xhrArray('shift', 'history.back');
   xhrArray('unshift', 'history.fwd', xhrCapture(xhrArray('read', 'history.fields')));
   xhrArray('del', 'hidden');  // clear toggle memory
  } else {
   alert('history.back is empty');
   params = xhrCapture(xhrArray('read', 'history.fields'))
  }
 } else if (vars == 'FWD=0&') {
  if (xhrArray('read', 'history.fwd')) {
   params = xhrArray('shift', 'history.fwd');
   xhrArray('unshift', 'history.back', xhrCapture(xhrArray('read', 'history.fields')));
   xhrArray('del', 'hidden');
  } else {
   alert('history.fwd is empty');
   params = xhrCapture(xhrArray('read', 'history.fields'))
  }
 } else {
  xhrArray('unshift', 'history.back', xhrCapture(xhrArray('read', 'history.fields')));
  xhrArray('del', 'history.fwd');
  if (xhrArray('read', 'history.max')) {
   if (xhrArray('read', 'history.back.' + xhrArray('read', 'history.max'))) {
    xhrArray('pop', 'history.back');
   }
  }

 }

} else {
 if (vars == 'BACK=0&') {
  if (xhrArray('read', 'history.back')) {
   params = xhrArray('shift', 'history.back');
   xhrArray('unshift', 'history.fwd', xhrArray('read', 'history.now'));
   xhrArray('set', 'history.now', params);
  } else {
   alert('history.back is empty');
   params = xhrArray('read', 'history.now');
  }
 } else if (vars == 'FWD=0&') {
  if (xhrArray('read', 'history.fwd')) {
   params = xhrArray('shift', 'history.fwd');
   xhrArray('unshift', 'history.back', xhrArray('read', 'history.now'));
   xhrArray('set', 'history.now', params);
  } else {
   alert('history.fwd is empty');
   params = xhrArray('read', 'history.now');
  }
 } else {
  xhrArray('unshift', 'history.back', xhrArray('read', 'history.now'));
  xhrArray('set', 'history.now', params);
  xhrArray('del', 'history.fwd');
 }

}

 url = params[0];
 vars = params[1];
 targets = params[2];
 xmlstring = params[3];

 var myConn = new XHConn(); 

 if (myConn) {
  if (url == '') {
   url = "#";
  }
//  if (url) {

   var fnWhenDone = function (oXML) {
   var xmlresponsetext = '';
    if (url == "#") {
     xmlresponsetext = xmlstring;
    } else {
     if (oXML.responseText) {
      xmlresponsetext = oXML.responseText;
     }
    }
    var targettype = typeof (targets);
    if (targettype == 'string') {               // convert to array(1)
     var targetstring = targets;
     targets = new Array();
     targets[0] = targetstring;
    } else {
     xmlresponsetext += xmlstring;
    }


    for(var i = 0; i < targets.length; i++) {
     var value = undefined;
     var opentag = "<!--<"+targets[i]+">-->";
     var closetag = "<!--<\/"+targets[i]+">-->";
     var opensplit = xmlresponsetext.split(opentag);
     if (opensplit[1]) {
      var postopen = opensplit[1]+"\n";         // so split[1] exists
      var closesplit = postopen.split(closetag);
      if (closesplit[1]) {
       value = closesplit[0];
      }
     }
     if (value == undefined) {
      if (targettype == 'string') {
       value = xmlresponsetext;
      } else {
       value = "";
      }
     }
     if (!(value == undefined)) {
      var target = "";
      var subtype = "";
      var typesplit = targets[i].split(":");
      if (typesplit[1]) {
       subtype = typesplit[1];
       target = typesplit[0].split(".");
      }else {
       target = targets[i].split(".");
      }
      if (target[2]) {
       xhrArray('set', target[0] + "." + target[1] + "." + target[2], value);
      } else {
       if (target[1]) {                              // form id
        if (document[target[0]][target[1]]) {        // ignore non existent target
         document[target[0]][target[1]].value=value; // watch line feeds in value
        }
       } else {
        if (target[0]) {                             // document id
         if (document.getElementById(target[0])) {   // ignore non existent
          document.getElementById(target[0]).innerHTML=value;
         }                                           
        }
       }
      }
     }
    }
    if (commands) {
     var commandtype = typeof (commands); // alert(commandtype);
     if (commandtype == 'string') {               // convert to array(1)
      var commandstring = commands;
      commands = new Array();
      commands[0] = commandstring;
     }

     for(var i = 0; i < commands.length; i++) {
// alert(commands[i]);
// var mytype = typeof (commands[i]);
// alert(mytype);
      eval ( commands[i] );
     }
    }

    if (xhrArray('read', 'page.busyindicator')) {
     document.getElementById(xhrArray('read', 'page.busyindicator.0')).innerHTML=xhrArray('read', 'page.busyindicator.2');
    }
//

   };
   if (url == '#') {
    fnWhenDone();
   } else {
    myConn.connect(url, mymethod, vars, fnWhenDone);
   }

//  }
 } else {
  alert("XMLHTTP not available. Try a newer/better browser.");
 }
};
// file xhrArray.js
/////////////////////////////////
// Fire on formfield change example
// Set initial value, then:
// 1. check for change at regular intervals
// <span onfocus="xhrArray('set', 'myId', formname.id.value);
// myInterval = window.setInterval(function(a,b) {
//  if (xhrArray('reset', 'myId', formname.id.value)) { GetData( [config] )} },3000)"; 
//  onblur="clearTimeout(myInterval)">
// 2. check for change on keyUp
// onkeyup="xhrArray('set', 'myId', formname.id.value);
// if (xhrArray('reset', 'myId', formname.id.value)) {
//  document.getElementById('busyindicator').innerHTML='&nbsp;<IMG SRC=\/images\/hourglass.gif  height=14 width=9>';
//  GetData( [config] )">
/////////

var myInterval; // initialise before window.setInterval call

////////

/*
Usage
<span onMouseDown="xhrProcess(
'set',				// myCommand 	set|read|delreset|unshift|shift|push|pop
'a.b.c.1',			// myArrayName 	object, up to 5 names or numbers
['1', '2', '3']			// myValue	'string' or ['array', 'of', 'strings'] 
);

xhrArray is an interface to an arbitrary javascript data structure.


1. myCommand.

2. myArrayName
Reference to an object.

3. 


Thus:
('set', 'a.b', 'ab')			set a.b to 'ab'
('set', 'a.b.c', 'abc')			set a.b.c to 'abc'		convert a.b to object, lose value
('set', 'a.b.c', ['this', 'array'])	set a.b.c to ['this', 'array']	overwrite previous value with array
('reset', 'a.b.c', 'abc')		reset a.b.c to 'abc'		true if changed
('del', 'a.b') 				delete a.b and all child objects.
('set', 'a.b.c.1', ['1','2','3','4'])	set a.b.c.1 to ['1','2','3','4']
('set', 'a.b.c.1.0', 'MM')		set a.b.c.1.0 to 'MM'
('set', 'a.b.c.2', 'WOO')		set a.b.c.2 to 'WOO'
('push', 'a.b.c', 'pushed')		push a.b.c 'pushed'		set a.b.c[next] to new value
('push', 'a.b.c', ['pushed', 'array'])	push a.b.c ['pushed', 'array']	set a.b.c[next] to new array
('pop', 'a.b.c')			pop a.b.c			fetch and remove a.b.c[last]
('pop', 'a.b.c.1')			pop a.b.c.1
('unshift', 'a.b.c', 'shifted')		unshift a.b.c 'unshifted'	insert as array[0]
('shift', 'a.b.c')			shift a.b.c			fetch and remove a.b.c[0]
GetDate('','','my.hidden.panel', 'hello world') is thus equivalent to xhr('set', 'my.hidden.panel', 'hello world') 
GetDate('','','maintablepanel', xhr('read', 'my.hidden.panel')) to place onto screen
*/


var myCommand;
var myArrayName;
var myValue;
var register = new Array();
function xhrArray(myCommand, myArrayName, myValue) {
 var iValue;
 if (myCommand == 'reset') {
  iValue = xhrArray('read', myArrayName);
 }
 var thisArray0 = new Array();
 var thisArray1 = new Array();
 var thisArray2 = new Array();
 var thisArray3 = new Array();
 var thisArray4 = new Array();
 var thisArray5 = new Array();
 var thisArray6 = new Array();
 var thisArray7 = new Array();
 var thisArray8 = new Array();
 var thisArray9 = new Array();
 var arrayRef = new Array();
 var keyRef = '';
 var arrayElements = myArrayName.split(".");
 if (arrayElements) {
  if (typeof(register) != 'object') {
   register = new Array();
  }
  if (typeof(register[arrayElements[0]]) != 'object') {
   if ((myCommand == 'read') || (myCommand == 'pop') || (myCommand == 'shift')) { return ''; }
   register[arrayElements[0]] = new Array();
  }                                                        // arrayRefName = 'register';
  if ((typeof(register[arrayElements[0]]) == 'string') && (typeof(myValue) != 'undefined') && (arrayElements[1])) {
   register[arrayElements[0]] = new Array();               // overwriting r.a0 value with r.a0.a1 object/value
  }
  thisArray0 = register[arrayElements[0]];
  if (arrayElements[1]) {
   if ((typeof(thisArray0[arrayElements[1]]) != 'object') && (typeof(thisArray0[arrayElements[1]]) != 'string')) {
    if ((myCommand == 'read') || (myCommand == 'pop') || (myCommand == 'shift')) { return ''; }
    thisArray0[arrayElements[1]] = new Array();
   }
   if ((typeof(thisArray0[arrayElements[1]]) == 'string') && (typeof(myValue) != 'undefined') && (arrayElements[2])) {
    thisArray0[arrayElements[1]] = new Array();
   }
   thisArray1 = thisArray0[arrayElements[1]];
   if (arrayElements[2]) {                                 // arrayRefName = 'register.' + arrayElements[0] + '.' + arrayElements[1];
    if ((typeof(thisArray1[arrayElements[2]]) != 'object') && (typeof(thisArray1[arrayElements[2]]) != 'string')) {
     if ((myCommand == 'read') || (myCommand == 'pop') || (myCommand == 'shift')) { return ''; }
     thisArray1[arrayElements[2]] = new Array();
    }
    if ((typeof(thisArray1[arrayElements[2]]) == 'string') && (typeof(myValue) != 'undefined') && (arrayElements[3])) {
     thisArray1[arrayElements[2]] = new Array();
    }
    thisArray2 = thisArray1[arrayElements[2]];
    if (arrayElements[3]) {
     if ((typeof(thisArray2[arrayElements[3]]) != 'object') && (typeof(thisArray2[arrayElements[3]]) != 'string')) {
      if ((myCommand == 'read') || (myCommand == 'pop') || (myCommand == 'shift')) { return ''; }
      thisArray2[arrayElements[3]] = new Array();
     }
     if ((typeof(thisArray2[arrayElements[3]]) == 'string') && (typeof(myValue) != 'undefined') && (arrayElements[4])) {
      thisArray2[arrayElements[3]] = new Array();         // overwriting r.a0.a1.a2.a3 value with r.a0.a1.a2.a3.a4 object/value
     }
     thisArray3 = thisArray2[arrayElements[3]];
     if (arrayElements[4]) {
      if ((typeof(thisArray3[arrayElements[4]]) != 'object') && (typeof(thisArray3[arrayElements[4]]) != 'string')) {
      if ((myCommand == 'read') || (myCommand == 'pop') || (myCommand == 'shift')) { return ''; }
       thisArray3[arrayElements[4]] = new Array();
      }
      if ((typeof(thisArray3[arrayElements[4]]) == 'string') && (typeof(myValue) != 'undefined') && (arrayElements[5])) {
       thisArray3[arrayElements[4]] = new Array();
      }
      thisArray4 = thisArray3[arrayElements[4]];
      if (arrayElements[5]) {
       if ((typeof(thisArray4[arrayElements[5]]) != 'object') && (typeof(thisArray4[arrayElements[5]]) != 'string')) {
       if ((myCommand == 'read') || (myCommand == 'pop') || (myCommand == 'shift')) { return ''; }
        thisArray4[arrayElements[5]] = new Array();
       }
       if ((typeof(thisArray4[arrayElements[5]]) == 'string') && (typeof(myValue) != 'undefined') && (arrayElements[6])) {
        thisArray4[arrayElements[5]] = new Array();
       }
       thisArray5 = thisArray4[arrayElements[5]];
       if (arrayElements[6]) {
        if ((typeof(thisArray5[arrayElements[6]]) != 'object') && (typeof(thisArray5[arrayElements[6]]) != 'string')) {
        if ((myCommand == 'read') || (myCommand == 'pop') || (myCommand == 'shift')) { return ''; }
         thisArray5[arrayElements[6]] = new Array();
        }
        if ((typeof(thisArray5[arrayElements[6]]) == 'string') && (typeof(myValue) != 'undefined') && (arrayElements[7])) {
         thisArray5[arrayElements[6]] = new Array();
        }
        thisArray6 = thisArray5[arrayElements[6]];
        if (arrayElements[7]) {
         if ((typeof(thisArray6[arrayElements[7]]) != 'object') && (typeof(thisArray6[arrayElements[7]]) != 'string')) {
         if ((myCommand == 'read') || (myCommand == 'pop') || (myCommand == 'shift')) { return ''; }
          thisArray6[arrayElements[7]] = new Array();
         }
         if ((typeof(thisArray6[arrayElements[7]]) == 'string') && (typeof(myValue) != 'undefined') && (arrayElements[8])) {
          thisArray6[arrayElements[7]] = new Array();
         }
         thisArray7 = thisArray6[arrayElements[7]];
         if (arrayElements[8]) {
          if ((typeof(thisArray7[arrayElements[8]]) != 'object') && (typeof(thisArray7[arrayElements[8]]) != 'string')) {
          if ((myCommand == 'read') || (myCommand == 'pop') || (myCommand == 'shift')) { return ''; }
           thisArray7[arrayElements[8]] = new Array();
          }
          if ((typeof(thisArray7[arrayElements[8]]) == 'string') && (typeof(myValue) != 'undefined') && (arrayElements[9])) {
           thisArray7[arrayElements[8]] = new Array();
          }
          thisArray8 = thisArray7[arrayElements[8]];
          if (arrayElements[9]) {
           if ((typeof(thisArray8[arrayElements[9]]) != 'object') && (typeof(thisArray8[arrayElements[9]]) != 'string')) {
           if ((myCommand == 'read') || (myCommand == 'pop') || (myCommand == 'shift')) { return ''; }
            thisArray8[arrayElements[9]] = new Array();
           }
           thisArray9 = thisArray8[arrayElements[9]];
           arrayRef = thisArray8;
           keyRef = arrayElements[9];
          } else {
           arrayRef = thisArray7;
           keyRef = arrayElements[8];
          }
         } else {
          arrayRef = thisArray6;
          keyRef = arrayElements[7];
         }
        } else {
         arrayRef = thisArray5;
         keyRef = arrayElements[6];
        }
       } else {
        arrayRef = thisArray4;
        keyRef = arrayElements[5];
       }
      } else {
       arrayRef = thisArray3;
       keyRef = arrayElements[4];
      }
     } else {
      arrayRef = thisArray2;
      keyRef = arrayElements[3];
     } 
    } else {
     arrayRef = thisArray1;
     keyRef = arrayElements[2];
    } 
   } else {
    arrayRef = thisArray0;
    keyRef = arrayElements[1];
   }
  } else {
   arrayRef = register;
   keyRef = arrayElements[0];
  }

// now the action
  if (myCommand == 'read') {
   if (arrayRef[keyRef].value) {
// alert('returning value' + arrayRef[keyRef].value);
    return arrayRef[keyRef].value;
   } else if (arrayRef[keyRef] != '') {
// alert('returning obj' + arrayRef[keyRef]);
    return arrayRef[keyRef];	
   } else {
// alert('not returning obj' + arrayRef[keyRef]);
    return '';
   }
  }

  if (myCommand == 'set') {
   if (typeof(myValue) == 'string') {
    arrayRef[keyRef] = myValue;
    return myValue;
   } else {
    arrayRef[keyRef] = myValue;
    return myValue.length;
   }
  }

  if (myCommand == 'reset') {
   if (iValue == myValue) {
    return false;
   } else {
    if (typeof(myValue) == 'string') {
     arrayRef[keyRef] = myValue;
     return true;
    } else {
     arrayRef[keyRef] = myValue;
     return true;
    }
   }
  }

  if (myCommand == 'del') {
   if (typeof(arrayRef[keyRef])) {
    delete arrayRef[keyRef];
   }
   return true;
  }
//
//  if (myCommand == 'eval') {
//   var commandtype = typeof (keyRef);
//   if (commandtype == 'string') {               // convert to array(1)
//    var commandstring = commands;
//    commands = new Array();
//    commands[0] = commandstring;
//   }
//   for(var i = 0; i < commands.length; i++) {
//    eval ( commands[i] );
//   }
//  }
//


  if (myCommand == 'push') {
   if (typeof(arrayRef[keyRef]) != 'object') {
    var stringVal;
    if (arrayRef[keyRef].value) {
     stringVal = arrayRef[keyRef].value;
    } else if (arrayRef[keyRef]) {
     stringVal = arrayRef[keyRef];
    }
    arrayRef[keyRef] = new Array(stringVal);
   }
   return arrayRef[keyRef].push(myValue);
  }

  if (myCommand == 'pop') {
   if (typeof(arrayRef[keyRef]) == 'object') {
    return arrayRef[keyRef].pop();
   }else {                                 // pseudo pop a string
    if (arrayRef[keyRef].value) {  
     var poppedvalue = arrayRef[keyRef].value;
     delete arrayRef[keyRef];
     return poppedvalue;
    } else if (arrayRef[keyRef]) {
     var poppedvalue = arrayRef[keyRef];
     delete arrayRef[keyRef];
     return poppedvalue;
    } else {
     return '';
    }
   }
  }

  if (myCommand == 'unshift') {
   if (typeof(arrayRef[keyRef]) != 'object') {
    var stringVal;
    if (arrayRef[keyRef].value) {
     stringVal = arrayRef[keyRef].value;
    } else if (arrayRef[keyRef]) {
     stringVal = arrayRef[keyRef];
    }
    arrayRef[keyRef] = new Array(stringVal);
   }
   return arrayRef[keyRef].unshift(myValue);
  }

  if (myCommand == 'shift') {
   if (typeof(arrayRef[keyRef]) == 'object') {
    return arrayRef[keyRef].shift();
   }else {                              // pseudo shift a string
    if (arrayRef[keyRef].value) {
     var poppedvalue = arrayRef[keyRef].value;
     delete arrayRef[keyRef];
     return poppedvalue;
    } else if (arrayRef[keyRef]) {
     var poppedvalue = arrayRef[keyRef];
     delete arrayRef[keyRef];
     return poppedvalue;
    } else {
     return '';
    }
   }

  }
 }
 return false;
}
/// emulate functions for IE5.0
function Array_push() {
  var A_p = 0
  for (A_p = 0; A_p < arguments.length; A_p++) {
   this[this.length] = arguments[A_p]
   }
  return this.length
}

if (typeof(Array.prototype.push) == "undefined") {
 Array.prototype.push = Array_push
}

function Array_pop() {
  var response = this[this.length - 1]
  this.length--
  return response
}

if (typeof(Array.prototype.pop) == "undefined") {
  Array.prototype.pop = Array_pop
}

function Array_shift() {
  var A_s = 0
  var response = this[0]
  for (A_s = 0; A_s < this.length-1; A_s++) {
   this[A_s] = this[A_s + 1]
   }
  this.length--
  return response
}

if (typeof(Array.prototype.shift) == "undefined") {
  Array.prototype.shift = Array_shift
}

function Array_unshift() {
  var A_u = 0
  for (A_u = this.length-1; A_u >= 0; A_u--) {
   this[A_u + arguments.length] = this[A_u]
   }
  for (A_u = 0; A_u < arguments.length; A_u++) {
   this[A_u] = arguments[A_u]
   }
  return this.length
}

if (typeof(Array.prototype.unshift) == "undefined") {
  Array.prototype.unshift = Array_unshift
}


///
// toggle. optional 'on/off' values, return false for virgin field
function toggle(target,toggle,on,off) {
 if (document.getElementById(target)) {  // add this 2007-06-30
  if (document.getElementById(target).innerHTML == '') {
   if (xhrArray('read', 'hidden.' + target) == '') {
    return false;
   }
   document.getElementById(target).innerHTML=xhrArray('pop','hidden.' + target);
   if ((toggle) && (on) && (off)) {
    document.getElementById(toggle).innerHTML=on;
   }
  } else {
   xhrArray('set','hidden.' + target, document.getElementById(target).innerHTML);
   document.getElementById(target).innerHTML='';
   if ((toggle) && (on) && (off)) {
    document.getElementById(toggle).innerHTML=off;
   }
  }
 }
};

// convert screen to GetData parameters
// eg <SCRIPT LANGUAGE="JavaScript">var fields = new Array('mainmenubuttons', 'secondarymenubuttons', 'labelpanel', 'maintablepanel', 'actionpanel');</SCRIPT>
// <BODY onLoad="xhrArray('set', 'history.now', xhrCapture(fields));">
function xhrCapture(fields) {
 var xmlstring = '';
 for(var i = 0; i < fields.length; i++) {
  var opentag = "<!--<"+fields[i]+">-->";
  var closetag = "<!--<\/"+fields[i]+">-->";
  var fielddata = document.getElementById(fields[i]).innerHTML;
  xmlstring += opentag + fielddata + closetag;
 }
 var params = new Array('', '', fields, xmlstring);
 return params;
};

// find position of mouse event
// usage onmousedown="alert(pos(event,'xy'))";
function pos(e, xy) {
 var posx = 0;
 var posy = 0;
 if (e.pageX || e.pageY) {
  posx = e.pageX;
  posy = e.pageY;
 }else if (e.clientX || e.clientY) {
   posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
   posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
 }
 if ( xy == 'x') {
  return posx;
 }else if (xy == 'y') {
  return posy;
 }else {
  return new Array(posx, posy); // mouse position relative to the document
 }
}

//################# unused
// find position of element
// usage alert(findPos(document.getElementById('evaltarget')));
//    or alert(findPos(evaltarget);
function XfindPos(obj) {
// Credit for this function: http://www.quirksmode.org/js/findpos.html
 var curleft = curtop = curwidth = curheight = parent_offSetLeft = parent_offSetTop = 0;
 if (obj.offsetParent) {
  curleft = obj.offsetLeft
  curtop = obj.offsetTop
  curwidth = obj.offsetWidth;
  curheight = obj.offsetHeight;
  while (obj = obj.offsetParent) {
   curleft += obj.offsetLeft
   curtop += obj.offsetTop
   if(obj.id) {
    parent_offSetLeft = obj.offsetLeft;
    parent_offSetTop = obj.offsetTop;
   }
  }
 }
 return [curleft,curtop,curwidth,curheight,parent_offSetLeft,parent_offSetTop];
}
// find position of elementid
// alert(findPos(elementid)); # not an imageid/name
function BETTERfindPos(obj) {
 var w = y = w = h = 0;
 if (obj.offsetParent) {
  x = obj.offsetLeft;
  y = obj.offsetTop;
  w = obj.offsetWidth;
  h = obj.offsetHeight;
  while ((obj = obj.offsetParent) && (obj.nodeType == 1)) {
   x += obj.offsetLeft;
   y += obj.offsetTop;
  }
 }
 return [x,y,w,h];
}
//################### end unused

//
