<!-- Hide
/////////////////////////////////////////////////////////////////////////
// Generic code to manage hierarchical menu trees.
// 980810, Matti Hannus, matti.hannus@vtt.fi, http://cic.vtt.fi/hannus/
/////////////////////////////////////////////////////////////////////////
var n, dlev, gifloc, toggled=0;
var i0=0,j0=0; // *990817* Previous opened menu branch (i0 > j0)
var style,link,body;

function find(text) {  // Find menu item containing text
  var j, k=-1;
  for (j=1; j<=n; j++) {if (txt[j].indexOf(text)>=0) {k=j; break;}}
  return k;
}

function findtxt(i) {  // Find menu item containing txt[i] but not item i
  var j, k=-1;
  for (j=0; j<=n; j++) if (i!=j && txt[j].indexOf(txt[i])>=0) {k=j; break;}
  return k;
}

function menulevel(option) { // Count menu hierarchy level
  for (var l=0; l<10; l++) 
    if (option.substring(l,l+1)!=" " && option.substring(l,l+1)!=".") break;
  return l;
}

function levels(m) { // Show hierarchy levels
// To be called from client page. Warning: slow if m>2)
  for (var j=1; j<=n; j++) {
    if (lev[j]<=m) {
      if (sub[j]<0) sub[j]=-sub[j]; // Show levels 0...dlev on first time 
    }
  }
  browse();
}

function setup() {     // Initialize data structure for menu tree
  setup = new menutree.setup();        // Setup values
  dlev = setup.levl;     // Default visible menu levels
  gifloc=setup.gifs;     // Image location
  togmod=setup.tmod;     // Toggle mode = 0:one branch | 1=user control
  style =setup.styl;
  target=(setup.trgt==null)? "menumain" : setup.trgt;
  link =(setup.link==null) ? "" : setup.link;
  body =(setup.body==null) ? "<BODY>" : setup.body;
  font =(setup.font==null) ? "<FONT>" : setup.font;
//alert(dlev+"\n"+gifloc+"\n"+togmod+"\n"+style+"\n"+body);
  optionlist = new menutree.menu(100); // Menu definition
  n = optionlist.length; // Number of options in menu
  nxt = new array(n);  // Pointer to next record at same level
  sub = new array(n);  // Pointer to first record at deeper level
  lev = new array(n);  // Hierarchy level (root=0)
  txt = new array(n);  // Text of record
  cmt = new array(n);  // Comment text
  lnk = new array(n);  // Pointer to linked record
  tmp = new array(10); // Max 10 levels
  tog = new array(10); // *990817* Max 10 levels
  nxt[n] = 9999; sub[n] = 0; // Initialize last record
  var l;
  for (var i=0; i<=n; i++) {
    var option = optionlist[i];       // Syntax=".....Text!!Comment"
    var k = option.indexOf("!!");     // Extract comment text
    if (k>0) {
      cmt[i] = option.substring(k+2,option.length);
      l = k;
    } else {
      cmt[i] = "";
      l = option.length;
    }
    lev[i] = menulevel(option);       // Extract menu tree hierarchy level
    txt[i] = option.substring(lev[i],l); // Extract visible menu item text
    if (txt[i] == '<HR>') txt[i] = '<IMG SRC="' + gifloc + 'hr.gif" WIDTH=100 HEIGHT=5>';
    if (lev[i] == lev[i-1]) {         // Same level
      nxt[i-1] = i;                   // Pointer to next record
      sub[i-1] = 0;                   // No subrecord
    } else if (lev[i] > lev[i-1]) {   // Deeper level
      if (lev[i]-lev[i-1]>=2) 
        alert("Menu tree error detected\nin function setup:"
        + "\n\nHierarchy level increment > 1\nlev[" + (i-1) + "]=" 
        + lev[i-1] + "\nlev[" + i + "]=" + lev[i]); 
      tmp[lev[i-1]] = i-1;            // Store recno for missing nxt pointer 
      sub[i-1] = (lev[i]<= dlev) ? i:-i; // Show levels 0...dlev on first time 
    } else if (lev[i] < lev[i-1]) {   // Higher level
      nxt[i-1] = 0;                   // No next record
      sub[i-1] = 0;                   // No subrecord
      nxt[tmp[lev[i]]] = i;           // Set pending nxt pointer to this record
    }
  }
  for (var i=0; i<=n; i++) {          // Set links
    k = txt[i].indexOf("->");         // Link text
    if (k>=0) {
      txt[i] = txt[i].substring(k+2,txt[i].length);
      lnk[i] = findtxt(i);
      txt[i] = txt[lnk[i]];
      cmt[i] = cmt[lnk[i]];
    }
  }
  browse();      // Display menu tree
}

function browse() {  // Display menu tree for browsing
  var text = "<HTML><HEAD>";
  text += link;
  text += style +'</HEAD>';
  text += body;
  if (target!=" ") text += "<BASE TARGET='" + target + "'>";
//alert(text);
  text += "<TABLE WIDTH=320 BORDER=0><TR><FORM><TD 'NOWRAP'><NOBR>";
  text += font;
  var i=0, j=-1, counter=0, l;
  for (l=1; l<=10; l++) tmp[l]=0;
  while (i<=n)  {
    counter++;
//..Error control
    if (j == i) {
//     alert("while loop in function browse() stopped incrementing at i=" + i);
       break;
    }
//..Add | (vertical lines) or blanks to start of line
//  text += "<BR>";      
    if (lev[i]>0) {
      for (l=1; l<lev[i]; l++) {
        if (tmp[l]>i) text += "<IMG SRC='" + gifloc + "vline.gif' WIDTH=16 HEIGHT=13>"
        else text += "<IMG SRC='" + gifloc + "blank.gif' WIDTH=16 HEIGHT=13>";
      };
//....Add one of icons: [+]  [-]  |-  |_
      if (sub[i] > 0) {
         text += "<A HREF='blank.html' TARGET='debug'";
         text += " onClick='parent.toggle(" + i + ","+togmod+");'>";
         text += "<IMG SRC='" + gifloc + "minus.gif' WIDTH=16 HEIGHT=13 BORDER=0";
         text += " ALT='" + cmt[i] + "'></A>";
//       text += " ALT='" + i + "'></A>";
      } else if (sub[i] < 0) { 
         text += "<A HREF='blank.html' TARGET='debug'";
         text += " onClick='parent.toggle(" + i + ","+togmod+");'>";
         text += '<IMG SRC="' + gifloc;
         text += (i==toggled && i>0) ? 'plusr.gif' : 'plus.gif'; // Highlight toggled item
         text += '" WIDTH=16 HEIGHT=13 BORDER=0';
         text += " ALT='" + cmt[i] + "'></A>";
//       text += " ALT='" + i + "'></A>";
      } else if (nxt[i] > 0 && nxt[i] < 9999) {
         text += "<IMG SRC=" + gifloc;
         text += (i!=toggled)?"branch.gif":"branchr.gif";
         text += " WIDTH=16 HEIGHT=13";
         text += " ALT='" + cmt[i] + "'>";
      } else {
         text += "<IMG SRC=" + gifloc;
         text += (i!=toggled)?"elbow.gif":"elbowr.gif";
         text +  " WIDTH=16 HEIGHT=13";
         text += " ALT='" + cmt[i] + "'>";
      }
    };
    if (lnk[i]>0) text += "<I>";// Make linked item italic
    if (i==toggled && i>0 && sub[i]>0) text += "<IMG SRC='" + gifloc + "down.gif' WIDTH=10 HEIGHT=13>";
    text += txt[i];
    if (lnk[i]>0) text += "</I>";
    text += "<BR>";      // Moved at the end of line 28.11.2000
//..Continue to next visible record
    j=i;                        // Store previous recno for error control
    if (sub[i] > 0) {           // Goto subrecord 
       tmp[lev[i]] = nxt[i];
       i = sub[i];
    } else if (nxt[i] > 0) {    // Goto next record
       i = nxt[i];
    } else if (lev[i] > 0) {    // Goto next higher level record
       for (l=lev[i]; l>0; l--) {  
         if (tmp[l] > 0) {
           i = tmp[l];
           tmp[l] = 0;
           break;
         }
       }
    } else {                    // Root only is visible
       i=9999;
    }
  }
  text += "</FONT></FORM></NOBR></TD></TR></TABLE></BODY></HTML>";
  browser.document.open("text/html");
  browser.document.write(text);
  browser.document.close();
}

function togglemode(tm) {
  togmod=tm;
}

function toggle(i,mode) { // Toggles visibility of a menu tree subbranch
//alert("toggle "+i+" "+mode);
  if (mode!=0) {        // 0:Old, 1: One brach open at a time. *990817*
    if (sub[i]>0) {     // *990817* Hide
    } else {            // *990817* Show
//    alert("hide "+i0+" ... "+j0+"\nshow "+i); // *990817*
      if (i0!=0 && j0!=0 && j0!=top(i)) { // *990817*
        for (var k=j0; k<=i0; k++) {      // *990817*
          if (sub[k]>0) sub[k]=-sub[k];   // *990817*
        }               // *990817*
      }                 // *990817*
      i0=i;             // *990817*
      j0=top(i);        // *990817*
    }                   // *990817*
    l=lev[i];           // *990817*
    tog[l]=i;           // *990817*
//  alert("tog["+1+"]=" + tog[1]+"\ntog["+2+"]=" + tog[2]+"\ntog["+3+"]=" + tog[3]);  // *990817*
  }
  toggled = i;
  sub[i] = - sub[i]; 
  browse();
}

function show(text) { // Show menu item containing txt and all higher levels. *990817*
//alert("SHOW(" + text + ")");
  var i=0,j,k;
  for (j=1; j<=n; j++) {              // Loop down
    if (sub[j]>0) sub[j]=-sub[j];     // Hide all
    if (txt[j].indexOf(text)>=0 && i==0) i=j; // Find first occurrence of text
  }
  if (i==0) return 0;  // Searched item was not found
  l0=lev[i];
  toggled=i;                      // Highlight item
//alert("found in:"+ i + ", text="+txt[i]);
  if (sub[i]<0) sub[i]=-sub[i];   // Show found item = i
  if (i>1) {                      // Loop up from i to top level
    for (j=i-1; j>0; j--) {
      if (lev[j]<l0) {
        if (sub[j]<0) {           // Show higher levels
          sub[j]=-sub[j]; 
//        alert(txt[j]+"\nj="+j+"\nlev["+j+"]="+lev[j]+",  l0="+l0);
          l0=lev[j];
        }
      } else {                    // Hide all other branches
        if (sub[j]>0) sub[j]=-sub[j];
      } 
      if (l0==1) break;
    }
  }
//alert("top in:"+ j + ", text="+txt[j]);
  browse();
  return i;
}

function top(i) {  // Find pointer to topmost record 
  k=i;
  while (k>0) {
//  alert("lev["+k+"]="+lev[k]+":"+txt[k].substring(15,45));
    if (lev[k]==1) break;
    k--;
  }
  return k;
}

function array(n) {  // Constructor for array
  this.length = n;
  for (var i=0; i <=n; i++) this[i]=0;
  return this;
}

function list() {    // List data structure for debugging
  var text = "<HTML><BODY BGCOLOR='#AAAAAA'><CENTER><H1>Menu tree structure</H1><TABLE BGCOLOR='#CCCCCC' CELLSPACING=0 BORDER=1><TR BGCOLOR='#BBBBBB'><TH>&nbsp;i&nbsp;</TH><TD><B>txt[i]</B></TD><TH>lev[i]</TH><TH>nxt[i]</TH><TH>sub[i]</TH><TH>lnk[i]</TD></TR>";
  var t = "</TD><TD ALIGN=CENTER>";
  for (var i=0; i<=n; i++) {
    text += "<TR><TD ALIGN=CENTER>" + i + "</TD><TD BGCOLOR='#FFFFFF'>";
    for (var l=1; l<=lev[i]; l++) text += (l<lev[i]) ? "| . " : "|-";
    text += txt[i] + t + lev[i] + t + ((nxt[i]!=0)?nxt[i]:"&nbsp;") + t + ((sub[i]!=0)?sub[i]:"&nbsp;") + t + ((lnk[i]>0)?lnk[i]:"&nbsp;") + "</TD></TR>"; 
  }
  text += "</TABLE></CENTER></BODY></HTML>";
  menumain.document.open("text/html");
  menumain.document.write(text);
  menumain.document.close();
}
// End hide -->

