var Navigation = Class.create();
Navigation.prototype = {

	Version: "1.0",
	sId: null,
	aNavigationHiders: new Array(), 
	
	/**
	 * initialize the navigation function
	 * 
	 * @param sId
	 * @param aOptions (@see setOptions)
	 * @return
	 */
	initialize: function(sId, aOptions)
	{

		this.sId = sId;
		this.setOptions(aOptions);
		
		Event.observe(window, 'load', this.initMenu.bind(this));
	}
	,
	
	/**
	 * set the options for this class
	 * @param aOptions
	 */
	setOptions: function(aOptions) {
	    this.aOptions = {
			sSubmenuSuffix: 'columns',
			sShowEffect: 'APPEAR',
			sHideEffect: 'FADE',
			sShowTime: '0.3',
			sHideTime: '0.2'
	    }
	    
	    Object.extend(this.aOptions, aOptions || {});
	 },
	 
	 /**
	  * initialize the menu
	  * 
	  * @return void
	  */
	 initMenu: function()
	 {
		 $(this.sId).childElements().each(this.initActions.bind(this));
		 
		this.aNavigationHiders.each(this.initNavigationHider.bind(this)); 
	 },
	
	 /**
	  * set's the action events for the menu
	  * 
	  * @return void
	  */
	 initActions : function(oElement)
	 {
		var oClone = this;
		
		var oSubmenu = $(oElement.id+'_'+this.aOptions.sSubmenuSuffix);
	
		//make all submenu's hidden
		oSubmenu.style.display = 'none';	
	
		//foreach element we are gonna set an action to show the submenu
		oElement.onmouseover = function(){ oClone.showMenu(oSubmenu);};
	 },
	 
	 /**
	  * initialize the navigation hiders
	  * 
	  * @param string sElement
	  * 
	  * @return void
	  */
	 initNavigationHider : function(sElement)
	 {
		var oClone = this;
		
		$(sElement).onmouseover = function(){oClone.hideMenu(oClone.getActiveMenu())};
	 },
	
	/**
	 * - show the menu if it's not active
	 * - if there is an active menu, hide it
	 * - set this menu as active
	 * - appear the menu
	 * 
	 * @param oEl
	 * @return void
	 */
	 showMenu : function(oEl)
	 {
	
		if(!this.isActiveMenu(oEl))
		{
			if(this.hasActiveMenu())
			{
				this.hideMenu(this.getActiveMenu());
			}
			
			this.setActiveMenu(oEl);
	
			var sEffectName = this.aOptions.sShowEffect;
			
			switch(sEffectName.toUpperCase())
			{
				case "APPEAR":
					new Effect.Appear(oEl, {duration: this.aOptions.sShowTime});
				break;
				case "SLIDEUP":
					new Effect.SlideUp(oEl, {duration: this.aOptions.sShowTime});
				break;
				case "GROW":
					new Effect.Grow(oEl, {duration: this.aOptions.sShowTime});
				break;
			}
		}
	},
	
	/**
	 * hide the menu
	 * 
	 * @param oEl
	 * @return void
	 */
	hideMenu : function(oEl)
	{
		if(oEl)
		{
			var sEffectName = this.aOptions.sHideEffect;
	
			switch(sEffectName.toUpperCase())
			{
				case "FADE":
					new Effect.Fade(oEl, {duration: this.aOptions.sHideTime});
				break;
				case "BLINDUP":
					new Effect.BlindUp(oEl, {duration: this.aOptions.sHideTime});
				break;
				case "FOLD":
					new Effect.Fold(oEl, {duration: this.aOptions.sHideTime});
				break;
				case "SLIDEDOWN":
					new Effect.SlideDown(oEl, {duration: this.aOptions.sHideTime});
				break;
				case "SHRINK":
					new Effect.Shrink(oEl, {duration: this.aOptions.sHideTime});
				break;
				case "SWITCHOFF":
					new Effect.SwitchOff(oEl, {duration: this.aOptions.sHideTime});
				break;
				case "PUFF":
					new Effect.Puff(oEl, {duration: this.aOptions.sHideTime});
				break;
				case "DROPOUT":
					new Effect.DropOut(oEl, {duration: this.aOptions.sHideTime});
				break;
			}
			
			this.setActiveMenu();
		}
	},
	
	/**
	 * check if an object is the active menu
	 * 
	 * @param oEl
	 * @return boolean
	 */
	isActiveMenu : function(oEl)
	{
		return oEl == this.getActiveMenu();
	},
	
	/**
	 * check if there is an active menu
	 * 
	 * @return boolean
	 */
	hasActiveMenu : function()
	{
		if(this.oActiveSubmenu){
			return true;
		}
		
		return false;
	},
	
	/**
	 * retuns the active submenu if available, else false
	 * 
	 * @return object/boolean
	 */
	getActiveMenu : function()
	{
		if(this.hasActiveMenu())
		{
			return this.oActiveSubmenu;
		}
		else
		{
			return false;
		}
	},
	
	/**
	 * set the active menu
	 * 
	 * @param oEl
	 * @return
	 */
	setActiveMenu : function(oEl)
	{
		this.oActiveSubmenu = oEl;	
	},
	
	/**
	 * hide the active menu onmouseover of the given element
	 * 
	 * @param sElement
	 * @return void
	 */
	addNavigationHider : function(sElement)
	{
		this.aNavigationHiders.push(sElement);
	}
}