
var isIE = navigator.appName.toLowerCase().indexOf('internet explorer')+1;
var isMac = navigator.appVersion.toLowerCase().indexOf('mac')+1;


var nAV = navigator.appVersion.toLowerCase();
var nUA = navigator.userAgent.toLowerCase();
var nP = navigator.platform.toLowerCase();
var isIE = nAV.indexOf('msie')!=-1;
var isIE6 = (nAV.indexOf('msie 6')!=-1 || nAV.indexOf('msie 5')!=-1);
var isFirefox = (nUA.indexOf('firefox')!=-1);
var isOpera = (nUA.indexOf('opera')!=-1);
var isSafari = (nUA.indexOf('safari')!=-1);
var isWin32 = (nP.indexOf('win')!=-1);
var isMac = (nP.indexOf('mac')!=-1);
if (isOpera) {
  isIE = false;
  isIE6 = false;
}

var gapmagicnumber=6;

function $(sID) {
  return document.getElementById(sID);
}

var tStart = new Date();


function Animator() {
  var self = this;
  this.timer = null;
  this.active = null;
  this.methods = [];
  this.tweenStep = [1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2];
  
  this.start = function() {
    if (self.active==true) return false;
    self.active = true;
    self.timer = window.setInterval(self.animate,20);
  }

  this.stop = function() {
    if (self.timer) {
      window.clearInterval(self.timer);
      self.timer = null;
      self.active = false;
    }
  }

  this.reset = function() {
    self.methods = [];
  }

  this.addMethod = function(oMethod,oncomplete) {
    for (var i=self.methods.length; i--;) {
      if (self.methods[i] == oMethod) {
        if (oncomplete) {
          self.methods[i]._oncomplete = oncomplete;
        }
        return false;
      }
    }
    self.methods[self.methods.length] = oMethod;
    self.methods[self.methods.length-1]._oncomplete = oncomplete||null;
  }

  this.createTween = function(start,end) {
    var start = parseInt(start);
    var end = parseInt(end);
    var tweenStepData = self.tweenStep;
    var tween = [start];
    var tmp = start;
    var diff = end-start;
    var j = tweenStepData.length;
    var isAscending = end>start;
    // alert('start, end, isAscending: '+start+','+end+','+isAscending);
    for (var i=0; i<j; i++) {
      tmp += diff*tweenStepData[i]*0.01;
      tween[i] = parseInt(tmp);
      // floor/ceiling checks (rounding errors?)
      if (isAscending) {
        if (tween[i]>end) tween[i] = end;
      } else {
        if (tween[i]<end) tween[i] = end;
      }
    }
    if (tween[i] != end) tween[i] = end;
    return tween;
  }
  
  this.animate = function(e) { 
    if (!self.active) return false;
    var active = false;
    for (var i=self.methods.length; i--;) {
      if (self.methods[i]) {
        if (self.methods[i]()) {
          active = true;
        } else {
          if (self.methods[i]._oncomplete) {
            self.methods[i]._oncomplete();
            self.methods[i]._oncomplete = null;
          }
          self.methods[i] = null;
        }
      }
    }
    if (!active) {
      self.stop();
      self.reset();
    }
  }

}

var animator = new Animator();



function getOffY(o) {
  var curtop = 0;
  if (o.offsetParent) {
    while (o.offsetParent) {
      curtop += o.offsetTop;
      o = o.offsetParent;
    }
  } else if (o.y) {
    curtop += o.y;
  }
  return curtop;
}


function classContains(o,sClass) {
  if (typeof(o.className)=='undefined' || !o.className) return false;
  var sC = o.className;
  return (sC==sClass || sC.indexOf(sClass+' ')+1 || sC.indexOf(' '+sClass)+1);
}

function addClass(o,sClass) {
  if (classContains(o,sClass)) return false;
  o.className = (o.className?o.className+' ':'')+sClass;
}

function removeClass(o,sClass) {
  if (!classContains(o,sClass)) return false;
  // need to use regexp
  o.className = o.className.replace(sClass+' ','');
  o.className = o.className.replace(' '+sClass,'');
  o.className = o.className.replace(sClass,'');
}












function NavElement(o,oInner,index) {

  var self = this;
  var needsCSSHelp = (isIE || isSafari || isOpera); // these don't handle css { dt:hover + dd } at all, or are buggy in this particular case - handled instead via JS
  this.o = o;
  this.oInner = oInner;
  this.oHeader = null;
  this.isOpen = false;
  this.tween = null;
  this.tweenOpen = [];
  this.tweenClose = [];
  this.frame = 0;
  this.frameCount = 0;
  this.height = 0;
  this.index = index;
  this.unit = 'px';
  this.lastHover = null;

  this.getHeight = function() {
    self.height = parseInt(self.o.offsetHeight)+(!isOpera?6:0);
  }

  this.createTween = function() {
    self.tweenOpen = animator.createTween(-self.height,0);
    self.tweenClose = animator.createTween(0,-(self.height-gapmagicnumber)); // magic number to remove gap
    self.tween = self.tweenClose;
    self.frameCount = self.tween.length;
  }

  this.oMouseHandler = function(evt) {
    // support for non-:hover case
    // window.status = event.type;
    var e = evt?evt:window.event;
    if (e.type != 'mouseover' && e.type != 'mouseout') return;
    if (!needsCSSHelp) return true;
    if (e.type == 'mouseover') {
      // super-lame workaround for Safari - confuses mouseout/:hover or something - must manually remove hover on last element {
      if (isSafari && self.lastHover) {
        removeClass(self.lastHover,'hover');
      }
      addClass(this,'hover');
      self.lastHover = this;
    } else {
      removeClass(this,'hover');
    }
  }

  this.assignHandlers = function() {
    self.oHeader.onclick = function(){navController.toggle(self.index);animator.start();}
  }

  this.releaseHandlers = function() {
    self.oHeader.onclick = null;
  }

  this.animate = function() {
    self.oInner.style.marginTop = self.tween[self.frame]+self.unit;
    if (self.tween == self.tweenOpen) {
      // if moving up off-screen, scroll.
      var oY = getOffY(self.oHeader);
      var wY = isIE?document.documentElement.scrollTop:window.scrollY;
      if (wY > oY) {
        // window.scrollTo(0,oY);
        if (isIE) {
          self.oHeader.scrollIntoView();
        } else {
          window.scrollTo(0,oY);
        }
      }
    }
    return (++self.frame<self.frameCount);
  }

  this.oncomplete = function() {

    self.frame = 0;
  }

  this.aniStart = function() {

  }

  this.open = function(fOncomplete) {

    if (self.isOpen) return false;
    self.isOpen = true;
    self.tween = self.tweenOpen;
    animator.addMethod(self.animate,fOncomplete||self.oncomplete);
    self.aniStart();
  }

  this.close = function(fOncomplete) {

    if (!self.isOpen) return false;
    self.isOpen = false;
    self.tween = self.tweenClose;
    animator.addMethod(self.animate,fOncomplete||self.oncomplete);
    self.aniStart();
  }

  this.init = function() {
    self.oHeader = self.o.parentNode.getElementsByTagName('h4')[0];
    self.assignHandlers();
    self.getHeight();
    self.createTween();
    self.oInner.style.marginTop = self.tweenOpen[0]+self.unit;
  }

  this.destructor = function() {
    self.releaseHandlers();
    self.lastHover = null;
    self.o = null;
    self.oInner = null;
    self = null;
  }

}


function NavController() {

  var self = this;
  this.navElements = [];
  this.lastOpen = -1;

  this.init = function() {

    var oUL = $('nav').getElementsByTagName('ul')[0].getElementsByTagName('ul');
    for (var i=oUL.length; i--;) {
      self.navElements[i] = new NavElement(oUL[i],oUL[i].getElementsByTagName('li')[0],i);
      self.navElements[i].init();
    }
    
  }

  this.toggle = function(i) {
    (self.navElements[i].isOpen)?self.navElements[i].close():self.navElements[i].open();
    if (self.lastOpen>-1 && self.lastOpen != i) self.navElements[self.lastOpen].close();
    self.lastOpen = i;
  }
	
  this.destructor = function() {
    for (var i=self.navElements.length; i--;) {
      self.navElements[i].destructor();
      delete self.navElements[i];
    }
    self.navElements = null;
    self = null;
  }

}


var navController = new NavController();


function unload() {
  navController.destructor();
  navController = null;

}



function init() {

  navController.init();

	if (openmenu>-1) {
		navController.toggle(openmenu);
		animator.start();
	}
	
  window.onload = null;
  window.onunload = unload;
  
}




function preInit() {
	
  if (document.getElementById) {

    window.onload = init;
  } else {
    return false;
  }
  if (isIE && isIE6) { // silly IE, web standards are for good browsers!

    addClass(document.getElementsByTagName('html')[0],'ie6');
  }

  // hide nav
  $('nav').className = 'closed';
	
}
