function scroll_start(dir) {
   var y=getY(this.pane);  var h=this.pane.expandedHeight;
   if (dir<0 ? y+h > this.navBottom : y < 0) {
      this.timeoutId=this.win.setTimeout("top.Nav.scroll_glide("+dir+")", this.scrollDelay);
   }
}

function move_pane(me, delta) {
   var y=getY(me.pane);  var h=me.pane.expandedHeight;
   if (delta<0) {
      if (y+delta+h < me.navBottom) {
	 setY(me.pane, me.navBottom-h);
	 return false;
      }
   } else {
      if (y+delta > 0) {
	 setY(me.pane, 0);
	 return false;
      }
   }
   incrY(me.pane, delta);
   return true;
}

function scroll_glide(dir) {
   if (this.timeoutId) {
      this.win.clearTimeout(this.timeoutId);
      this.timeoutId=undefined;
   }
   if (move_pane(this, dir*this.scrollStep))
      this.timeoutId=this.win.setTimeout("top.Nav.scroll_glide("+dir+")", this.scrollTimer);
}

function scroll_click(delta) {
   this.scroll_stop();
   move_pane(this, delta*this.navBottom);
}

function scroll_stop() {
   if (this.timeoutId) {
      this.win.clearTimeout(this.timeoutId);
      this.timeoutId=undefined;
   }
}

function check_scroll_active(me) {
   var nav=me.pane;
   if (nav.expandedHeight <= me.navBottom) {
      setY(nav,0);
      setVisibility(me.scroll_arrows, "hidden");
   } else {
      var excess = nav.expandedHeight - me.navBottom;
      var bottom_gap = excess + getY(nav);
      if (bottom_gap < 0) incrY(nav, -bottom_gap);
      setVisibility(me.scroll_arrows, "visible");
   }
}

function tell_expand() {
   window.status= this.containingLayer.isExpanded ? "Collapse subtopics" : "Expand subtopics";
   return true;
}

function toggle_me() {
   var nav=top.Nav;
   if (nav.highlighted) {
      setBgColor(nav.highlighted, nav.win.document.bgColor);
      nav.highlighted=null;
   }
   nav.toggle(this.containingLayer, this);
   return false;
}

function highlight(level) {
   var l = this.pane;
   var y = getY(l);
   var layers = getLayers(l);
   for (var i=0; i<level.length; ++i) {
      l=layers[level[i] + l.firstSubtopic];
      if (i<level.length-1) {
	 if (!l.isExpanded) {
	    this.toggle(l);  y=undefined;
	 }
      }
      if (y !== undefined) y+=getY(l);
      layers = getLayers(l);
   }
   if (this.highlighted) setBgColor(this.highlighted, this.win.document.bgColor);
   this.highlighted= layers && layers.length ? layers[0] : l;
   setBgColor(this.highlighted, this.win.highlightColor);
   if (y != undefined) {
      if (y<0) {
	 incrY(this.pane, -y);
	 check_scroll_active(this);
      } else if ((y += getH(this.highlighted)-this.navBottom)>0) {
	 incrY(this.pane, -y);
	 check_scroll_active(this);
      }
   }
}

function init_layer(l, w, expand_now) {
   var layers = getLayers(l);
   var x=0; var y=0; var h=0;
   l.isExpanded = expand_now || this.saved_state && this.saved_state.shift();
   if (expand_now) {
      var own_topic=layers[0];
      var arrow = getImage(l);
      arrow.src = this.collapseURL;
      x = arrow.width;
      y = getH(own_topic);
   } else {
      if (layers.length) {
	 if (l != this.pane) {
	    var arrow = getImage(l);
	    if (l.isExpanded) arrow.src = this.collapseURL;
	    x = arrow.width;
	    var own_topic=layers[0];
	    setX(own_topic, x);
	    setY(own_topic, 0);
	    setW(own_topic, w);
	    y = getH(own_topic);
	    var link = getLink(l);
	    link.containingLayer = l;
	    link.onmouseover=tell_expand;
	    link.onclick=toggle_me;
	    setVisibility(own_topic, "inherit");
	    l.availableWidth = w;
	    l.firstSubtopic=1;
	 } else {
	    l.firstSubtopic=0;
	 }
      } else {
	 setW(l, w);
	 return getH(l);
      }
   }
   if (l.isExpanded) {
      for (var i=l.firstSubtopic; i<layers.length; ++i) {
	 var subtopic=layers[i];
	 h += this.topicPadding;
         setX(subtopic, x);
	 setY(subtopic, y+h);
	 setVisibility(subtopic, "inherit");
	 if (i>l.firstSubtopic && !subtopic.siblingAbove)
	    layers[i-1].siblingAbove=subtopic;
	 h += this.init_layer(subtopic, w-x);
      }
      l.expandedHeight=h;
   }
   if (isNS4) {
      l.clip.height=y+h;
      l.clip.width=w;
   }
   return y+h;
}

function toggle(l,link) {
   var delta_h; var y_top=0; var y_bottom;
   if (l.expandedHeight == undefined) {
      y_bottom = Math.min(this.init_layer(l, l.availableWidth, true), this.navBottom);
      delta_h = l.expandedHeight;
   } else {
      var vis; var arrowURL;
      var layers = getLayers(l);
      var own_topic=layers[0];
      if (l.isExpanded) {
	 delta_h = -l.expandedHeight;
	 vis = "hidden";
	 arrowURL = this.expandURL;
	 l.isExpanded = false;
      } else {
	 delta_h = l.expandedHeight;
	 y_bottom = Math.min(getH(own_topic)+delta_h, this.navBottom);
	 vis = "inherit";
	 arrowURL = this.collapseURL;
	 l.isExpanded = true;
      }
      getLinkImage(l,link).src = arrowURL;
      for (var i=1; i<layers.length; ++i) {
	 setVisibility(layers[i], vis);
      }
   }
   var nav = this.pane;
   while (true) {
      if (isNS4) l.clip.height += delta_h;
      if (y_bottom !== undefined) {
	 var y=getY(l);
	 y_top+=y; y_bottom+=y;
      }
      if (l == nav) break;
      while (l.siblingAbove) {
	 l=l.siblingAbove;
	 incrY(l, delta_h);
      }
      l=getParent(l);
      l.expandedHeight += delta_h;
   }
   if (y_bottom !== undefined) {
      if (y_top<0)
	 incrY(nav, -y_top);
      else if ((y_bottom-=this.navBottom)>0)
	 incrY(nav, -y_bottom);
   }
   check_scroll_active(this);
}

function save_state(l) {
   this.saved_state.push(l.isExpanded);
   if (l.isExpanded) {
      var layers=getLayers(l);
      for (var i=l.firstSubtopic; i<layers.length; ++i)
	 this.save_state(layers[i]);
   }
}

function repaint() {
   if (this.curHeight != winH(this.win) || this.curWidth != winW(this.win)) {
      if (isNS4) top.document.location.reload();
      this.saved_state=new Array;
      this.save_state(this.pane);
      this.win.document.location.reload();
   }
}

function init_pane(win) {
   this.win=win;
   var doc=win.document;
   this.curHeight=winH(win);
   this.curWidth=winW(win);
   var nav = getById(doc, "navigation");
   this.pane=getFirstChild(nav);
   var side_margin=getX(nav);
   this.topicPadding=getY(nav);
   if (!this.expandURL) {
      this.expandURL = getFirstImage(this.pane).src;
      this.collapseURL = this.expandURL.replace("expand","collapse");
   }

   this.shortcuts = getById(doc,"shortcuts");
   this.scroll_arrows = getById(doc,"scroll_arrows");
   var arrowH = getH(this.scroll_arrows);
   this.navBottom = winH(win) - getH(this.shortcuts) - arrowH;
   setZ(nav, 1);
   setY(this.scroll_arrows, this.navBottom);
   setY(this.shortcuts, this.navBottom+arrowH);
   var WW=winW(win);
   if (top.isOpera) setVisibleW(this.scroll_arrows, WW);
   /***
      setVisibleW(this.shortcuts, WW);
      setBgColor(this.scroll_arrows, this.bgColor);	// make them non-transparent
      setBgColor(this.shortcuts, this.bgColor);
      setZ(this.scroll_arrows, 2);
      setZ(this.shortcuts, 2);
   ***/
   WW-=2*side_margin;
   if (!top.isNS4) {
      setW(nav, WW);
      setH(nav, this.navBottom);
   }
   setClip(nav, WW, this.navBottom);

   setVisibility(nav, "visible");
   setVisibility(this.shortcuts, "visible");

   if (!this.saved_state) this.saved_state=[ true ];
   this.init_layer(this.pane, WW-2*side_margin);
   delete this.saved_state;
   check_scroll_active(this);
   if (isNS4) win.captureEvents(Event.RESIZE);
   win.onresize=function() { top.Nav.repaint() }
}

function Nav_handler() {
   this.win=undefined;
   this.pane=undefined;
   this.scroll_arrows=undefined;
   this.shortcuts=undefined;
   this.navBottom=0;
   this.topicPadding=0;
   this.collapseURL=undefined;
   this.expandURL=undefined;
   this.curHeight=0;
   this.curWidth=0;

   this.init_pane=init_pane;
   this.init_layer=init_layer;
   this.toggle=toggle;
   this.repaint=repaint;
   this.highlight=highlight;
   this.save_state=save_state;
   this.scroll_start=scroll_start;
   this.scroll_glide=scroll_glide;
   this.scroll_click=scroll_click;
   this.scroll_stop=scroll_stop;
   this.timeoutId=undefined;
}

var Nav=new Nav_handler();
