// Made by Matt Haggard
// Apr 2007
//
// A simple, relatively easy-to-use drop-down menu system.
//
// Feel free to use/alter this code.  Just leave the credits here.

// ---------------------------------------------------------------
function SM_onload() {
  SM_productMenu.attachTo('sm_products');
  SM_registerMenu.attachTo('sm_register');
  SM_securityInfoMenu.attachTo('sm_securityinfo');
  SM_searchMenu.attachTo('sm_search');
  SM_buynowMenu.attachTo('sm_buynow');
}
var SM_buynowMenu = new MM_Menu({
  items: [
    ["Price List", "/pricelist.adp"],
  ],
  offsetX: -4
});
var SM_productMenu = new MM_Menu({
  items: [
    ["Site Certification", "/sitecertinfo.adp"],
    ["Appliance", "/securitymetricsappliance.adp"],
    ["Perimeter Check", "/networkcheckinfo.adp"],
    ["Desktop Check", "/securitycheck.adp"],
    ["Product Comparison", "/comparison_external.adp"],
    ["Penetration Testing","/pentest.adp"],
    ["Consulting Services", "/consulting.adp"],
    ["PCI Onsite Audits", "/pci_audits.adp"],
    ["PA-DSS Audits", "/padss_audit.adp"],
    ["Forensic Response", "/forensics.adp"],
    ["PTS", "/pts.adp"],
    ["FREE Port Scan", "/portscan.adp"]
  ],
  offsetX: -4
});
var SM_registerMenu = new MM_Menu({
  items: [
    ["Edit Profile", "/register_home.adp?action=edit"],
    ["Forgot Password", "/register_home.adp?action=forgot"]
  ],
  offsetX: -4
});
var SM_securityInfoMenu = new MM_Menu({
  items: [
    ["Information", "", {
      submenu: {
        placement: "right",
        offsetY: -5,
        items: [
          ["<nobr>IP Information</nobr>", "/ipinformation.adp"],
          ["<nobr>IP Sleuth</nobr>", "/ip_sleuth.adp"],
          ["<nobr>Port List</nobr>", "/portlist.adp"]
        ]
      },
      myclass: "MM_item_right",
      myhover: "MM_item_right_hover"
    }],
    ["Security Tools", "/securitytools.adp"],
    ["Acquirers", "/acquirer.adp"]
  ],
  offsetX: -4
});
var SM_searchMenu = new MM_Menu({
  preventHide: function() {
      return (document.getElementById('idx_search').hasfocus);
    },
  align: "right",
  items: [
    ["<form name=\"nav_search\" method=\"post\" action=\"search.adp\"><input type=\"text\" class=\"MM_input\" id=\"idx_search\" onfocus=\"this.hasfocus=true;\" onblur=\"this.hasfocus=false;\" name=\"q\"> <input class=\"MM_button\" value=\"Search\" type=\"submit\" name=\"SEARCH\"></form>","", {
      myhover: "MM_item_nohover"
    }],
    ["Site Map", "/sitemap.adp"]
  ],
  offsetX: 0
});
// ---------------------------------------------------------------



/*
Define the following in your style sheet (fill in any extra):
.MM_menu {
  cursor: pointer;
  _cursor: hand;
}
.MM_menu_hover { }
.MM_menu_active { }
.MM_menu .MM_item { }
.MM_menu .MM_item_hover { }
.MM_menu .MM_item_active { }
*/

/* ****************************************************************
Instructions:
The idea behind this drop-down menu is to first make the HTML, then
attach a menu to some HTML element you've already made.  For example,
if you have:

  <div id="somediv">Some text</div>
  
and you want to attach a menu to that div, you would use the following
JavaScript:

  var mymenu = new MM_Menu({
    items: [
      ["Apple", "apple.html"],
      ["Banana", "banana.html"],
      ["Orange", "orange.html"]
    ]
  });
  mymenu.attachTo("somediv");


All the options ----------------------------------------------------
When creating a menu, here's all of the options you can specify.  Make
sure to separate each with a comma.

  var mymenu = new MM_Menu({
    items: [ [] ],      // An array of items to put in the list (see above)
    
    offsetX: 10,        // shift the menu this number of pixels horizontally
    offsetY: -3,        // shift the menu this number of pixels vertically
    placement: "left",  // which way should the menu drop off?
                        // Can be "left", "right" or "below" (default)
    width: 200,         // Force the menu to be of a certain width
    
    mystyle: "...",     // Additional style to add to this particular menu
    myclass: "MenuCL",  // CSS class to use for this menu (default: MM_menu)
    myhover: "MenuCLH", // CSS class to use for when hovering over this menu (default: MM_menu_hover)
    myactive: "MenuA",  // !! Doesn't work !!
    
    preventHide: ...,   // Provide a function that returns a boolean result.
                        // The function should return true when you want the
                        // menu to remain hidden after someone has moved their
                        // mouse away.  It should return false when you want
                        // the menu to disappear when someone moves their mouse
                        // away.
                        // Example:
                            preventHide: function() {
                              return (document.getElementById('signin').value != "");
                            },
                        // The above function will not let the menu disappear while there
                        // is some text in 'signin' (it could be an input field inside
                        // one of the menu items)
  });
  
  
  SUBMENUS
  Use the "submenu" property to make submenus.  Set the second element as "" for
  each item that you don't want to have a link anywhere.
  
  The following will create a menu system like this:
                      First Item  ----->  Sub item 1
                      Second Item         Sub item 2
  Sub item A  <-----  Third Item          Sub item 3
  Sub item B
  Sub item C
  
  var mymenu = new MM_Menu({
    items: [
      ["First Item", "", {
        submenu: {
          placement: "right",
          items: [
            ["Sub item 1", "subitem.html?item=1"],
            ["Sub item 2", "subitem.html?item=2"],
            ["Sub item 3", "subitem.html?item=3"]
          ]
        }
      }],
      ["Second Item", "somewhere.html"],
      ["Third Item", "", {
        submenu: {
          placement: "left",
          items: [
            ["Sub item A", "subitem.html?item=A"],
            ["Sub item B", "subitem.html?item=B"],
            ["Sub item C", "subitem.html?item=C"]
          ]
        }
      }]
    ]
  });

***************************************************************** */




var hiddenpar = null;

// PopUpMenu class
function MM_Menu() {
  var MM_defaultMenuClass = "MM_menu";
  var MM_defaultMenuHover = "MM_menu_hover";
  var MM_defaultMenuActive = "MM_menu_active";
  
  var input = null;
  if (arguments.length == 1) {
    input = arguments[0];
  }
  this.offsetX = dft("offsetX", input, 0);
  this.offsetY = dft("offsetY", input, 0);
  this.placement = dft("placement", input, "below");
  this.align = dft("align", input, "left");
  this.width = dft("width", input, 0);
  this.keepshowing = false;
  this.menuItems = null;
  this.mydiv = null;
  this.parentDiv = null;
  this.preventHide = dft("preventHide", input, null);
  this.mystyle = dft("mystyle", input, "");
  this.myclass = dft("myclass", input, MM_defaultMenuClass);
  this.myhover = dft("myhover", input, MM_defaultMenuHover);
  this.myactive = dft("myactive", input, MM_defaultMenuActive);
  
  if (input.items) {
    if (this.menuItems == null) {
      this.menuItems = new Array();
    }
    for (var i = 0; i < input.items.length; i++) {     
      this.menuItems[this.menuItems.length] = new MM_Item(input.items[i]);
    }
  }
  
  function dft(valname, obj, defaultval) {
    if (obj) {
      return (obj[valname] ? obj[valname] : defaultval);
    } else {
      return defaultval;
    }
  }
  
  // tostring
  this.toString = function() {
    return "("+this.offsetX+","+this.offsetY+") mydiv:"+this.mydiv+" placement:"+this.placement;
  }
  
  // Show
  this.show = function(e) {
    who = (this.MM_menu ? this.MM_menu : this);
    
    // if it's an item, highlight it
    if (who.parentDiv.isMenuItem) {
      who.parentDiv.className = who.parentDiv.myclass+" "+who.parentDiv.myhover;
    }
    
    if (who.mydiv == null) {
      who.makeDiv();
    }
    if (who.mydiv.style.visibility != "visible") {
      who.rePosition();
      who.mydiv.style.visibility = "visible";
      // Widthisize all the elements
      if (who.placement != "left") {
        for (var i = 0; i < who.mydiv.childNodes.length; i++) {
          who.mydiv.childNodes[i].style.width = (who.width ? who.width : who.mydiv.offsetWidth);
        }
      }
    }
  };
  
  // Hide
  this.hide = function(e) {
    who = (this.MM_menu ? this.MM_menu : this);
    
    // if it's an item, highlight it
    if (who.parentDiv.isMenuItem) {
      who.parentDiv.className = who.parentDiv.myclass;
    }
    
    if (!e) var e = window.event;
    var relTarg = e.toElement || e.relatedTarget;
    // If the element it's going to should maintain visibility, then maintain it
    var par = relTarg;
    var cont = true;
    do {
      if (par && par.MM_menu) {
        // see if it has the same menu
        if (par.MM_menu == who) {
          who.keepshowing = true;
          break;
        } else {
          who.keepshowing = false;
        }
      } else {
        who.keepshowing = false;
      }
      try {
        cont = (par = par.parentNode);
      } catch (err) {
        cont = false;
      }
    } while ( cont );
      
    if (!who.keepshowing && !who.mydiv.mouseisover && (!who.preventHide || (who.preventHide && !who.preventHide()) ) ) {      
      if (hiddenpar == null) {
        hiddenpar = par;
      }
      try {
        var b = par.className;
        who.mydiv.style.visibility = "hidden";
      } catch (err) {
        // do nothing
        var st = ""+err;
        if (st.substr(0, 10) == "Permission") {
          // do nothing
        } else {
          who.mydiv.style.visibility = "hidden";
        }
      }
      
    }
  };
  
  // makeDiv
  this.makeDiv = function() {
    who = (this.MM_menu ? this.MM_menu : this);
    who.keepshowing = true;
    var newdiv = document.createElement('div');
    newdiv.className = who.myclass;
    newdiv.setAttribute("style",who.mystyle);
    newdiv.style.visibility = "hidden";
    newdiv.style.position = "absolute";
    
    // Create Menu Items
    for (var i = 0; i < who.menuItems.length; i++) {
      var mi = document.createElement('div');
      var thisitem = who.menuItems[i];
      
      var myclass = thisitem.myclass;
      var myhover = thisitem.myhover;
      var myactive = thisitem.myactive;
      
      if (thisitem.mystyle)
        mi.setAttribute("style",thisitem.mystyle);
      
      mi.className = myclass;
      
      mi.href = thisitem.href;
      if (mi.href != "" && mi.href) {
        mi.onclick = function(event) {
          window.location = this.href;
        };
      }
      mi.innerHTML = thisitem.label;
      newdiv.appendChild(mi);
      mi.onmouseover = function(event) {
        this.className = this.myclass+" "+this.myhover;
      }
      mi.onmouseout = function(event) {
        this.className = this.myclass;
      }
      mi.myclass = myclass;
      mi.myhover = myhover;
      mi.myactive = myactive;
      if (thisitem.submenu) {
        mi.isMenuItem = true;
        thisitem.submenu.attachTo(mi);
      }
    }
    
    who.mydiv = newdiv;
    
    who.parentDiv.appendChild(newdiv);
    
    newdiv.mouseisover = false;
    newdiv.onmouseover = function(event) {
      this.mouseisover = true;
    }
    newdiv.onmouseout = function(event) {
      this.mouseisover = false;
    }
    
    // Decide where this should go
    var position = who.position();
    /*if (who.align == "right") {
      newdiv.style.right = position[2];
    } else {
      newdiv.style.left = position[0];
    }*/
    newdiv.style.left = position[0];
    newdiv.style.top = position[1];
    
    who.keepshowing = false;
  };
  
  // position - determines the x and y coordinates for this object.
  this.position = function() {
    who = (this.MM_menu ? this.MM_menu : this);
    var par = who.parentDiv;
    var offleft = 0;
    var offtop = 0;
    var offright = 0;
    
    if (who.placement == "right") {
      // Drop to the right side
      offleft = who.offsetX + par.offsetWidth;
      offtop = who.offsetY;
      who.mydiv.style.width= (who.width ? who.width : who.mydiv.offsetWidth);
      do {
        offleft += par.offsetLeft;
        offtop += par.offsetTop;
      } while ( (par = par.offsetParent) && (par.style.position != "absolute") );
    } else if (who.placement == "left") {
      // Drop to the left side
      offleft = who.offsetX - (who.width ? who.width : who.mydiv.offsetWidth);
      offtop = who.offsetY;
      who.mydiv.style.width= (who.width ? who.width : who.mydiv.offsetWidth);
      do {
        offleft += par.offsetLeft;
        offtop += par.offsetTop;
      } while ( (par = par.offsetParent) && (par.style.position != "absolute") );
    } else {
      // Default bottom
      if (who.align == "right") {
        offleft = who.offsetX - (who.width ? who.width : who.mydiv.offsetWidth) + (par.offsetWidth ? par.offsetWidth : 0);
      } else {
        offleft = who.offsetX;
        
      }
      who.mydiv.style.width= (who.width ? who.width : who.mydiv.offsetWidth);
      offright = who.offsetX + 1 * par.offsetWidth;
      offtop = who.offsetY + 1 * par.offsetHeight;
      //d("Based off of parent: "+offright+" from parent: "+par);
      do {
        if (who.align == "right") {
          offleft += par.offsetLeft;
        } else {
          offleft += par.offsetLeft;
        }
        offright += par.offsetLeft;
        //d("offright increased to "+offright+" from parent: "+par);
        offtop += par.offsetTop;
      } while ( (par = par.offsetParent) && (par.style.position != "absolute") );
    }
    return new Array(offleft, offtop, offright);
  }
  
  this.rePosition = function() {
    who = (this.MM_menu ? this.MM_menu : this);    
    who.keepshowing = false;
    var position = who.position();
    if (who.align == "right") {
      who.mydiv.style.right = position[2];
    } else {
      who.mydiv.style.left = position[0];
    }
    who.mydiv.style.top = position[1];
  }
  
  // attachTo -- static-like method
  this.attachTo = function(towhoID) {
    towho = (typeof(towhoID) == "string") ? document.getElementById(towhoID) : towhoID;
    if (towho) {
      towho.onmouseover = this.show;
      towho.onmouseout = this.hide;
      this.parentDiv = towho;
      towho.MM_menu = this;
    }
  }
  
  // add
  /*
    add(MM_Item_object) - adds the object to the list
    add(label, href) - creates a new object and adds it to the list
  */
  this.add = addF;
  function addF(label, href) {
    if (this.menuItems == null) {
      this.menuItems = new Array();
    }
    if (typeof(label) == "object") {
      this.menuItems[this.menuItems.length] = new MM_Item(label);
    } else {
      this.menuItems[this.menuItems.length] = new MM_Item(label, href);
    }
  }
  
  // setclass
  this.setClass = function(towhat) {
    this.myclass = towhat;
  }
  // setstyle
  this.setStyle = function(towhat) {
    this.mystyle = towhat;
  }
}


// Debugging
function d(str) {
  if (document.getElementById('errdiv')) {
    var mydiv = document.createElement("div");
    mydiv.innerHTML = str;
    var errdiv = document.getElementById('errdiv');
    if (errdiv.childNodes.length > 25) {
      errdiv.removeChild(errdiv.childNodes[0]);
    }
    errdiv.appendChild(mydiv);
  }
}



// MenuItem class
//
// MM_Item(label, href) - return an MM_Item object
// MM_Item(array)
//  where array:
//    0 = label
//    1 = href
//    2 = object of properties
function MM_Item(label, href) {
  var MM_defaultItemClass = "MM_item";
  var MM_defaultItemHover = "MM_item_hover";
  var MM_defaultItemActive = "MM_item_active";
  
  var extra = null;
  if (typeof(label) == "object") {
    this.label = label[0];
    this.href = label[1];
    var extra = (label[2] ? label[2] : null);
    if ( extra && extra.submenu) {
      this.submenu = new MM_Menu(extra.submenu);
    }
    if ( extra && extra.myhover) {
      //alert('hover inside');
    }
    this.mystyle = dft("mystyle", extra, "");
    this.myclass = dft("myclass", extra, MM_defaultItemClass);
    this.myhover = dft("myhover", extra, MM_defaultItemHover);
    this.myactive = dft("myactive", extra, MM_defaultItemActive);
  } else {
    this.label = label;
    this.href = href;
    this.submenu = null;
    this.mystyle = dft("mystyle", extra, "");
    this.myclass = dft("myclass", extra, MM_defaultItemClass);
    this.myhover = dft("myhover", extra, MM_defaultItemHover);
    this.myactive = dft("myactive", extra, MM_defaultItemActive);
  }
  
  function dft(valname, obj, defaultval) {
    if (obj) {
      return (obj[valname] ? obj[valname] : defaultval);
    } else {
      return defaultval;
    }
  }
  
  this.addMenu = function(menu) {
    this.submenu = menu;
  }
}