/**
 * @class Navigation
 * @author Adam "NiX0n" VanBerlo
 * @requires Prototype >= 1.6.0
 * @requires Navigation CSS
 * @copyright (c)2009 Adam "NiX0n" VanBerlo
 * @license Navigation is licensed under a Creative Commons 
 * 		Attribution 3.0 United States License 
 * 		<http://creativecommons.org/licenses/by/3.0/us/>
 * @classDescription Provides a W3C standards compliant navigation.
 * Complete with contextual linked data and minimalist JavaScript.
 */
var Navigation = 
{
	//
	// Constants
	//
		
	/**
	 * Tag name of menu wrapper
	 * @var string
	 */
	TAG: 'ul',
	
	//
	// Properties
	//
		
	/**
	 * Collection of parent menus
	 * @var HTMLElement[]
	 */
	menus: null,
	
	/**
	 * Parent menu currently active
	 * @var HTMLElement
	 */
	active: null,
	
	doPreventClick: false,

	//
	// Methods
	//
	
	/**
	 * Prepare navigation menus with necessary event listeners
	 * @param HTMLElement[] elements
	 */
	prepare: function(elements)
	{
		Navigation.menus = $A(elements);
		Navigation.hideAll();
		Navigation.menus.each(function(menu)
		{
			var submenus = menu.immediateDescendants();
			menu.observe('mouseout', Navigation.menu_Mouseout);
			menu.observe('click', Navigation.menu_Click);
			submenus.each(function(submenu) 
			{
				submenu.observe('mouseover', Navigation.submenu_Mouseover);
			});
		});
	},
	
	
	/**
	 * Hide all submenus
	 */
	hideAll: function()
	{
		Navigation.active = null;
		Navigation.menus.each(function(menu)
		{
			Navigation.show(menu, false);
		});
	},
	

	/**
	 * Show/Hide submenu
	 * @param HTMLElement parent parent menu
	 * @param boolean show true, show; false, hide
	 */
	show: function (parent, show)
	{
		// find submenu and hide/show
		parent.select(Navigation.TAG).invoke(show ? 'show' : 'hide');
	},

	/**
	 * Menu 'mouseout' event handler
	 * @param Event event
	 */
	menu_Mouseout: function (event)
	{
		var x = Event.pointerX(event);
		var y = Event.pointerY(event);
		var submenu = this.select(Navigation.TAG).first();
		if(!submenu) return;
		var inside = Position.within(this, x, y) || Position.within(submenu, x, y);
		if(!inside)
		{
			Navigation.show(this, false);
			Navigation.active = null;
		}
	},
	
	/**
	 * Menu 'click' event handler
	 * @param Event event
	 */
	menu_Click: function (event)
	{
		if(Navigation.doPreventClick)
			Event.stop(event);
	},

	/**
	 * Submenu 'mouseover' event handler
	 * @param Event event
	 */
	submenu_Mouseover: function (event)
	{
		var menu = this.parentNode;
		if(Navigation.active !== menu)
		{
			Navigation.hideAll();
			Navigation.active = menu;
			Navigation.show(menu, true);
			Navigation.preventClick();
		}
	},
	
	/**
	 * Temporarily (1/10th second) prevent top menu click
	 * This prevents browsers (mobile) from sending mouseover AND click
	 * events simultaneously.
	 */
	preventClick: function()
	{
		Navigation.doPreventClick = true;
		new PeriodicalExecuter(function(pe) 
		{
			Navigation.doPreventClick = false;
			pe.stop();
		}, .1);
	}
};

