//======================================================================================//
//  			         DS Cascading Menu					//
// 											//
//               The DS Menu Object was created and designed by Dave Bleeker		//
//	                    Email( info.webboard@xs4all.nl )		                //
//											//
//======================================================================================//
//                        (c) Copyright 2003 Detailed Simplicity			//
//======================================================================================//

// Check protocol
// check browsers
var ua 		= navigator.userAgent;
var opera 	= /opera [56789]|opera\/[56789]/i.test(ua);
var ie 		= !opera && /MSIE/.test(ua);
var ie50 	= ie && /MSIE 5\.[01234]/.test(ua);
var ie55 	= /MSIE ((5\.[56789])|([6789]))/.test( navigator.userAgent ) && navigator.platform == "Win32";
var ie6 	= ie && /MSIE [6789]/.test(ua);
var ieBox 	= ie && (document.compatMode == null || document.compatMode != "CSS1Compat");
var moz 	= !opera && /gecko/i.test(ua);
var nn6 	= !opera && /netscape.*6\./i.test(ua);

if (ie && document.getElementById == null) // ie4
{	
  document.getElementById = function(sId) 
  {
    return document.all[sId];
  };
}

// define the default values
dsMenuDefaultWidth			= 260;
dsMenuDefaultBorderLeft			= 1;
dsMenuDefaultBorderRight		= 1;
dsMenuDefaultBorderTop			= 1;
dsMenuDefaultBorderBottom		= 0;
dsMenuDefaultPaddingLeft		= 1;
dsMenuDefaultPaddingRight		= 1;
dsMenuDefaultPaddingTop			= 0;
dsMenuDefaultPaddingBottom		= 1;

dsMenuDefaultShadowLeft			= 0;
dsMenuDefaultShadowRight		= 0; // ie && !ie50 && /win32/i.test(navigator.platform) ? 4 :0;
dsMenuDefaultShadowTop			= 0;
dsMenuDefaultShadowBottom		= 0; // ie && !ie50 && /win32/i.test(navigator.platform) ? 4 : 0;

dsMenuItemDefaultHeight			= 30;
dsMenuItemDefaultText			= "Untitled";
dsMenuItemDefaultHref			= "javascript:void(0)";

dsMenuSeparatorDefaultHeight		= 6;

dsMenuDefaultEmptyText			= "Empty";

dsMenuDefaultUseAutoPosition		= nn6 ? false : true;

// other global constants
dsMenuImagePath				= "images";

dsMenuUseHover				= true; // opera ? true : false;
dsMenuHideTime				= 300;
dsMenuShowTime				= 250;


//==============================================//
// Menu Handler for the DSmenu Object 	//
//==============================================//
var dsMenuHandler = 
{
  idCounter	:0,
  idPrefix	:"ds-menu-object-",
  all		:{},
  getId		:function () { return this.idPrefix + this.idCounter++; },
  overMenuItem	:function (oItem) 
  {
    if (this.showTimeout != null) window.clearTimeout(this.showTimeout);
    if (this.hideTimeout != null) window.clearTimeout(this.hideTimeout);
    var jsItem = this.all[oItem.id];


    if (dsMenuShowTime <= 0) this._over(jsItem);
    else this.showTimeout = window.setTimeout("dsMenuHandler._over(dsMenuHandler.all['" + jsItem.id + "'])", dsMenuShowTime);
  },

  outMenuItem	:function (oItem) 
  {
    if (this.showTimeout != null) window.clearTimeout(this.showTimeout);
    if (this.hideTimeout != null) window.clearTimeout(this.hideTimeout);
    var jsItem = this.all[oItem.id];    


    if (dsMenuHideTime <= 0) this._out(jsItem);
    else this.hideTimeout = window.setTimeout("dsMenuHandler._out(dsMenuHandler.all['" + jsItem.id + "'])", dsMenuHideTime);
  },

  blurMenu	:function (oMenuItem) 
  {
    window.setTimeout("dsMenuHandler.all[\"" + oMenuItem.id + "\"].subMenu.hide();", dsMenuHideTime);
  },

  _over		:function (jsItem) 
  {
    if (jsItem.subMenu) 
    {
      jsItem.parentMenu.hideAllSubs();
      jsItem.subMenu.show();
    }
    else jsItem.parentMenu.hideAllSubs();
  },

  _out		:function (jsItem) 
  {
    // find top most menu
    var root = jsItem;
    var m;

    if (root instanceof DSmenuButton) m = root.subMenu;
    else 
    {
      m = jsItem.parentMenu;
      while (m.parentMenu != null && !(m.parentMenu instanceof DSmenuBar))
      m = m.parentMenu;
    }
    if (m != null) m.hide();	
  },
  hideMenu	:function (menu) 
  {
    if (this.showTimeout != null) window.clearTimeout(this.showTimeout);
    if (this.hideTimeout != null) window.clearTimeout(this.hideTimeout);
    this.hideTimeout = window.setTimeout("dsMenuHandler.all['" + menu.id + "'].hide()", dsMenuHideTime);
  },
  showMenu	:function (menu, src, dir) 
  {
    if (this.showTimeout != null) window.clearTimeout(this.showTimeout);
    if (this.hideTimeout != null) window.clearTimeout(this.hideTimeout);
    if (arguments.length < 3) dir = "vertical";
    menu.show(src, dir);
  }

};


//==============================================//
// The DS Menu Object itself 		        //
//==============================================//
function DSmenu() 
{
  this._menuItems		= [];
  this._subMenus		= [];
  this.id			= dsMenuHandler.getId();
  this.top			= 0;
  this.left			= 0;
  this.shown			= false;
  this.parentMenu		= null;
  dsMenuHandler.all[this.id] 	= this;
}

//==============================================//
// Create Menu functions			//
//==============================================//
DSmenu.prototype.width			= dsMenuDefaultWidth;
DSmenu.prototype.emptyText		= dsMenuDefaultEmptyText;
DSmenu.prototype.useAutoPosition	= dsMenuDefaultUseAutoPosition;

DSmenu.prototype.borderLeft		= dsMenuDefaultBorderLeft;
DSmenu.prototype.borderRight		= dsMenuDefaultBorderRight;
DSmenu.prototype.borderTop		= dsMenuDefaultBorderTop;
DSmenu.prototype.borderBottom		= dsMenuDefaultBorderBottom;

DSmenu.prototype.paddingLeft		= dsMenuDefaultPaddingLeft;
DSmenu.prototype.paddingRight		= dsMenuDefaultPaddingRight;
DSmenu.prototype.paddingTop		= dsMenuDefaultPaddingTop;
DSmenu.prototype.paddingBottom		= dsMenuDefaultPaddingBottom;

DSmenu.prototype.shadowLeft		= dsMenuDefaultShadowLeft;
DSmenu.prototype.shadowRight		= dsMenuDefaultShadowRight;
DSmenu.prototype.shadowTop		= dsMenuDefaultShadowTop;
DSmenu.prototype.shadowBottom		= dsMenuDefaultShadowBottom;

DSmenu.prototype.add = function (menuItem) 
{
  this._menuItems[this._menuItems.length] = menuItem;
  if (menuItem.subMenu) 
  {
    this._subMenus[this._subMenus.length] = menuItem.subMenu;
    menuItem.subMenu.parentMenu = this;
  }
  menuItem.parentMenu = this;
};

DSmenu.prototype.show = function (relObj, sDir) 
{
  if (this.useAutoPosition) this.position(relObj, sDir);
	
  var divElement = document.getElementById(this.id);
  divElement.style.left = opera ? this.left : this.left + "px";
  divElement.style.top = opera ? this.top : this.top + "px";
  divElement.style.visibility = "visible";
  this.shown = true;
  if (this.parentMenu) this.parentMenu.show();
};

DSmenu.prototype.hide = function () 
{
  this.hideAllSubs();
  var divElement = document.getElementById(this.id);
  divElement.style.visibility = "hidden";
  this.shown = false;
};

DSmenu.prototype.hideAllSubs = function () 
{
  for (var i = 0; i < this._subMenus.length; i++) 
  {
    if (this._subMenus[i].shown) this._subMenus[i].hide();
  }
};


DSmenu.prototype.toString = function () 
{
  var top = this.top + this.borderTop + this.paddingTop;
  var str = "<div id='" + this.id + "' class='ds-menu' style='" + "width:" + (!ieBox  ?	this.width - this.borderLeft - this.paddingLeft - this.borderRight - this.paddingRight  : this.width) + "px;" +	(this.useAutoPosition ?	"left:" + this.left + "px;" + "top:" + this.top + "px;" : "") + (ie50 ? "filter: none;" : "") + "'>";
	
  if (this._menuItems.length == 0) 
  {
    str +=	"<span class='ds-menu-empty'>" + this.emptyText + "</span>";
  }
  else 
  {	
    // loop through all menuItems
    for (var i = 0; i < this._menuItems.length; i++) 
    {
      var mi = this._menuItems[i];
      str += mi;
      if (!this.useAutoPosition) 
      {
	if (mi.subMenu && !mi.subMenu.useAutoPosition) mi.subMenu.top = top - mi.subMenu.borderTop - mi.subMenu.paddingTop;
	top += mi.height;
      }
    }
  }
  str += "</div>";

  for (var i = 0; i < this._subMenus.length; i++) 
  {
    this._subMenus[i].left = this.left + this.width - this._subMenus[i].borderLeft;
    str += this._subMenus[i];
  }
  return str;
};

// DSmenu.prototype.position defined later
function DSmenuItem(sText, sHref, sToolTip, oSubMenu) 
{
  this.text = sText || dsMenuItemDefaultText;
  this.href = (sHref == null || sHref == "") ? dsMenuItemDefaultHref : sHref;
  this.subMenu = oSubMenu;
  if (oSubMenu) oSubMenu.parentMenuItem = this;
  this.toolTip = sToolTip;
  this.id = dsMenuHandler.getId();
  dsMenuHandler.all[this.id] = this;
};

DSmenuItem.prototype.height 	= dsMenuItemDefaultHeight;
DSmenuItem.prototype.toString 	= function () 
{
  return "<a" +	" id='" +this.id+ "'" +" href=\"" +this.href+ "\"" +(this.toolTip ? " title=\"" +this.toolTip+ "\"" : "") +" onmouseover='dsMenuHandler.overMenuItem(this)'" +(dsMenuUseHover ? " onmouseout='dsMenuHandler.outMenuItem(this)'" : "") +(this.subMenu ? " unselectable='on' tabindex='-1'" : "") + ">" +(this.subMenu ? "<img class='arrow' src=\"" + dsMenuImagePath + "arrow.right.gif\">" : "") +this.text + "</a>";
};


function DSmenuSeparator() 
{
  this.id = dsMenuHandler.getId();
  dsMenuHandler.all[this.id] = this;
};

DSmenuSeparator.prototype.height 	= dsMenuSeparatorDefaultHeight;
DSmenuSeparator.prototype.toString 	= function () 
{
  return "<div" +" id='" +this.id+ "'" +(dsMenuUseHover ? " onmouseover='dsMenuHandler.overMenuItem(this)'" +" onmouseout='dsMenuHandler.outMenuItem(this)'" : "") + "></div>"
};

function DSmenuBar() 
{
  this._parentConstructor = DSmenu;
  this._parentConstructor();
}

DSmenuBar.prototype = new DSmenu;
DSmenuBar.prototype.toString = function () 
{
  var str = "<div id='" +this.id+ "' class='ds-menu-bar'>";

  // loop through all menuButtons
  for (var i = 0; i < this._menuItems.length; i++)
  str += this._menuItems[i];
	
  str += "</div>";

  for (var i = 0; i < this._subMenus.length; i++)
  str += this._subMenus[i];
  return str;
};

function DSmenuButton(sText, sHref, sToolTip, oSubMenu) 
{
  this._parentConstructor = DSmenuItem;
  this._parentConstructor(sText, sHref, sToolTip, oSubMenu);
}

DSmenuButton.prototype = new DSmenuItem;
DSmenuButton.prototype.toString = function () 
{
  return	"<a" + " id='" +this.id+ "'" +" href='" +this.href+ "'" +(this.toolTip ? " title='" +this.toolTip+ "'" : "") +(dsMenuUseHover ? (" onmouseover='dsMenuHandler.overMenuItem(this)'" +" onmouseout='dsMenuHandler.outMenuItem(this)'") : (" onfocus='dsMenuHandler.overMenuItem(this)'" +(this.subMenu ? " onblur='dsMenuHandler.blurMenu(this)'" : ""))) +">" +this.text+ "</a>"; // (this.subMenu ? " <img class='arrow' src='" +dsMenuImagePath+ "arrow.down.gif' align='absmiddle'>" : "") +"</a>";
};


//==============================================//
// Positioning functions 			//
//==============================================//
function getInnerLeft(el) 
{
  if (el == null) return 0;
  if (ieBox && el == document.body || !ieBox && el == document.documentElement) return 0;
  return getLeft(el) + getBorderLeft(el);
}

function getLeft(el) 
{
  if (el == null) return 0;
  return el.offsetLeft + getInnerLeft(el.offsetParent);
}

function getInnerTop(el) 
{
  if (el == null) return 0;
  if (ieBox && el == document.body || !ieBox && el == document.documentElement) return 0;
  return getTop(el) + getBorderTop(el);
}

function getTop(el) 
{
  if (el == null) return 0;
  return el.offsetTop + getInnerTop(el.offsetParent);
}

function getBorderLeft(el) 
{
  return ie ? el.clientLeft :
  parseInt(window.getComputedStyle(el, null).getPropertyValue("border-left-width"));
}

function getBorderTop(el) 
{
  return ie ? el.clientTop :
  parseInt(window.getComputedStyle(el, null).getPropertyValue("border-top-width"));
}

function opera_getLeft(el) 
{
  if (el == null) return 0;
  return el.offsetLeft + opera_getLeft(el.offsetParent);
}

function opera_getTop(el) 
{
  if (el == null) return 0;
  return el.offsetTop + opera_getTop(el.offsetParent);
}

function getOuterRect(el) 
{
  return {
    left	: (opera ? opera_getLeft(el) : getLeft(el)),
    top		: (opera ? opera_getTop(el) : getTop(el)),
    width	: el.offsetWidth,
    height	: el.offsetHeight
  };
}

// mozilla bug! scrollbars not included in innerWidth/height
function getDocumentRect(el) 
{
  return { left : 0, top : 0, width : (ie ? (ieBox ? document.body.clientWidth : document.documentElement.clientWidth) : window.innerWidth), height:(ie ? (ieBox ? document.body.clientHeight : document.documentElement.clientHeight) : window.innerHeight ) };
}

function getScrollPos(el) 
{
  return { left : (ie ? (ieBox ? document.body.scrollLeft : document.documentElement.scrollLeft) : window.pageXOffset), top: (ie ?(ieBox ? document.body.scrollTop : document.documentElement.scrollTop) : window.pageYOffset) };
}

//==============================================//
// End positioning functions. Start to  	//
// position the menu.				//
//==============================================//
DSmenu.prototype.position = function (relEl, sDir) 
{
  var dir = sDir;

  // find parent item rectangle, piRect
  var piRect;

  if (!relEl) 
  {
    var pi = this.parentMenuItem;
    if (!this.parentMenuItem) return;
		
    relEl = document.getElementById(pi.id);

    if (dir == null) dir = pi instanceof DSmenuButton ? "vertical" : "horizontal";
		
    piRect = getOuterRect(relEl);
  }
  else if (relEl.left != null && relEl.top != null && relEl.width != null && relEl.height != null) 
  {		
    // got a rect
    piRect = relEl;
  }
  else piRect = getOuterRect(relEl);
	
  var menuEl 	= document.getElementById(this.id);
  var menuRect 	= getOuterRect(menuEl);
  var docRect 	= getDocumentRect();
  var scrollPos = getScrollPos();
  var pMenu 	= this.parentMenu;
	
  if (dir == "vertical") 
  {
    if (piRect.left + menuRect.width - scrollPos.left <= docRect.width) this.left = piRect.left;
    else if (docRect.width >= menuRect.width)
    this.left = docRect.width + scrollPos.left - menuRect.width;
    else this.left = scrollPos.left;
			
    if (piRect.top + piRect.height + menuRect.height <= docRect.height + scrollPos.top) this.top = piRect.top + piRect.height;
    else if (piRect.top - menuRect.height >= scrollPos.top)
    this.top = piRect.top - menuRect.height;
    else if (docRect.height >= menuRect.height)
    this.top = docRect.height + scrollPos.top - menuRect.height;
    else this.top = scrollPos.top;
  }
  else 
  {
   if (piRect.top + menuRect.height - this.borderTop - this.paddingTop <= docRect.height + scrollPos.top) this.top = piRect.top - this.borderTop - this.paddingTop;
   else if (piRect.top + piRect.height - menuRect.height + this.borderTop + this.paddingTop >= 0) this.top = piRect.top + piRect.height - menuRect.height + this.borderBottom + this.paddingBottom + this.shadowBottom;
   else if (docRect.height >= menuRect.height) this.top = docRect.height + scrollPos.top - menuRect.height;
   else this.top = scrollPos.top;

   var pMenuPaddingLeft = pMenu ? pMenu.paddingLeft : 0;
   var pMenuBorderLeft = pMenu ? pMenu.borderLeft : 0;
   var pMenuPaddingRight = pMenu ? pMenu.paddingRight : 0;
   var pMenuBorderRight = pMenu ? pMenu.borderRight : 0;
		
   if (piRect.left + piRect.width + menuRect.width + pMenuPaddingRight + pMenuBorderRight - this.borderLeft + this.shadowRight <= docRect.width + scrollPos.left)
   this.left = piRect.left + piRect.width + pMenuPaddingRight + pMenuBorderRight - this.borderLeft;
   else if (piRect.left - menuRect.width - pMenuPaddingLeft - pMenuBorderLeft + this.borderRight + this.shadowRight >= 0) this.left = piRect.left - menuRect.width - pMenuPaddingLeft - pMenuBorderLeft + this.borderRight + this.shadowRight;
   else if (docRect.width >= menuRect.width) this.left = docRect.width  + scrollPos.left - menuRect.width;
   else this.left = scrollPos.left;
  }
};