<!--
// List Cascade Menu (04-Mar-2006)
// by Vic Phillips http://www.vicsjavascripts.org.uk

// Add Functionality to a List defined in the HTML Code
// Clicking a List Item will toggle the display of child UL list items
// and hide other UL list items.
// There may be as many levels in the list as required.

// With optional persistence to retain the last display when a visitor revisits.
// List item images may be specified and may be toggled with the display.
// List Items may also be connected with lines in the form of a menu tree.

// There may be as many applications on a page as required.

// Application Notes

// **** The HTML Code
//
// The list is defined in the HTML Code and does not require any special attributes
// but must be contained in a parent element  with a unique ID name.
// e.g.
//  <div id="test1" >
//   <ul >
//     <li>Tom0</li>
//      <ul >
//       <li>Dick0</li>
//        <ul >
//         <li>Dick00</li>
//           <ul id="d3">
//            <li>Dick000</li>
//            <li>Dick001</li>
//           </ul>
//         <li>Dick01</li>
//           <ul >
//            <li>Dick0000</li>
//            <li>Dick0010</li>
//           </ul>
//        </ul>
//       <li>Dick1</li>
//           <ul >
//            <li>Dick1000</li>
//            <li>Dick1010</li>
//           </ul>
//      </ul>
//     <li>Tom1
//   </ul>
//  </div>
//
// Event calls and links may be added to the code as required.

// **** Initialisation
//
// The script would normally be initialised from a <BODY> or window onload event
// e.g.
// <body onload="zxcInitList('test1',null,null);" >
// where:
// parameter 0 = the unique ID name of the parent element of the List (string)
// parameter 1 = is required if images are to be used.
// parameter 2 = is required if lines are to be used.

// ***** Item Images
//
// List item images may be specified and may be toggled with the display.
// Three images must be specified in an array
// field 0 = a standard (non toggling) image                                      (string)
// field 1 = display child UL image to be displayed when the child UL is hidden.  (string)
// field 2 = hide    child UL image to be displayed when the child UL is visible. (string)
//
// This array is assigned the second parameter of the initialisation call
// e.g. <body onload="zxcInitList('test',['right.gif','down.gif','up.gif'])" >

// **** Lines
//
// List Items may also be connected with lines in the form of a menu tree.
// If lines are used the parent elements must have a style
// display of 'display:absolute;' or  'display:relative;'
// and a style width of a width appropriate to the extended List
//
// The line attributes are defined in an array
// field 0 = the line type (solid, dotted, etc)  (string)
// field 1 = the line color                      (string)
// field 2 = the horizontal(X) line offset.      (digits)
// field 3 = the vertical(Y)   line offset.      (digits)
//
// This array is assigned the third parameter of the initialisation call
// e.g. <body onload="zxcInitList('test',['right.gif','down.gif','up.gif'],['dotted','black',10,8]);zxcInitList('test1',null,['dotted','black',10,10]);" >

// **** General
//
// All variable, function etc. names are prefixed with 'zxc' to minimise conflicts with other JavaScripts
// These characters are easily changed to characters of choice using global find and replace.

// The functional code(about 6K) is best as an external JavaScript

// Tested with IE6 and Mozilla FireFox

// Customising Variables

var zxcDays=1; // The List Menu display states will be available on revisits for a specified number of days

// Functional Code - NO NEED to Change

var zxcCursor='pointer'
if (document.all){ zxcCursor='hand'; }
var zxcExp=new Date(new Date().getTime()+zxcDays*86400000).toGMTString();

function zxcInitList(zxcid,zxcsimg,zxcline){
 zxcsimg=zxcsimg||['','',''];
 zxcp=document.getElementById(zxcid);
// zxcp.ary fields - 0 = id, 1 = .nu, 2 = line attributes, 3 = displayed items, 4 = line objects, 5 on = master LIs
 zxcp.ary=[zxcp,[],zxcline,[],[]];
 var zxcary=[];
 var zxcels=zxcp.getElementsByTagName('*')||zxcp.all;
 for (var zxc0=0;zxc0<zxcels.length;zxc0++){
  if (zxcels[zxc0].tagName.toUpperCase()=='LI'){
   zxcels[zxc0].style.listStyleImage='url('+zxcsimg[0]+')';
   zxcAddEvent(zxcels[zxc0],'zxcDisplay','click');
  }
  if (zxcels[zxc0].tagName.toUpperCase()=='UL'||zxcels[zxc0].tagName.toUpperCase()=='LI'){
   zxcary.push(zxcels[zxc0]);
  }
  if (zxcels[zxc0].tagName.toUpperCase()=='UL'){
   zxcels[zxc0].ary=[];
  }
  if (zxcels[zxc0].tagName.toUpperCase()=='LI'){
   zxcels[zxc0].parentNode.ary.push(zxcels[zxc0]);
  }
 }
 for (var zxc1=1;zxc1<zxcary.length;zxc1++){
  if (zxcary[zxc1].tagName.toUpperCase()=='UL'&&zxcary[zxc1-1].tagName.toUpperCase()=='LI'){
   zxcary[zxc1-1].slave=zxcary[zxc1];
   zxcary[zxc1-1].nu=zxc1;
   zxcp.ary.push(zxcary[zxc1-1]);
   zxcary[zxc1-1].ary=zxcp.ary;
   zxcary[zxc1-1].style.cursor=zxcCursor;
  }
 }
 for (var zxc2=5;zxc2<zxcp.ary.length;zxc2++){
  zxcp.ary[zxc2].level=0;
  zxcobj=zxcp.ary[zxc2];
  while (zxcobj.parentNode!=zxcp){
   zxcp.ary[zxc2].level++;
   zxcobj=zxcobj.parentNode;
  }
  zxcp.ary[zxc2].slave.level=zxcp.ary[zxc2].level;
  zxcp.ary[zxc2].slave.style.display='none';
  zxcp.ary[zxc2].img=zxcsimg;
  zxcp.ary[zxc2].style.listStyleImage='url('+zxcsimg[1]+')';
 }
 if (zxcGetCookie(zxcid)){
  zxcookie=zxcGetCookie(zxcid).split('|');
  for (var zxc4=0;zxc4<zxcookie.length;zxc4++){
   for (var zxc5=5;zxc5<zxcp.ary.length;zxc5++){
    if (zxcp.ary[zxc5].nu==zxcookie[zxc4]){
     zxcp.ary[zxc5].slave.style.display='';
     zxcp.ary[1].push(zxcp.ary[zxc5].nu);
     zxcp.ary[zxc5].style.listStyleImage='url('+zxcsimg[2]+')';
    }
   }
  }
  zxcSetFormCookie(zxcid,zxcp.ary[1].join('|'));
 }
 if (zxcp.ary[2]&&window['zxcLines']){
  zxcLines(zxcp.ary);
 }
}

function zxcDisplay(zxce){
 zxce.cancelBubble=true;
 if (zxce.stopPropagation){ zxce.stopPropagation(); }
 if (!this.slave){ return; }
 if (this.slave.style.display=='none'){
  this.slave.style.display='';
  this.ary[1].push(this.nu);
  this.style.listStyleImage='url('+this.img[2]+')';
 }
 else {
  this.slave.style.display='none';
  this.ary[1]=this.ary[1].remove(this.nu);
  this.style.listStyleImage='url('+this.img[1]+')';
 }
 for (var zxc0=5;zxc0<this.ary.length;zxc0++){
  if (this.ary[zxc0]!=this&&this.ary[zxc0].slave.level>=this.level){
   this.ary[zxc0].slave.style.display='none';
   this.ary[1]=this.ary[1].remove(this.ary[zxc0].nu);
   this.ary[zxc0].style.listStyleImage='url('+this.img[1]+')';
  }
 }
 zxcSetFormCookie(this.ary[0].id,this.ary[1].join('|'));
 if (this.ary[2]&&window['zxcLines']){
  zxcLines(this.ary);
 }
}

function zxcLines(zxcary){
 zxcary[3]=[];
 for (var zxc0=5;zxc0<zxcary.length;zxc0++){
  if (zxcary[zxc0].slave.style.display!='none'){
   zxcary[3].push(zxcary[zxc0]);
  }
 }
 for (var zxc7=0;zxc7<zxcary[4].length;zxc7++){
  zxcary[0].removeChild(zxcary[4][zxc7]);
 }
 zxcary[4]=[];
 var zxcbrd=(zxcary[2][0]+' '+zxcary[2][1]+' 1px')
 zxcdv=zxcMakeEle('DIV',{position:'absolute',overflow:'hidden',width:'2px',height:'100px',borderLeft:zxcbrd});
 zxcary[0].appendChild(zxcdv);
 zxcdh=zxcMakeEle('DIV',{position:'absolute',overflow:'hidden',width:'100px',height:'2px',borderTop:zxcbrd});
 zxcary[0].appendChild(zxcdh);
 var zxcdvc,zxcdhc;
 for (var zxc8=0;zxc8<zxcary[3].length;zxc8++){
  zxcdvc=zxcdv.cloneNode(false);
  zxcary[0].appendChild(zxcdvc);
  zxcary[4].push(zxcdvc);
  zxcdvc.style.left=(zxcary[3][zxc8].offsetLeft-zxcary[2][2])+'px';
  zxcdvc.style.top=(zxcary[3][zxc8].offsetTop+zxcary[2][3]*2)+'px';
  zxcdvc.style.height=(zxcary[3][zxc8].slave.ary[zxcary[3][zxc8].slave.ary.length-1].offsetTop-zxcary[3][zxc8].offsetTop-zxcary[2][3])+'px';
  for (var zxc9=0;zxc9<zxcary[3][zxc8].slave.ary.length;zxc9++){
   zxcdhc=zxcdh.cloneNode(false);
   zxcary[0].appendChild(zxcdhc);
   zxcary[4].push(zxcdhc);
   zxcdhc.style.left=zxcdvc.style.left;
   zxcdhc.style.top=(zxcary[3][zxc8].slave.ary[zxc9].offsetTop+zxcary[2][3])+'px';
   zxcdhc.style.width=(zxcary[3][zxc8].slave.ary[zxc9].offsetLeft-zxcdvc.offsetLeft-zxcary[2][2]*2)+'px';
  }
 }
 zxcary[0].removeChild(zxcdv);
 zxcary[0].removeChild(zxcdh);
}

function zxcMakeEle(zxctype,zxcstyle){
 var zxcele=document.createElement(zxctype);
 if (zxcstyle){
  for (key in zxcstyle){ zxcele.style[key]=zxcstyle[key]; }
 }
 return zxcele;
}

Array.prototype.remove=function(zxcremi){
 for (this.i=0;this.i<this.length;this.i++){
  if (this[this.i]==zxcremi){
   this.splice(this.i,1);
  }
 }
 return this;
}

function zxcEventAdd(zxco,zxct,zxcf) {
 if ( zxco.addEventListener ){ zxco.addEventListener(zxct, function(e){ zxco[zxcf](e);}, false); }
 else if ( zxco.attachEvent ){ zxco.attachEvent('on'+zxct,function(e){ zxco[zxcf](e); }); }
 else {
  var zxcPrev=zxco["on" + zxct];
  if (zxcPrev){ zxco['on'+zxct]=function(e){ zxcPrev(e); zxco[zxcf](e); }; }
  else { zxco['on'+zxct]=zxco[zxcf]; }
 }
}

function zxcAddEvent(zxc,zxcfun,zxcevt){
 if (zxc.addEvent){ return; }
 zxc.addEvent=window[zxcfun];
 zxcEventAdd(zxc,zxcevt,'addEvent');
}

function zxcGetCookie(zxcnme){
 var zxcst=document.cookie.indexOf(zxcnme+"=");
 var zxclen=zxcst+zxcnme.length+1;
 if ((!zxcst)&&(zxcnme != document.cookie.substring(0,zxcnme.length))) return null;
 if (zxcst==-1) return null;
 var zxcend=document.cookie.indexOf(";",zxclen);
 if (zxcend==-1) zxcend=document.cookie.length;
 return decodeURI(document.cookie.substring(zxclen,zxcend));
}

function zxcSetFormCookie(zxcnme,zxcval){
 if (!zxcDays){ return; }
 document.cookie=zxcnme+"="+encodeURI(zxcval)+";expires="+zxcExp+";path=/;"
}

//-->

