// SpryMenuBar.js - version 0.13 - Spry Pre-Release 1.6.1
//
// Copyright (c) 2006. Adobe Systems Incorporated.
// All rights reserved.
//

// START OF SPRY COMPONENTS
  (function() { 
  
  if (typeof Spry == "undefined") window.Spry = {}; if (!Spry.Widget) Spry.Widget = {};
  
  Spry.BrowserSniff = function()
  {
	  var b = navigator.appName.toString();
	  var up = navigator.platform.toString();
	  var ua = navigator.userAgent.toString();
  
	  this.mozilla = this.ie = this.opera = this.safari = false;
	  var re_opera = /Opera.([0-9\.]*)/i;
	  var re_msie = /MSIE.([0-9\.]*)/i;
	  var re_gecko = /gecko/i;
	  var re_safari = /(applewebkit|safari)\/([\d\.]*)/i;
	  var r = false;
  
	  if ( (r = ua.match(re_opera))) {
		  this.opera = true;
		  this.version = parseFloat(r[1]);
	  } else if ( (r = ua.match(re_msie))) {
		  this.ie = true;
		  this.version = parseFloat(r[1]);
	  } else if ( (r = ua.match(re_safari))) {
		  this.safari = true;
		  this.version = parseFloat(r[2]);
	  } else if (ua.match(re_gecko)) {
		  var re_gecko_version = /rv:\s*([0-9\.]+)/i;
		  r = ua.match(re_gecko_version);
		  this.mozilla = true;
		  this.version = parseFloat(r[1]);
	  }
	  this.windows = this.mac = this.linux = false;
  
	  this.Platform = ua.match(/windows/i) ? "windows" :
					  (ua.match(/linux/i) ? "linux" :
					  (ua.match(/mac/i) ? "mac" :
					  ua.match(/unix/i)? "unix" : "unknown"));
	  this[this.Platform] = true;
	  this.v = this.version;
  
	  if (this.safari && this.mac && this.mozilla) {
		  this.mozilla = false;
	  }
  };
  
  Spry.is = new Spry.BrowserSniff();
  
  // Constructor for Menu Bar
  // element should be an ID of an unordered list (<ul> tag)
  // preloadImage1 and preloadImage2 are images for the rollover state of a menu
  Spry.Widget.MenuBar = function(element, opts)
  {
	  this.init(element, opts);
  };
  
  Spry.Widget.MenuBar.prototype.init = function(element, opts)
  {
	  this.element = this.getElement(element);
  
	  // represents the current (sub)menu we are operating on
	  this.currMenu = null;
	  this.showDelay = 250;
	  this.hideDelay = 600;
	  if(typeof document.getElementById == 'undefined' || (navigator.vendor == 'Apple Computer, Inc.' && typeof window.XMLHttpRequest == 'undefined') || (Spry.is.ie && typeof document.uniqueID == 'undefined'))
	  {
		  // bail on older unsupported browsers
		  return;
	  }
  
	  // Fix IE6 CSS images flicker
	  if (Spry.is.ie && Spry.is.version < 7){
		  try {
			  document.execCommand("BackgroundImageCache", false, true);
		  } catch(err) {}
	  }
  
	  this.upKeyCode = Spry.Widget.MenuBar.KEY_UP;
	  this.downKeyCode = Spry.Widget.MenuBar.KEY_DOWN;
	  this.leftKeyCode = Spry.Widget.MenuBar.KEY_LEFT;
	  this.rightKeyCode = Spry.Widget.MenuBar.KEY_RIGHT;
	  this.escKeyCode = Spry.Widget.MenuBar.KEY_ESC;
  
	  this.hoverClass = 'MenuBarItemHover';
	  this.subHoverClass = 'MenuBarItemSubmenuHover';
	  this.subVisibleClass ='MenuBarSubmenuVisible';
	  this.hasSubClass = 'MenuBarItemSubmenu';
	  this.activeClass = 'MenuBarActive';
	  this.isieClass = 'MenuBarItemIE';
	  this.verticalClass = 'MenuBarVertical';
	  this.horizontalClass = 'MenuBarHorizontal';
	  this.enableKeyboardNavigation = true;
  
	  this.hasFocus = false;
	  // load hover images now
	  if(opts)
	  {
		  for(var k in opts)
		  {
			  if (typeof this[k] == 'undefined')
			  {
				  var rollover = new Image;
				  rollover.src = opts[k];
			  }
		  }
		  Spry.Widget.MenuBar.setOptions(this, opts);
	  }
  
	  // safari doesn't support tabindex
	  if (Spry.is.safari)
		  this.enableKeyboardNavigation = false;
  
	  if(this.element)
	  {
		  this.currMenu = this.element;
		  var items = this.element.getElementsByTagName('li');
		  for(var i=0; i<items.length; i++)
		  {
			  if (i > 0 && this.enableKeyboardNavigation)
				  items[i].getElementsByTagName('a')[0].tabIndex='-1';
  
			  this.initialize(items[i], element);
			  if(Spry.is.ie)
			  {
				  this.addClassName(items[i], this.isieClass);
				  items[i].style.position = "static";
			  }
		  }
		  if (this.enableKeyboardNavigation)
		  {
			  var self = this;
			  this.addEventListener(document, 'keydown', function(e){self.keyDown(e); }, false);
		  }
  
		  if(Spry.is.ie)
		  {
			  if(this.hasClassName(this.element, this.verticalClass))
			  {
				  this.element.style.position = "relative";
			  }
			  var linkitems = this.element.getElementsByTagName('a');
			  for(var i=0; i<linkitems.length; i++)
			  {
				  linkitems[i].style.position = "relative";
			  }
		  }
	  }
  };
  Spry.Widget.MenuBar.KEY_ESC = 27;
  Spry.Widget.MenuBar.KEY_UP = 38;
  Spry.Widget.MenuBar.KEY_DOWN = 40;
  Spry.Widget.MenuBar.KEY_LEFT = 37;
  Spry.Widget.MenuBar.KEY_RIGHT = 39;
  
  Spry.Widget.MenuBar.prototype.getElement = function(ele)
  {
	  if (ele && typeof ele == "string")
		  return document.getElementById(ele);
	  return ele;
  };
  
  Spry.Widget.MenuBar.prototype.hasClassName = function(ele, className)
  {
	  if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)
	  {
		  return false;
	  }
	  return true;
  };
  
  Spry.Widget.MenuBar.prototype.addClassName = function(ele, className)
  {
	  if (!ele || !className || this.hasClassName(ele, className))
		  return;
	  ele.className += (ele.className ? " " : "") + className;
  };
  
  Spry.Widget.MenuBar.prototype.removeClassName = function(ele, className)
  {
	  if (!ele || !className || !this.hasClassName(ele, className))
		  return;
	  ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
  };
  
  // addEventListener for Menu Bar
  // attach an event to a tag without creating obtrusive HTML code
  Spry.Widget.MenuBar.prototype.addEventListener = function(element, eventType, handler, capture)
  {
	  try
	  {
		  if (element.addEventListener)
		  {
			  element.addEventListener(eventType, handler, capture);
		  }
		  else if (element.attachEvent)
		  {
			  element.attachEvent('on' + eventType, handler);
		  }
	  }
	  catch (e) {}
  };
  
  // createIframeLayer for Menu Bar
  // creates an IFRAME underneath a menu so that it will show above form controls and ActiveX
  Spry.Widget.MenuBar.prototype.createIframeLayer = function(menu)
  {
	  var layer = document.createElement('iframe');
	  layer.tabIndex = '-1';
	  layer.src = 'javascript:""';
	  layer.frameBorder = '0';
	  layer.scrolling = 'no';
	  menu.parentNode.appendChild(layer);
	  
	  layer.style.left = menu.offsetLeft + 'px';
	  layer.style.top = menu.offsetTop + 'px';
	  layer.style.width = menu.offsetWidth + 'px';
	  layer.style.height = menu.offsetHeight + 'px';
  };
  
  // removeIframeLayer for Menu Bar
  // removes an IFRAME underneath a menu to reveal any form controls and ActiveX
  Spry.Widget.MenuBar.prototype.removeIframeLayer =  function(menu)
  {
	  var layers = ((menu == this.element) ? menu : menu.parentNode).getElementsByTagName('iframe');
	  while(layers.length > 0)
	  {
		  layers[0].parentNode.removeChild(layers[0]);
	  }
  };
  
  // clearMenus for Menu Bar
  // root is the top level unordered list (<ul> tag)
  Spry.Widget.MenuBar.prototype.clearMenus = function(root)
  {
	  var menus = root.getElementsByTagName('ul');
	  for(var i=0; i<menus.length; i++)
		  this.hideSubmenu(menus[i]);
  
	  this.removeClassName(this.element, this.activeClass);
  };
  
  // bubbledTextEvent for Menu Bar
  // identify bubbled up text events in Safari so we can ignore them
  Spry.Widget.MenuBar.prototype.bubbledTextEvent = function()
  {
	  return Spry.is.safari && (event.target == event.relatedTarget.parentNode || (event.eventPhase == 3 && event.target.parentNode == event.relatedTarget));
  };
  
  // showSubmenu for Menu Bar
  // set the proper CSS class on this menu to show it
  Spry.Widget.MenuBar.prototype.showSubmenu = function(menu)
  {
	  if(this.currMenu)
	  {
		  this.clearMenus(this.currMenu);
		  this.currMenu = null;
	  }
	  
	  if(menu)
	  {
		  this.addClassName(menu, this.subVisibleClass);
		  if(typeof document.all != 'undefined' && !Spry.is.opera && navigator.vendor != 'KDE')
		  {
			  if(!this.hasClassName(this.element, this.horizontalClass) || menu.parentNode.parentNode != this.element)
			  {
				  menu.style.top = menu.parentNode.offsetTop + 'px';
			  }
		  }
		  if(Spry.is.ie && Spry.is.version < 7)
		  {
			  this.createIframeLayer(menu);
		  }
	  }
	  this.addClassName(this.element, this.activeClass);
  };
  
  // hideSubmenu for Menu Bar
  // remove the proper CSS class on this menu to hide it
  Spry.Widget.MenuBar.prototype.hideSubmenu = function(menu)
  {
	  if(menu)
	  {
		  this.removeClassName(menu, this.subVisibleClass);
		  if(typeof document.all != 'undefined' && !Spry.is.opera && navigator.vendor != 'KDE')
		  {
			  menu.style.top = '';
			  menu.style.left = '';
		  }
		  if(Spry.is.ie && Spry.is.version < 7)
			  this.removeIframeLayer(menu);
	  }
  };
  
  // initialize for Menu Bar
  // create event listeners for the Menu Bar widget so we can properly
  // show and hide submenus
  Spry.Widget.MenuBar.prototype.initialize = function(listitem, element)
  {
	  var opentime, closetime;
	  var link = listitem.getElementsByTagName('a')[0];
	  var submenus = listitem.getElementsByTagName('ul');
	  var menu = (submenus.length > 0 ? submenus[0] : null);
  
	  if(menu)
		  this.addClassName(link, this.hasSubClass);
  
	  if(!Spry.is.ie)
	  {
		  // define a simple function that comes standard in IE to determine
		  // if a node is within another node
		  listitem.contains = function(testNode)
		  {
			  // this refers to the list item
			  if(testNode == null)
				  return false;
  
			  if(testNode == this)
				  return true;
			  else
				  return this.contains(testNode.parentNode);
		  };
	  }
  
	  // need to save this for scope further down
	  var self = this;
	  this.addEventListener(listitem, 'mouseover', function(e){self.mouseOver(listitem, e);}, false);
	  this.addEventListener(listitem, 'mouseout', function(e){if (self.enableKeyboardNavigation) self.clearSelection(); self.mouseOut(listitem, e);}, false);
  
	  if (this.enableKeyboardNavigation)
	  {
		  this.addEventListener(link, 'blur', function(e){self.onBlur(listitem);}, false);
		  this.addEventListener(link, 'focus', function(e){self.keyFocus(listitem, e);}, false);
	  }
  };
  Spry.Widget.MenuBar.prototype.keyFocus = function (listitem, e)
  {
	  this.lastOpen = listitem.getElementsByTagName('a')[0];
	  this.addClassName(this.lastOpen, listitem.getElementsByTagName('ul').length > 0 ? this.subHoverClass : this.hoverClass);
	  this.hasFocus = true;
  };
  Spry.Widget.MenuBar.prototype.onBlur = function (listitem)
  {
	  this.clearSelection(listitem);
  };
  Spry.Widget.MenuBar.prototype.clearSelection = function(el){
	  //search any intersection with the current open element
	  if (!this.lastOpen)
		  return;
  
	  if (el)
	  {
		  el = el.getElementsByTagName('a')[0];
		  
		  // check children
		  var item = this.lastOpen;
		  while (item != this.element)
		  {
			  var tmp = el;
			  while (tmp != this.element)
			  {
				  if (tmp == item)
					  return;
				  try{
					  tmp = tmp.parentNode;
				  }catch(err){break;}
			  }
			  item = item.parentNode;
		  }
	  }
	  var item = this.lastOpen;
	  while (item != this.element)
	  {
		  this.hideSubmenu(item.parentNode);
		  var link = item.getElementsByTagName('a')[0];
		  this.removeClassName(link, this.hoverClass);
		  this.removeClassName(link, this.subHoverClass);
		  item = item.parentNode;
	  }
	  this.lastOpen = false;
  };
  Spry.Widget.MenuBar.prototype.keyDown = function (e)
  {
	  if (!this.hasFocus)
		  return;
  
	  if (!this.lastOpen)
	  {
		  this.hasFocus = false;
		  return;
	  }
  
	  var e = e|| event;
	  var listitem = this.lastOpen.parentNode;
	  var link = this.lastOpen;
	  var submenus = listitem.getElementsByTagName('ul');
	  var menu = (submenus.length > 0 ? submenus[0] : null);
	  var hasSubMenu = (menu) ? true : false;
  
	  var opts = [listitem, menu, null, this.getSibling(listitem, 'previousSibling'), this.getSibling(listitem, 'nextSibling')];
	  
	  if (!opts[3])
		  opts[2] = (listitem.parentNode.parentNode.nodeName.toLowerCase() == 'li')?listitem.parentNode.parentNode:null;
  
	  var found = 0;
	  switch (e.keyCode){
		  case this.upKeyCode:
			  found = this.getElementForKey(opts, 'y', 1);
			  break;
		  case this.downKeyCode:
			  found = this.getElementForKey(opts, 'y', -1);
			  break;
		  case this.leftKeyCode:
			  found = this.getElementForKey(opts, 'x', 1);
			  break;
		  case this.rightKeyCode:
			  found = this.getElementForKey(opts, 'x', -1);
			  break;
		  case this.escKeyCode:
		  case 9:
			  this.clearSelection();
			  this.hasFocus = false;
		  default: return;
	  }
	  switch (found)
	  {
		  case 0: return;
		  case 1:
			  //subopts
			  this.mouseOver(listitem, e);
			  break;
		  case 2:
			  //parent
			  this.mouseOut(opts[2], e);
			  break;
		  case 3:
		  case 4:
			  // left - right
			  this.removeClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
			  break;
	  }
	  var link = opts[found].getElementsByTagName('a')[0];
	  if (opts[found].nodeName.toLowerCase() == 'ul')
		  opts[found] = opts[found].getElementsByTagName('li')[0];
  
	  this.addClassName(link, opts[found].getElementsByTagName('ul').length > 0 ? this.subHoverClass : this.hoverClass);
	  this.lastOpen = link;
	  opts[found].getElementsByTagName('a')[0].focus();
	
		  //stop further event handling by the browser
	  return Spry.Widget.MenuBar.stopPropagation(e);
  };
  Spry.Widget.MenuBar.prototype.mouseOver = function (listitem, e)
  {
	  var link = listitem.getElementsByTagName('a')[0];
	  var submenus = listitem.getElementsByTagName('ul');
	  var menu = (submenus.length > 0 ? submenus[0] : null);
	  var hasSubMenu = (menu) ? true : false;
	  if (this.enableKeyboardNavigation)
		  this.clearSelection(listitem);
  
	  if(this.bubbledTextEvent())
	  {
		  // ignore bubbled text events
		  return;
	  }
  
	  if (listitem.closetime)
		  clearTimeout(listitem.closetime);
  
	  if(this.currMenu == listitem)
	  {
		  this.currMenu = null;
	  }
  
	  // move the focus too
	  if (this.hasFocus)
		  link.focus();
  
	  // show menu highlighting
	  this.addClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
	  this.lastOpen = link;
	  if(menu && !this.hasClassName(menu, this.subHoverClass))
	  {
		  var self = this;
		  listitem.opentime = window.setTimeout(function(){self.showSubmenu(menu);}, this.showDelay);
	  }
  };
  Spry.Widget.MenuBar.prototype.mouseOut = function (listitem, e)
  {
	  var link = listitem.getElementsByTagName('a')[0];
	  var submenus = listitem.getElementsByTagName('ul');
	  var menu = (submenus.length > 0 ? submenus[0] : null);
	  var hasSubMenu = (menu) ? true : false;
	  if(this.bubbledTextEvent())
	  {
		  // ignore bubbled text events
		  return;
	  }
  
	  var related = (typeof e.relatedTarget != 'undefined' ? e.relatedTarget : e.toElement);
	  if(!listitem.contains(related))
	  {
		  if (listitem.opentime) 
			  clearTimeout(listitem.opentime);
		  this.currMenu = listitem;
  
		  // remove menu highlighting
		  this.removeClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
		  if(menu)
		  {
			  var self = this;
			  listitem.closetime = window.setTimeout(function(){self.hideSubmenu(menu);}, this.hideDelay);
		  }
		  if (this.hasFocus)
			  link.blur();
	  }
  };
  Spry.Widget.MenuBar.prototype.getSibling = function(element, sibling)
  {
	  var child = element[sibling];
	  while (child && child.nodeName.toLowerCase() !='li')
		  child = child[sibling];
  
	  return child;
  };
  Spry.Widget.MenuBar.prototype.getElementForKey = function(els, prop, dir)
  {
	  var found = 0;
	  var rect = Spry.Widget.MenuBar.getPosition;
	  var ref = rect(els[found]);
  
	  var hideSubmenu = false;
	  //make the subelement visible to compute the position
	  if (els[1] && !this.hasClassName(els[1], this.MenuBarSubmenuVisible))
	  {
		  els[1].style.visibility = 'hidden';
		  this.showSubmenu(els[1]);
		  hideSubmenu = true;
	  }
  
	  var isVert = this.hasClassName(this.element, this.verticalClass);
	  var hasParent = els[0].parentNode.parentNode.nodeName.toLowerCase() == 'li' ? true : false;
	  
	  for (var i = 1; i < els.length; i++){
		  //when navigating on the y axis in vertical menus, ignore children and parents
		  if(prop=='y' && isVert && (i==1 || i==2))
		  {
			  continue;
		  }
		  //when navigationg on the x axis in the FIRST LEVEL of horizontal menus, ignore children and parents
		  if(prop=='x' && !isVert && !hasParent && (i==1 || i==2))
		  {
			  continue;
		  }
			  
		  if (els[i])
		  {
			  var tmp = rect(els[i]); 
			  if ( (dir * tmp[prop]) < (dir * ref[prop]))
			  {
				  ref = tmp;
				  found = i;
			  }
		  }
	  }
	  
	  // hide back the submenu
	  if (els[1] && hideSubmenu){
		  this.hideSubmenu(els[1]);
		  els[1].style.visibility =  '';
	  }
  
	  return found;
  };
  Spry.Widget.MenuBar.camelize = function(str)
  {
	  if (str.indexOf('-') == -1){
		  return str;	
	  }
	  var oStringList = str.split('-');
	  var isFirstEntry = true;
	  var camelizedString = '';
  
	  for(var i=0; i < oStringList.length; i++)
	  {
		  if(oStringList[i].length>0)
		  {
			  if(isFirstEntry)
			  {
				  camelizedString = oStringList[i];
				  isFirstEntry = false;
			  }
			  else
			  {
				  var s = oStringList[i];
				  camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
			  }
		  }
	  }
  
	  return camelizedString;
  };
  
  Spry.Widget.MenuBar.getStyleProp = function(element, prop)
  {
	  var value;
	  try
	  {
		  if (element.style)
			  value = element.style[Spry.Widget.MenuBar.camelize(prop)];
  
		  if (!value)
			  if (document.defaultView && document.defaultView.getComputedStyle)
			  {
				  var css = document.defaultView.getComputedStyle(element, null);
				  value = css ? css.getPropertyValue(prop) : null;
			  }
			  else if (element.currentStyle) 
			  {
					  value = element.currentStyle[Spry.Widget.MenuBar.camelize(prop)];
			  }
	  }
	  catch (e) {}
  
	  return value == 'auto' ? null : value;
  };
  Spry.Widget.MenuBar.getIntProp = function(element, prop)
  {
	  var a = parseInt(Spry.Widget.MenuBar.getStyleProp(element, prop),10);
	  if (isNaN(a))
		  return 0;
	  return a;
  };
  
  Spry.Widget.MenuBar.getPosition = function(el, doc)
  {
	  doc = doc || document;
	  if (typeof(el) == 'string') {
		  el = doc.getElementById(el);
	  }
  
	  if (!el) {
		  return false;
	  }
  
	  if (el.parentNode === null || Spry.Widget.MenuBar.getStyleProp(el, 'display') == 'none') {
		  //element must be visible to have a box
		  return false;
	  }
  
	  var ret = {x:0, y:0};
	  var parent = null;
	  var box;
  
	  if (el.getBoundingClientRect) { // IE
		  box = el.getBoundingClientRect();
		  var scrollTop = doc.documentElement.scrollTop || doc.body.scrollTop;
		  var scrollLeft = doc.documentElement.scrollLeft || doc.body.scrollLeft;
		  ret.x = box.left + scrollLeft;
		  ret.y = box.top + scrollTop;
	  } else if (doc.getBoxObjectFor) { // gecko
		  box = doc.getBoxObjectFor(el);
		  ret.x = box.x;
		  ret.y = box.y;
	  } else { // safari/opera
		  ret.x = el.offsetLeft;
		  ret.y = el.offsetTop;
		  parent = el.offsetParent;
		  if (parent != el) {
			  while (parent) {
				  ret.x += parent.offsetLeft;
				  ret.y += parent.offsetTop;
				  parent = parent.offsetParent;
			  }
		  }
		  // opera & (safari absolute) incorrectly account for body offsetTop
		  if (Spry.is.opera || Spry.is.safari && Spry.Widget.MenuBar.getStyleProp(el, 'position') == 'absolute')
			  ret.y -= doc.body.offsetTop;
	  }
	  if (el.parentNode)
			  parent = el.parentNode;
	  else
		  parent = null;
	  if (parent.nodeName){
		  var cas = parent.nodeName.toUpperCase();
		  while (parent && cas != 'BODY' && cas != 'HTML') {
			  cas = parent.nodeName.toUpperCase();
			  ret.x -= parent.scrollLeft;
			  ret.y -= parent.scrollTop;
			  if (parent.parentNode)
				  parent = parent.parentNode;
			  else
				  parent = null;
		  }
	  }
	  return ret;
  };
  
  Spry.Widget.MenuBar.stopPropagation = function(ev)
  {
	  if (ev.stopPropagation)
		  ev.stopPropagation();
	  else
		  ev.cancelBubble = true;
	  if (ev.preventDefault) 
		  ev.preventDefault();
	  else 
		  ev.returnValue = false;
  };
  
  Spry.Widget.MenuBar.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
  {
	  if (!optionsObj)
		  return;
	  for (var optionName in optionsObj)
	  {
		  if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
			  continue;
		  obj[optionName] = optionsObj[optionName];
	  }
  };
  
  })();
   // EndSpryComponent

