//-----------------------------------------------------------------------
// Module name   : GtDropdown
// Author        : Paul Battersby
// Creation Date : Oct 03/08
//
// NOTE:
//   Place this "&#9660;" beside a menu title to show a down arrow which
//   indicates there is a dropdown
//
// Drop Down Tabs Menu- Author: Dynamic Drive (http://www.dynamicdrive.com)
// Created: May 16th, 07'
//
// This is the menu in use at Javascriptkit.com
//
// Usage:
//  <link href="gtDropdown.css" rel="stylesheet" type="text/css" >
//
//  <style type="text/css">
//    /* example of how to override default tab background colour */
//    .gtDropdown li a {
//      background-color: #ff0000; /* background tab colour */
//    }
//  </style>
//
//  <script type="text/javascript">
//    window.addEvent("domready",function() {
//      new GtDropdown("myMenu");
//    });
//  </script>
//
//    ...
//
//  <!-- menu tabs -->
//  <div id="gtDropdownHide"> <!-- used to hide the menu until it's ready -->
//    <div id="myMenu">
//    <ul>
//      <li><a href="http://www.javascriptkit.com">Home</a></li>
//      <li><a href="#" rel="tutorialdropdown">Tutorials &#9660;</a></li>
//      <li><a href="#" rel="refdropdown">References &#9660;</a></li>
//    </ul>
//    </div>
//
//    <!--1st drop down menu -->
//    <div id="tutorialdropdown">
//      <a href="http://www.javascriptkit.com/javatutors/">JavaScript Tutorials</a>
//      <a href="http://www.javascriptkit.com/howto/">Web Building Tutorials</a>
//    </div>
//
//    <!--2nd drop down menu -->
//    <div id="refdropdown" style="width: 150px;">
//      <a href="http://www.javascriptkit.com/filters/">IE Filters Reference</a>
//      <a href="http://www.javascriptkit.com/dhtmltutors/cssreference.shtml">CSS Reference</a>
//    </div>
//  </div>
//
//  NOTE:
//   - default width of each submenu is set in gtDropdown.css but can be
//     overridden by setting the style in the dropdown div (see above width:150px)
//
//  $Log: gtDropdown.js $
//  Revision 1.6  2009-11-06 13:43:21-04  Battersby
//  - updated for use with latest mootools
//
//  Revision 1.5  2009-03-18 09:14:45-04  Battersby
//  - added documentation
//  - added automatic hiding of menu until after formatting is applied
//
//  Revision 1.4  2009-02-06 15:04:25-04  Battersby
//  - corrected some documentation
//
//  Revision 1.3  2008-12-12 16:43:40-04  Battersby
//  - passes jsLint test
//
//  Revision 1.2  2008-10-05 11:44:02-04  Battersby
//  - corrected some documentation
//
//  Revision 1.1  2008-10-03 21:03:07-04  Battersby
//  Initial revision
//
//------------------------------------------------------------------------

//---------------------------- INCLUDE FILES -----------------------------

var GtDropdown = new Class({
  Implements: [Events, Options],

//----------------------------- CONSTANTS --------------------------------


//----------------------------- VARIABLES --------------------------------

  options : {
    disappeardelay   : 250, // set delay in miliseconds before menu disappears onmouseout
    disablemenuclick : true, // when user clicks on a menu item with a drop down menu,
                             //  disable menu item's link
    enableiframeshim : 1, //1 or 0, for true or false

    cssClass : "gtDropdown", // name of css class that is used by this

    hideId : "gtDropdownHide", // id of div that surrounds the entire menu that will be
                 // set to "block" after menu is ready. I have seen it happen
                 //  that the menu appears unformatted for a brief moment
                 // This will fix it


    // function to be called when something is complete
    onComplete : Class.empty
  },

  dropmenuobj: null,
  ie: document.all,
  firefox : document.getElementById&&!document.all,
  islinux: /Linux/i.test(navigator.userAgent),
  previousmenuitem : null,
  currentpageurl : window.location.href.replace("http://"+window.location.hostname, "").replace(/^\//, ""), //get current page url (minus hostname, ie: http://www.dynamicdrive.com/)


//----------------------------- FUNCTIONS --------------------------------

  //No need to edit beyond here////////////////////////

  getposOffset : function(what, offsettype){
		var totaloffset=(offsettype=="left")? what.offsetLeft : what.offsetTop;
		var parentEl=what.offsetParent;
      while (parentEl!==null){
				totaloffset=(offsettype=="left")? totaloffset+parentEl.offsetLeft : totaloffset+parentEl.offsetTop;
				parentEl=parentEl.offsetParent;
			}
		return totaloffset;
	},

  showhide : function(obj, e, obj2){ //obj refers to drop down menu, obj2 refers to tab menu item mouse is currently over
    if (this.ie || this.firefox) {
      this.dropmenuobj.style.left=this.dropmenuobj.style.top="-500px";
    }
		if (e.type=="click" && obj.visibility==hidden || e.type=="mouseover"){
      if (obj2.parentNode.className.indexOf("default")==-1) { //if tab isn't a default selected one
        obj2.parentNode.className="selected";
      }
      obj.visibility="visible";
      this.hidebanner();
    } else if (e.type=="click") {
      obj.visibility="hidden";
    }
	},

	iecompattest:function(){
    return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body;
	},

	clearbrowseredge:function(obj, whichedge){
    var edgeoffset=0;
    var windowedge;
		if (whichedge=="rightedge"){
      windowedge=this.ie && !window.opera? this.standardbody.scrollLeft+this.standardbody.clientWidth-15 : window.pageXOffset+window.innerWidth-15;
      this.dropmenuobj.contentmeasure=this.dropmenuobj.offsetWidth;
      if (windowedge-this.dropmenuobj.x < this.dropmenuobj.contentmeasure) { //move menu to the left?
        edgeoffset=this.dropmenuobj.contentmeasure-obj.offsetWidth;
      }
    } else {
      var topedge=this.ie && !window.opera? this.standardbody.scrollTop : window.pageYOffset;
      windowedge=this.ie && !window.opera? this.standardbody.scrollTop+this.standardbody.clientHeight-15 : window.pageYOffset+window.innerHeight-18;
      this.dropmenuobj.contentmeasure=this.dropmenuobj.offsetHeight;
			if (windowedge-this.dropmenuobj.y < this.dropmenuobj.contentmeasure){ //move up?
        edgeoffset=this.dropmenuobj.contentmeasure+obj.offsetHeight;
        if ((this.dropmenuobj.y-topedge)<this.dropmenuobj.contentmeasure) { //up no good either?
          edgeoffset=this.dropmenuobj.y+obj.offsetHeight-topedge;
        }
			}
      this.dropmenuobj.firstlink.style.borderTopWidth=(edgeoffset===0)? 0 : "1px"; //Add 1px top border to menu if dropping up
		}
    return edgeoffset;
	},

  dropit : function(obj, e, dropmenuID) {
    if (this.dropmenuobj){ //hide previous menu
      this.dropmenuobj.style.visibility="hidden"; //hide menu
      if (this.previousmenuitem && this.previousmenuitem!=obj){
        if (this.previousmenuitem.parentNode.className.indexOf("default")===-1) { //If the tab isn't a default selected one
          this.previousmenuitem.parentNode.className="";
        }
			}
    }
    this.clearhidemenu();
		if (this.ie||this.firefox){
      obj.onmouseout=function(){this.delayhidemenu(obj);}.bind(this);
      obj.onclick=function(){return !this.options.disablemenuclick;}.bind(this); //disable main menu item link onclick?
      this.dropmenuobj=document.getElementById(dropmenuID);
      this.dropmenuobj.onmouseover=function(){this.clearhidemenu();}.bind(this);
      this.dropmenuobj.onmouseout=function(e){this.dynamichide(e, obj);}.bind(this);
      this.dropmenuobj.onclick=function(){this.delayhidemenu(obj);}.bind(this);
      this.showhide(this.dropmenuobj.style, e, obj);
      this.dropmenuobj.x=this.getposOffset(obj, "left");
      this.dropmenuobj.y=this.getposOffset(obj, "top");
      this.dropmenuobj.style.left=this.dropmenuobj.x-this.clearbrowseredge(obj, "rightedge")+"px";
      this.dropmenuobj.style.top=this.dropmenuobj.y-this.clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+1+"px";
      this.previousmenuitem=obj; //remember main menu item mouse moved out from (and into current menu item)
      this.positionshim(); //call iframe shim function
		}
	},

	contains_firefox:function(a, b) {
    while (b.parentNode) {
      if ((b = b.parentNode) == a) {
        return true;
      }
    }
		return false;
	},

	dynamichide:function(e, obj2){ //obj2 refers to tab menu item mouse is currently over
    var evtobj=window.event? window.event : e;
    if (this.ie&&!this.dropmenuobj.contains(evtobj.toElement)) {
      this.delayhidemenu(obj2);
    } else if (this.firefox&&e.currentTarget!= evtobj.relatedTarget&& !this.contains_firefox(evtobj.currentTarget, evtobj.relatedTarget)) {
      this.delayhidemenu(obj2);
    }
	},

	delayhidemenu:function(obj2){
    this.delayhide=setTimeout( function() {
      this.dropmenuobj.style.visibility='hidden';
      this.showbanner();
      if (obj2.parentNode.className.indexOf('default')==-1) {obj2.parentNode.className='';}
    }.bind(this),this.options.disappeardelay); //hide menu
	},

	clearhidemenu:function(){
		if (this.delayhide!="undefined"){
      clearTimeout(this.delayhide);
      this.hidebanner();
		}
	},

	 hidebanner:function(){
      if (this.islinux) {
        document.getElementById('topbanner').style.visibility="hidden";
      }
		},

	 showbanner:function(){
      if (this.islinux) {
        document.getElementById('topbanner').style.visibility="visible";
      }
		},

	positionshim:function(){ //display iframe shim function
    if (this.options.enableiframeshim && typeof this.shimobject!="undefined"){
      if (this.dropmenuobj.style.visibility==="visible"){
        this.shimobject.style.width=this.dropmenuobj.offsetWidth+"px";
        this.shimobject.style.height=this.dropmenuobj.offsetHeight+"px";
        this.shimobject.style.left=this.dropmenuobj.style.left;
        this.shimobject.style.top=this.dropmenuobj.style.top;
			}
    this.shimobject.style.display=(this.dropmenuobj.style.visibility==="visible")? "block" : "none";
		}
	},

	hideshim:function(){
    if (this.options.enableiframeshim && typeof this.shimobject!="undefined") {
      this.shimobject.style.display='none';
    }
	},

  isSelected:function(menuurl){
    menuurl=menuurl.replace("http://"+menuurl.hostname, "").replace(/^\//, "");
    return (this.currentpageurl==menuurl);
  },

  //************************************************************************
  // Name   : initialize (constructor)
  //
  //  (string) menuid - id of div that contains the main menu
  //  (string) dselected - ?
  //  (object) options - (optional) configuration options. See options declaration
  //                     above for the available options
  //
  // Returns : (nothing)
  //*************************************************************************
  initialize : function(menuid,dselected,options) {
    var relvalue;
    var setalready=false;

    this.setOptions(options);

    $(menuid).addClass(this.options.cssClass);

    this.standardbody=(document.compatMode=="CSS1Compat")? document.documentElement : document.body; //create reference to common "body" across doctypes
    var menuitems=document.getElementById(menuid).getElementsByTagName("a");
		for (var i=0; i<menuitems.length; i++){
			if (menuitems[i].getAttribute("rel")){
        relvalue=menuitems[i].getAttribute("rel");
        document.getElementById(relvalue).firstlink=document.getElementById(relvalue).getElementsByTagName("a")[0];

       // add the submenu class
       $(relvalue).addClass(this.options.cssClass + "Sub");

       $(menuitems[i]).addEvent("mouseover",function(e) {
          var event = e;
          this.dropit(event.target, event, event.target.getAttribute("rel"));
        }.bind(this));
      }
      if (dselected=="auto" && !setalready && this.isSelected(menuitems[i].href)){
        menuitems[i].parentNode.className+=" selected default";
        setalready=true;
      } else if (parseInt(dselected)==i) {
        menuitems[i].parentNode.className+=" selected default";
      }
    } // end for

    // if a div is in use to hide the menu until the formatting is complete
    // reveal the menu
    if (this.options.hideId && $(this.options.hideId)) {
      $(this.options.hideId).setStyle("display","block");
    } // endif
  }

});
