var Submenu = new Class(Observer, {
	include: Options,
	
	Options: {
		delay: 500
	},	
	
	initialize: function(submenu, button, mainMenu, options) {
		this.setOptions(options);
		
		this.mainMenu = mainMenu;
		this.button = button;
		this.submenu = submenu;
		this.fade = new Fx.Fade(submenu, {
				duration: "short",
				engine: "javascript",
				onFinish: function() { this.doneFade() }.bind(this),
				onStart: function() { this.startFade() }.bind(this)
			}
		);
		
		this.timeOut = null;
		this.isActive = false;
		this.transitionIn = false;
		this.transitionOut = false;
		this.bypassLock = false
		
		this.id = submenu.get("id");
	},
	
	startFade: function() {
		if (this.fade.how == "in") {
			this.transitionIn = true;
		} else {
			this.transitionOut = true;
		}
	},
	
	doneFade: function() {
		if (this.fade.how == "in") {
			this.isActive = true;
		} else {
			this.isActive = false;
		}
		
		this.transitionIn = false;
		this.transitionOut = false;
	},
	
	doneHighlight: function() {
		if (!this.button.hasClass("hover")) {
			this.button.addClass("hover");
		}
	},
	
	delayFadeStart: function() {
		if (!this.timeOut) {
			this.timeOut = setTimeout(function(){ this.fadeOut() }.bind(this), this.options.delay);
		}
	},
	
	delayFadeStop: function() {
		if (this.timeOut) {
			clearTimeout(this.timeOut);
			this.timeOut = null;
		}
	},
	
	highlightButton: function() {
		if (!this.button.hasClass("hover")) {
			this.button.addClass("hover");
		}
	},
	
	deHighlightButton: function() {
		if (this.button.hasClass("hover")) {
			this.button.removeClass("hover");
		}	
	},
	
	fadeIn: function() {
		this.delayFadeStop();
		
		if ((!this.isActive && !this.transitionIn && !this.transitionOut) || (this.bypassLock && !this.transitionIn)) {						
			this.submenu.setStyle({
				"z-index": "500",
				"display": "block"
			});
			
			//this.fade.finish();
			//this.fade.start('in');
			
			this.fire('opened');
			
			this.transitionIn = false;
			this.isActive = true;		
			this.bypassLock = false;
			this.highlightButton();
		}
	}, 
	
	forceFadeOut: function() {
		this.fadeOut(true);
	},
	
	fadeOut: function(force) {
		this.delayFadeStop();	
		
		if ((this.isActive && !this.transitionOut) || force) {
			this.submenu.setStyle({
				"z-index": "100",
				"display": "none"
			});

			//this.fade.finish();
			//this.fade.start('out');
			
			this.fire('closed');
			
			this.transitionOut = false;
			this.isActive = false;
			this.deHighlightButton();
		}
	}			
});

var MainMenu = new Class(Observer, {
	initialize: function() {					
		this.subMenus = {};
		this.activeSubMenu = null;
		this.cameFromButton = null;
		
		$("mainmenu").on({
			mouseover: function(e) { this.onMouseOver(e) }.bind(this),
			mousemove:  function(e) { this.onMouseMove(e) }.bind(this),
			mouseout:  function(e) { this.onMouseOut(e) }.bind(this)
		});
							
		$("mainmenu").find(".has_submenu").each(
			function(element) {
				var subMenu = new Submenu(element.find(".submenu").first(), element, this);
				
				subMenu.on({
					opened: function() { this.onSubmenuOpened() }.bind(this),
					closed: function() { this.onSubmenuClosed() }.bind(this)
				});
				
				this.subMenus[subMenu.id] = subMenu;
			}.bind(this)
		);
	},
	
	onSubmenuOpened: function() {
		this.fire('opened');
	},
	
	onSubmenuClosed: function() {
		this.fire('closed');
	},
	
	getSubmenuButton: function(e) {
		return e.find(".has_submenu");
	},
	
	getSubmenu: function(e) {
		var li = this.getSubmenuButton(e);
		var ul = null;
		
		if (li){
			ul = li.find(".submenu").first();
		}
		return (ul) ? this.subMenus[ul.get("id")] : null;
	},
	
	onMouseOver: function(e) {
		var subMenuButton = this.getSubmenuButton(e);
		
		if (subMenuButton) {
			var pos = e.position();
			var liDimensions = subMenuButton.dimensions();
			
			if (pos.y >= liDimensions.top &&
				pos.y <= liDimensions.top + liDimensions.height + 1) {
				
				this.cameFromButton = subMenuButton;
			}
		} else {
			this.cameFromButton = null;
		}
		return false;
	},
	
	onMouseMove:function(e) {
		var subMenu = this.getSubmenu(e);
		var subMenuButton = this.getSubmenuButton(e);
			
		if (this.activeSubMenu && this.activeSubMenu != subMenu) {
			this.activeSubMenu.forceFadeOut();
		}		
	
		if (subMenu && subMenu.button == this.cameFromButton) {
			subMenu.fadeIn();
		}
		
		this.activeSubMenu = subMenu;
		return false;
	},
	
	onMouseOut: function(e) {
		var subMenu = this.getSubmenu(e);
		
		if (subMenu) {
			var pos = e.position();
			var subMenuDimensions = subMenu.submenu.dimensions();
			var liDimensions = subMenu.button.dimensions();
			
			if (pos.x <= subMenuDimensions.left ||
				pos.x >= subMenuDimensions.left + subMenuDimensions.width ||
				pos.y >= subMenuDimensions.top + subMenuDimensions.height) {
				
				subMenu.bypassLock = false;
				subMenu.delayFadeStart();
			} else if (pos.y <= liDimensions.top) {
				subMenu.forceFadeOut();
				subMenu.bypassLock = true;
			} else if ((pos.y < liDimensions.top + liDimensions.height) && 
					   (pos.x >= liDimensions.left + liDimensions.width || pos.x <= liDimensions.left)) {
				subMenu.bypassLock = true;
			}
		}
		return false;
	}
});
