
Event.DOMReady(prepareRolloverMenus);

function prepareRolloverMenus(){
	var menus = Document.getElementsByClassMatch("JS:RolloverMenu");	
	menus.each(RollOverMenu);
}

function RollOverMenu(element){
	element.state = "normal";
	if(Browser.getBrowser() == "firefox"){
		element.setAttribute("title", null); // fixes firefox alt breaker bug
	}
	var parameters = Document.getArguments(element, "JS:RolloverMenu");
	var rolloverId = parameters[0];
	var type = (parameters[1] != "vertical" ) ? "horizontal" : "vertical";
	var align = parameters[2];
	var extraX = (parameters[3]) ? parameters[3] : 0;
	var extraY = (parameters[4]) ? parameters[4] : 0;
	var rollover = document.getElementById(rolloverId);
	if(type == "horizontal"){
		RollOverMenu.setHorizontalMenu(rollover, element, align, extraX, extraY);
	}
	else{
		RollOverMenu.setVerticalMenu(rollover, element, align, extraX, extraY);
	}
	RollOverMenu.setChildren(rollover);
	rollover.trigger = element;
	rollover.originalHeight = rollover.offsetHeight;
	//Event.addEvent(rollover, "mouseout", RollOverMenu.hide);
	Event.addEvent(element, "mouseover", RollOverMenu.show);
	//Event.addEvent(element, "mouseout", RollOverMenu.cancel);
}
RollOverMenu.setHorizontalMenu = function(rollover, caller, align, extraX, extraY){
	var callerX = Document.getX(caller);
	var callerWidth = caller.offsetWidth;
	var callerFarX = callerX + callerWidth;
	var rolloverWidth = rollover.offsetWidth;
	switch(align){
		case "left":
			rollover.style.left = (callerX + extraX) + "px";
			break;
		case "right":
			rollover.style.left = (callerFarX - rolloverWidth + extraX) + "px";
			break;
		default :
			var diff = (rolloverWidth - callerWidth) /2;
			rollover.style.left = (callerX - diff + extraX) + "px";
			break;
	}
	rollover.style.top = (Document.getY(caller) + caller.offsetHeight + extraY) + "px";
}
RollOverMenu.setVerticalMenu = function(rollover, caller, align, extraX, extraY){
	var callerY = Document.getY(caller);
	var callerHeight = caller.offsetHeight;
	var callerFarY = callerY + callerHeight;
	var rolloverHeight = rollover.offsetHeight;
	switch(align){
		case "top":
			rollover.style.top = (callerY + extraY) + "px";
			break;
		case "bottom":
			rollover.style.top = (callerFarY - rolloverHeight + extraY) + "px";
			break;
		default :
			var diff = (rolloverHeight - callerHeight) /2;
			rollover.style.top = (callerY - diff + extraY) + "px";
			break;
	}
	rollover.style.left = (Document.getX(caller) + caller.offsetWidth + extraX) + "px";
}
RollOverMenu.show = function(evt){
	Event.preventDefault(evt);
	var callee = Event.getTarget(evt);
	var rolloverId = Document.getArguments(callee, "JS:RolloverMenu")[0];
	var rollover = document.getElementById(rolloverId);
	RollOverMenu.animateIn(rollover);
}
RollOverMenu.cancel = function(evt){
	var callee = Event.getTarget(evt);
	var elementTo = Event.getElementTo(evt);
	var rolloverId = Document.getArguments(callee, "JS:RolloverMenu")[0];
	var rollover = document.getElementById(rolloverId);
	var isChild = Document.isChildOf(elementTo, rollover);
	if(! isChild){
		RollOverMenu.animateOut(rollover);
	}
}
RollOverMenu.setChildren = function(element){
	var children = element.getElementsByTagName("*");
	element.rolloverId = element.id;
	for(var i = 0 ; i < children.length; i ++){
		children[i].rolloverId = element.id;
	}
}
RollOverMenu.hide = function(evt){
	var callee = Event.getTarget(evt);
	var elementTo = Event.getElementTo(evt);
	var rollover = document.getElementById(callee.rolloverId);
	var trigger = rollover.trigger;
	if(! trigger.animating){
		var isChild = Document.isChildOf(elementTo, rollover);
		if(! isChild){
			RollOverMenu.animateOut(rollover);
		}
	}
}
RollOverMenu.animateIn = function(element){
	var trigger = element.trigger;
	var currentVisible = Document.getStyle(element, "visibility");
	if(currentVisible == "visible"){
		return;
	}
	if(trigger.animating){
		return;	
	}
	trigger.animating = true;
	var children = Document.getChildNodes(element);
	for(var i = 0; i < children.length; i ++){
		children[i].style.visibility = "hidden";
	}
	var height = element.offsetHeight;
	element.style.height = "0px";
	element.style.visibility = "visible";
	var ani = new Tween(element, "height", Strong.easeInOut, 0, height, 0.2);
	ani.onMotionFinished = function(){
		trigger.animating = false;
		for(var i = 0; i < children.length; i ++){
			children[i].style.opacity = 0;
			children[i].style.filter = "alpha(opacity=0)"; 
			children[i].style.visibility = "visible";
			var fadeIn = new Tween(children[i], "alpha", None.easeNone, 0, 100, 0.1);
			if(i == (children.length - 1)){
				fadeIn.onMotionFinished = function(){
					// finished animating
					RollOverMenu.failSafe(trigger, element);
					trigger.animating = false;
				}
			}
		}
	}
}
RollOverMenu.failSafe = function(trigger, element){
	// get trigger coords
	trigger.startX = Document.getX(trigger);
	trigger.endX = trigger.startX + trigger.offsetWidth;
	trigger.startY = Document.getY(trigger);
	trigger.endY = trigger.startY + trigger.offsetHeight;
	// get rollover coords
	element.startX = Document.getX(element);
	element.endX = element.startX + element.offsetWidth;
	element.startY = Document.getY(element);
	element.endY = element.startY + element.offsetHeight;
	Event.addEvent(document, "mousemove", failSafe);
	var moveActivated = false;
	function failSafe(evt){
		if(moveActivated){
			return;
		}
		var mouseX = Document.getMouseX(evt);
		var mouseY = Document.getMouseY(evt);
		// is within trigger
		if( (mouseX >= trigger.startX && mouseX <= trigger.endX) && (mouseY >= trigger.startY && mouseY <= trigger.endY) ){
			return;
		}
		// is within rollover
		if(mouseX < element.startX || mouseX > element.endX){
			Event.removeEvent(document, "mousemove", failSafe);
			RollOverMenu.animateOut(element);
		moveActivated = true;
		}
		else if(mouseY < element.startY || mouseY > element.endY){
			Event.removeEvent(document, "mousemove", failSafe);
			RollOverMenu.animateOut(element);
		moveActivated = true;
		}
	}
}
RollOverMenu.animateOut = function(element){
	var trigger = element.trigger;
	if(trigger.animating){
		return;	
	}
	trigger.animating = true;
	var children = Document.getChildNodes(element);
	var height = element.offsetHeight;
	for(var i = 0; i < children.length; i ++){
		children[i].style.visibility = "";
		var fadeOut = new Tween(children[i], "alpha", None.easeNone, 100, 0, 0.1);
		// only aniimate the rollover once in the loop
		if(i == 0){
			fadeOut.onMotionFinished = function(){
				var ani = new Tween(element, "height", Strong.easeInOut, height, 0, 0.2);
				ani.onMotionFinished = function(){
					element.style.height = element.originalHeight + "px";
					element.style.visibility = "hidden";
					trigger.animating = false;
				}
			}
		}
	}
}

