ypSlideOutMenu.Registry = [];
ypSlideOutMenu.aniLen = 750;
ypSlideOutMenu.hideDelay = 1500;
ypSlideOutMenu.minCPUResolution = 10;

/* utility functions 
// offsetTop and offsetLeft corrections
// note: IE5 Mac will not include page margins in calculations.
function ypSlideOutMenuOffsetTop(element) 
{
	return getOffsetProperty(element, 'Top', true);
}

function ypSlideOutMenuOffsetLeft(element) 
{
	return getOffsetProperty(element, 'Left', true);
}

function ypSlideOutMenuOffsetLeft(element, property, deep) {
   var offsetValue = 0;
   offsetProperty = 'offset' + property;
   
   do 
   {
      offsetValue += element[offsetProperty];
      element = element.offsetParent;
   } while (deep == true && element != document.body && element != null);
   
   return offsetValue;
}
*/

// utility functions 
function ypSlideOutMenuOffsetTop(el)
{
	var intTop = el.offsetTop;
	var objParent = el.offsetParent;
	while (objParent != null && objParent != document.body)
	{
		intTop += objParent.offsetTop;
		objParent = objParent.offsetParent;
	}
	return intTop;
}

function ypSlideOutMenuOffsetLeft(el)
{
	var intLeft = el.offsetLeft;
	var objParent = el.offsetParent;
	while (objParent != null && objParent != document.body)
	{
		intLeft += objParent.offsetLeft;
		objParent = objParent.offsetParent;
	}
	return intLeft;
}

// constructor
function ypSlideOutMenu(id, dir, parent)
{
	this.ie = document.all ? 1 : 0;
	this.ns4 = document.layers ? 1 : 0;
	this.dom = document.getElementById ? 1 : 0;
	if (this.ie || this.ns4 || this.dom) 
	{
		this.id = id;
		this.dir = dir;
		this.parent = parent;
		this.srcActivatingEl = null;
		this.orientation = dir == "left" || dir == "right" ? "h" : "v";
		this.dirType = dir == "right" || dir == "down" ? "-" : "+";
		this.dim = this.orientation == "h" ? document.getElementById(id + "Content").offsetWidth : document.getElementById(id + "Content").offsetHeight;
		this.hideTimer = false;
		this.aniTimer = false;
		this.open = false;
		this.over = false;
		this.startTime = 0;
		this.gRef = "ypSlideOutMenu_"+id;
		eval(this.gRef+"=this");
		ypSlideOutMenu.Registry[id] = this;
		
		this.load();
	}
}

ypSlideOutMenu.prototype.load = function() 
{
	var d = document;
	var lyrId1 = this.id + "Container";
	var lyrId2 = this.id + "Content";
	var obj1 = this.dom ? d.getElementById(lyrId1) : this.ie ? d.all[lyrId1] : d.layers[lyrId1];
	if (obj1) 
	{
		var obj2 = this.ns4 ? obj1.layers[lyrId2] : this.ie ? d.all[lyrId2] : d.getElementById(lyrId2);
	}

	if (!obj1 || !obj2) 
	{
		window.setTimeout(this.gRef + ".load()", 100);
	}
	else 
	{
		this.container = obj1;
		this.menu = obj2;
		this.style = this.ns4 ? this.menu : this.menu.style;
		this.homePos = eval("0" + this.dirType + this.dim);
		this.outPos = 0;
		this.accelConst = (this.outPos - this.homePos) / ypSlideOutMenu.aniLen / ypSlideOutMenu.aniLen;
		
		// set event handlers.
		if (this.ns4) this.menu.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT);
		this.menu.onmouseover = new Function("ypSlideOutMenu.showMenu('" + this.id + "')");
		this.menu.onmouseout = new Function("ypSlideOutMenu.hideMenu('" + this.id + "')");
		
		//set initial state
		this.endSlide();
	}
}

ypSlideOutMenu.prototype.keepInWindow  = function()
{
	var ExtraSpace     = 5;
	var ieCSS = (this.ie && document.compatMode) ? document.compatMode ==  "CSS1Compat" : false;
	var canvas = ieCSS ? document.documentElement : document.body;

  var WindowLeftEdge		= (this.ie) ? canvas.scrollLeft   : window.pageXOffset;
  var WindowTopEdge			= (this.ie) ? canvas.scrollTop    : window.pageYOffset;
  var WindowWidth				= (this.ie) ? canvas.clientWidth  : window.innerWidth;
  var WindowHeight			= (this.ie) ? canvas.clientHeight : window.innerHeight;

  var WindowRightEdge		= (WindowLeftEdge + WindowWidth) - ExtraSpace;
  var WindowBottomEdge	= (WindowTopEdge + WindowHeight) - ExtraSpace;
  var MenuLeftEdge			= parseInt(this.container.style.left);
  var MenuRightEdge			= MenuLeftEdge + parseInt(this.container.offsetWidth);
  var MenuBottomEdge		=	parseInt(this.container.style.top) + parseInt(this.container.offsetTop);
    
  if (MenuRightEdge > WindowRightEdge) 
  {
		this.container.style.left = MenuLeftEdge - (MenuRightEdge - WindowRightEdge);
  }
}

ypSlideOutMenu.showMenu = function(id)
{
	var reg = ypSlideOutMenu.Registry;
	var obj = reg[id];
	
	if (obj.over)
	{
		if (obj.hideTimer) { reg[id].hideTimer = window.clearTimeout(reg[id].hideTimer); }
		if (reg[obj.parent])
		{
			if (reg[obj.parent].hideTimer) {reg[obj.parent].hideTimer = window.clearTimeout(reg[obj.parent].hideTimer); }
			reg[obj.parent].over = false;
		}
	}
	else
	{
		// only show child menus if the parent has finished sliding
		if (reg[obj.parent])
		{
			if (reg[obj.parent].aniTimer) return;
		}
		if (obj.container) 
		{
			obj.over = true;
			
			// Set the source activating element
			if (!obj.srcActivatingEl)
			{
				obj.srcActivatingEl = document.getElementById("act" + obj.id.substr(4));
			}
			for (menu in reg) 
			{
				//if (id != menu && obj.parent != menu) { ypSlideOutMenu.hide(menu); }
				if (id != menu && obj.parent != menu && id != reg[menu].parent) { ypSlideOutMenu.hide(menu); }
				//if (id != menu && obj.parent != menu && id != reg[menu].parent && obj.parent != reg[menu].parent) { ypSlideOutMenu.hide(menu); }
			}
			
			if (!obj.open && !obj.aniTimer) 
			{
				if (obj.dir == "down")
				{
					if (obj.dim == 0) 
					{
						obj.dim = obj.menu.offsetHeight; 
						obj.homePos = eval("0" + obj.dirType + obj.dim);
						obj.accelConst = (obj.outPos - obj.homePos) / ypSlideOutMenu.aniLen / ypSlideOutMenu.aniLen;
					}
					obj.container.style.top = ypSlideOutMenuOffsetTop(obj.srcActivatingEl) + obj.srcActivatingEl.offsetHeight;
					obj.container.style.left = ypSlideOutMenuOffsetLeft(obj.srcActivatingEl); 
				}
				else if (obj.dir == "right")
				{
					if (obj.dim == 0) 
					{
						obj.dim = obj.menu.offsetWidth; 
						obj.homePos = eval("0" + obj.dirType + obj.dim);
						obj.accelConst = (obj.outPos - obj.homePos) / ypSlideOutMenu.aniLen / ypSlideOutMenu.aniLen;
					}
					obj.container.style.top = ypSlideOutMenuOffsetTop(obj.srcActivatingEl);
					obj.container.style.left = ypSlideOutMenuOffsetLeft(obj.srcActivatingEl) + obj.srcActivatingEl.offsetWidth + 2;
					obj.keepInWindow();
				}
				
				// set the srcActivatingEl classname
				obj.srcActivatingEl.className += obj.parent ? ' menuActive' : ' active';

				reg[id].startSlide(true);
				//obj.container.style.border = '1px solid black';
				//obj.container.firstChild.firstChild.firstChild.firstChild.firstChild.style.backgroundColor = "white";
				log(obj.container.firstChild.firstChild.firstChild.firstChild.firstChild.tagName + " : " + obj.container.firstChild.firstChild.firstChild.firstChild.firstChild.offsetTop);
				log(obj.container.style.top + ' : ' + obj.container.style.left + ' h:' + obj.container.offsetHeight + ' w:' + obj.container.offsetWidth + ' z:' + obj.container.style.zIndex + ' : ' + obj.container.style.visibility);
			}
		}
	}
}

ypSlideOutMenu.hideMenu = function(id, noDelay)
{
	var obj = ypSlideOutMenu.Registry[id];
	if (obj.container) 
	{
		if (obj.hideTimer) window.clearTimeout(obj.hideTimer);
		obj.hideTimer = window.setTimeout("ypSlideOutMenu.hide('" + id + "')", noDelay ? 150 : ypSlideOutMenu.hideDelay);
	}
}

ypSlideOutMenu.hideAll = function()
{
	var reg = ypSlideOutMenu.Registry;
	for (menu in reg) 
	{
		ypSlideOutMenu.hide(menu);
		if (menu.hideTimer) window.clearTimeout(menu.hideTimer);
	}
	// un-Hide all select elements
	showSelects();
}

ypSlideOutMenu.hideChildren = function()
{
	var reg = ypSlideOutMenu.Registry;
	for (menu in reg) 
	{
		if (reg[menu].parent)
		{
			ypSlideOutMenu.hide(menu);
			if (menu.hideTimer) window.clearTimeout(menu.hideTimer);
		}
	}
}

ypSlideOutMenu.hide = function(id)
{
	var obj = ypSlideOutMenu.Registry[id];
	obj.over = false;
	if (obj.hideTimer) window.clearTimeout(obj.hideTimer);
	obj.hideTimer = 0;
	if (obj.srcActivatingEl) 
	{ 
		if (!obj.srcActivatingEl.getAttribute("selected")) obj.srcActivatingEl.className = obj.srcActivatingEl.className.indexOf("more") > -1 ? 'more' : '';
	}
	if (obj.open && !obj.aniTimer) 
	{
		obj.startSlide(false);
		if (obj.parent)
		{
			objParent = ypSlideOutMenu.Registry[obj.parent];
			if (!objParent.over) ypSlideOutMenu.hide(obj.parent);
		}
		else
		{
			// un-Hide all select elements
			showSelects();
		}
	}
}

ypSlideOutMenu.prototype.startSlide = function(open) 
{
	// Hide all select elements
	hideSelects();

	this.open = open
	if (open) this.setVisibility(true);
	this.startTime = (new Date()).getTime();
	this.aniTimer = window.setInterval(this.gRef + ".slide()", ypSlideOutMenu.minCPUResolution);
}

ypSlideOutMenu.prototype.slide = function()
{
	var elapsed = (new Date()).getTime() - this.startTime;
	if (elapsed > ypSlideOutMenu.aniLen) this.endSlide();
	else 
	{
		var d = Math.round(Math.pow(ypSlideOutMenu.aniLen-elapsed, 2) * this.accelConst);
		if (this.open && this.dirType == "-") d = -d;
		else if (this.open && this.dirType == "+") d = -d;
		else if (!this.open && this.dirType == "-") d = -this.dim + d;
		else d = this.dim + d;
		this.moveTo(d);
	}
}

ypSlideOutMenu.prototype.endSlide = function() 
{
	this.aniTimer = window.clearTimeout(this.aniTimer);
	this.moveTo(this.open ? this.outPos : this.homePos);
	if (!this.open) this.setVisibility(false);
	if ((this.open && !this.over) || (!this.open && this.over)) 
	{
		this.startSlide(this.over);
	}
}
ypSlideOutMenu.prototype.setVisibility = function(bShow) 
{ 
	var s = this.ns4 ? this.container : this.container.style;
	s.visibility = bShow ? "visible" : "hidden";
}

ypSlideOutMenu.prototype.moveTo = function(p) 
{ 
	this.style[this.orientation == "h" ? "left" : "top"] = this.ns4 ? p : p + "px";
}

ypSlideOutMenu.prototype.getPos = function(c) 
{
	return parseInt(this.style[c]);
}

ypSlideOutMenu.prototype.onactivate = function() { }
ypSlideOutMenu.prototype.ondeactivate = function() { }
