var menu = null;

var userAgent = navigator.userAgent.toLowerCase();



function Menu(section,subsection,layeredFlash) {

  /*

   Funky animated menu object

   ==========================

   Arguments:

   -----------------

   section       // (int) section (if any) to show as "highlighted" (fixed open, static)

   subsection    // (int) subsection (if any) to highlight

   layeredFlash  // (boolean) apply nav logic (or not) based on flash layering support - dependant also on flash embedding support

  */

  var self = this;

  this.menu = null;

  this.menuID = 'menu'; // menu container element ID

 // if (typeof(layeredFlash)=='undefined') {

    layeredFlash = false;

 // } else {

    // logical AND with flash support check

    // enable menu drop-down if flash not supported (but is flagged as being on this page)

    //layeredFlash &= flash.hasVersion(5);

 // }

  this.containers = [];

  this.frames = [1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1];

  this.tweens = [];

  this.menuGroups = [];

  this.menuHeight = [];

  this.menuItems = [];

  this.items = [];

  this.itemCount = 0;

  

  this.createTweens = function() {

    // Generate array of pixel offsets for nav containers

    for (var i=0; i<this.containers.length; i++) {

      this.tweens[i] = [0];

      this.tmp = 0;

      menuOffset = userAgent.isIE?10:9;

      for (var j=0; j<this.frames.length; j++) {

        this.tmp += ((this.menuHeight[i]+menuOffset)*(this.frames[j]*.01));

        this.tweens[i][this.tweens[i].length] = parseInt(this.tmp);

      }

      this.tweens[i][this.tweens[i].length] = this.menuHeight[i]+menuOffset;

    }

  }

  

  this.findNode = function(n) {

    // find a non-text node

    if (!n || !n.nodeType) return null;

    while (n.nodeType==3 && n.parentNode) {

      n = n.parentNode;

    }

    return n;

  }

  

  this.isChildOfId = function(targetId, target) {

    if (!target) return false;

    do {

      if (target.id && target.id.indexOf(targetId)+1) {

        return true;

      } else if (target.parentNode) {

        target = target.parentNode;

      }

    } while (target.parentNode && target.parentNode.nodeName != 'BODY');

    return false;

  }

  

  this.init = function() {

    // Grab items and create menu item objects, assign event handlers

    this.menu = document.getElementById(this.menuID);

    itemsTmp = this.menu.getElementsByTagName('li');

    for (var i=0; i<itemsTmp.length; i++) {

      if (itemsTmp[i].className && itemsTmp[i].className.indexOf('nav-groups')+1) {

        this.menuGroups[this.menuGroups.length] = itemsTmp[i];

        // only add to item count if menu has sub-items

        if (this.menuGroups[this.menuGroups.length-1].getElementsByTagName('ul').length) this.itemCount++;

      }

    }

    if (this.supported) {

      // remove CSS offset for static containers

      for (i=0; i<this.itemCount; i++) {

        if (section != i) {

          // don't remove padding from "stuck" open section

          document.getElementById('sub-group'+i).style.paddingTop = '0px';

        } else if (section == i && subsection+1) {

          // show highlighted sub-menu item, if applicable

          document.getElementById('nav-group'+i).getElementsByTagName('a')[subsection].className = 'active';

        }

      }

    }

    for (i=0; i<this.itemCount; i++) {

      // create container objects and nav item objects

      this.containers[i] = this.menuGroups[i].getElementsByTagName('ul')[0];

      this.menuHeight[i] = this.containers[i].offsetHeight; // height plus offset of margin

      this.menuItems[i] = new this.MenuItem(i);

      if (this.supported) {

        // supported browsers: assign animation event handlers or show static based on global "section" variable

        this.menuItems[i].show();

        if (section !=i) {

          // roll up menu if not selected

          this.containers[i].style.marginTop = ((this.menuHeight[i])*-1)+'px';

        }

      } else {

        // unsupported browsers: point to static show/hide function instead

        this.menuItems[i].move = this.menuItems[i].moveStatic;

        if (section == i && subsection+1) {

          document.getElementById('nav-group'+i).getElementsByTagName('a')[subsection].className = 'active';

        }

      }

      if ('nav-group'+section != this.menuGroups[i].id) {

        // Assign event handler to top-level anchor tag

        handler = this.menuItems[i].eventHandler;

        this.menuGroups[i].getElementsByTagName('a')[0].onmouseover = handler;

        this.menuGroups[i].getElementsByTagName('a')[0].onmouseout = handler;

        this.menuGroups[i].getElementsByTagName('div')[1].onmouseout = handler;

      } else {

        // do not assign event handlers - show nav and leave open

        this.menuItems[i].show();

      }

    }

  }

  

  this.ns6Fix = function() {

    // netscape 6.x "invisible links/disappearing float" nav workaround (strange browser bug?)

    // fix: change a display property of menu container (causing a reflow)

    document.getElementById(this.menuID).style.width='100%';

  }

  

  this.MenuItem = function(menuIndex) {

    this.direction = null;

    this.menuIndex = menuIndex;

    this.frameIndex = 0;

    this.defaultClassName = '';

    this.timers = [];

    this.active = 0;

    var me = this;

    

    this.animate = function() {

      if (this.frameIndex<0 || this.frameIndex>self.tweens[this.menuIndex].length) {

        this.frameIndex = 0;

      } else {

        if (this.frameIndex >= self.tweens[this.menuIndex].length) {

        } else {

          self.containers[this.menuIndex].style.marginTop = (self.menuHeight[menuIndex]*-1)+(this.direction==1?0:-1)+(self.tweens[this.menuIndex][this.frameIndex])-(4)+'px';

        }

      }

      this.frameIndex += this.direction;

    }



    this.reset = function(msg) {

      // reset after previous animation

      this.active = 0;

      this.timers = [];

      // catch potential frame mis-counts from excessive event firing

      if (this.frameIndex >= self.tweens[this.menuIndex].length) {

        this.frameIndex = self.tweens[this.menuIndex].length-1;

      }

    }

    

    this.clearTimers = function() {

      for (var i=0; i<this.timers.length; i++) {

        clearTimeout(this.timers[i]);

      }

      this.timers = [];

    }



    this.eventHandler = function(e) {

      e = e||window.event;

      if (e.relatedTarget || e.target) {

        var eRelatedTarget = self.findNode(e.relatedTarget);

        var eTarget = self.findNode(e.target);

      }

      if (e.type == 'mouseover' && !e.srcElement) {

        // W3C-style mouseover

        if (e.target == this) {

          me.move(1);

        } else if (e.target) {

          // me.move(1,e);

        }

      } else if (e.type == 'mouseover') {

        // IE-style mouseover

        me.move(1);

      } else if (e.type == 'mouseout' && !e.srcElement) {

        // W3C-style mouseout

        if (e.target == this) {

          if (!menu.isChildOfId('nav-group'+me.menuIndex,eRelatedTarget)) {

            me.move(-1);

          }

        } else if (!menu.isChildOfId('nav-group'+me.menuIndex,eRelatedTarget)) {

          // not related, nor a child.

          me.move(-1);

        }

      } else if (e.type == 'mouseout') {

        // IE-style mouseout

        if (!menu.isChildOfId('nav-group'+me.menuIndex,e.toElement)) {

          me.move(-1);

        }

      }

    }

    

    this.hide = function() {

      with (self.containers[me.menuIndex].style) {

        if (visibility != 'hidden') visibility = 'hidden';

      }

    }

    

    this.show = function() {

      with (self.containers[me.menuIndex].style) {

        if (visibility != 'visible') visibility = 'visible';

      }

    }

    

    this.moveStatic = function(direction,evt) {

      if (direction==1) {

        me.show();

      } else {

        me.hide();

      }

    }

    

    this.move = function(direction) {

      if (this.active == 0) {

        // not currently moving

        this.clearTimers();

        if (this.frameIndex>1 && direction==1) {

          return false;

        } 

        this.active = 1;

        this.direction = direction;

        this.timeout = 0;

        for (var i=0; i<self.tweens[this.menuIndex].length; i++) {

          this.timeout += 20;

          this.timers[this.timers.length] = setTimeout("menu.menuItems["+this.menuIndex+"].animate()",this.timeout);

        }

        this.timers[this.timers.length] = setTimeout("menu.menuItems["+this.menuIndex+"].reset()",this.timeout);

      } else {

        // nav is currently moving

        this.clearTimers();

        this.reset();

        this.timeout = 0;

        this.direction = (this.direction==-1?1:-1);

        if (this.direction==1) {

          for (var i=this.frameIndex; i<self.tweens[this.menuIndex].length; i++) {

            this.timeout += 20;

            this.timers[this.timers.length] = setTimeout("menu.menuItems["+this.menuIndex+"].animate()",this.timeout);

          }

        } else {

          for (var i=this.frameIndex; i>0; i--) {

            this.timeout += 20;

            this.timers[this.timers.length] = setTimeout("menu.menuItems["+this.menuIndex+"].animate()",this.timeout);

          }

        }

        this.timers[this.timers.length] = setTimeout("menu.menuItems["+this.menuIndex+"].reset()",this.timeout);

      }

    }

    

  } // MenuItem

  

  // Menu() constructor

  

  // determine browser type, assign animate handlers only where supported

  this.supported = true;

  

  if (userAgent.isMac && layeredFlash) {

    // Mac has issues with reliably layering HTML overtop of Flash - disable nav dropdown

    this.supported = false;

    return null;

  }

  

  if (userAgent.isMac && (userAgent.isSafari || userAgent.isIE || userAgent.equivalentMozilla < 1.0)) {

    this.supported = false;

  } else if (userAgent.isMac && userAgent.equivalentMozilla>=1.1 && !layeredFlash) {

    this.supported = true;

  } else if (userAgent.isMac) {

    this.supported = false;

  } else if (userAgent.isWin32) {

    if ((userAgent.isNS && userAgent.equivalentMozilla<1.1) || userAgent.isNS6x) {

      this.supported = false;

    }

  }

  

  if (userAgent.isNS6x) {

    // check for netscape 6 display bug

    setTimeout("menu.ns6Fix()",20); // give time to react - may be related to dynamic flash insert

  }

  

  if (layeredFlash) {

    // test for flash "layering" support

    if (userAgent.isWin) {

      if (!userAgent.isNS && !userAgent.isIE) {

        return false;

      }

    }

    if (userAgent.isNS && userAgent.equivalentMozilla < 1) {

      return false;

    }

  }

  

  this.init();

  this.createTweens();

}