/**
 * @author Kirill Mazin
 * @version 1.1
 */



/**
* Base class 
*/
var Core = Class.create({
	initialize: function(targetElement){
		this.targetElement 	= targetElement;	// div element where the menu is being generated
		this.items 			= []; // stores the menu items
		this.element    	= []; // stores html items that are dynamically generated
		this.html;			  // stores the final html output
		this.bg_id			= this.targetElement+'_bg';
		this.a_menu_id		= null; //id of the active menu
		this.l_menu_id		= null; //id of the last active menu
		this.menu_out_counter = 0;
	},
	
	getHTML : function(){
		return this.html;
	},
	
	/**
	* Firebug debugger
	*/
	trace: function(message){
		//console.log(message);
	}
})


/**
* Menu generating class
*/

var MenuGenerator = Class.create(Core, {
	initialize: function($super, targetElement){
		$super(targetElement);
		this.enableMenuArea();
	
	},
	
	
	addItem : function(menuObj){
		this.items.push(new Menu(menuObj,this.bg_id,this.targetElement));
		this.generate();
		this.inject();
		//this.hideBG();
		this.enable();
		
	},
	
	/**
	 * Makes the large background (mwnu class) receive events
	 */
	enableMenuArea: function(){
		document.observe("mouseover",this.handleBGOver.bind(this));
		$(this.targetElement).observe('mouseover',this.handleAreaEvents.bind(this));
		$(this.targetElement).observe('mouseout',this.handleAreaEvents.bind(this));
		
	},
	
	generate: function(){
		var h = this;
		this.element = [];
		
		// push the background element
		//this.element.push('<div id="'+this.bg_id+'" class="menu_bg">bg</div>');
		
		// push all the menus' html
	 	this.items.each(function(item){
	 		h.element.push(item.getHTML());
	 	});	
	 	
	 	this.html = this.element.join("");
	},
	
	/**
	* Make all menus active
	*/
	enable : function(){
		//this.trace("enable the menu " + this.targetElement);
		
		// enable all menus
		this.items.each(function(item){
	 		item.enable();
	 	});	

		// subscribe to menu events
	 	document.observe(this.targetElement+":menuIn",this.handleEvents.bind(this));
		document.observe(this.targetElement+":menuOut",this.handleEvents.bind(this));
		
		// subscribe to header events
		document.observe(this.targetElement+":headerIn",this.handleEvents.bind(this));
		document.observe(this.targetElement+":headerOut",this.handleEvents.bind(this));
	 	
	},
	
	
	/**
	* Events relevant to menu background
	*/
	handleBGOver : function (e){
		if(this.c_menu_id!=null){
			$(this.c_menu_id).hide();
			this.c_menu_id = null;
		}
		
		if(this.l_menu_id!=null){
			$(this.l_menu_id).removeClassName('testStyle');
			//this.c_menu_id = null;
		}
		
	},
	
	handleEvents : function (e){
		
		switch(e.memo.type){
			case "menuIn":
				this.c_menu_id = e.memo.last_list_id;
				$(this.c_menu_id).show();
				$(this.l_menu_id).addClassName('testStyle');
				break;
			case "menuOut":
				$(this.c_menu_id).hide();
				break;
			case "headerIn":	
				if(this.l_menu_id!=null){
				//	$(this.c_menu_id).hide();
					$(this.l_menu_id).removeClassName('testStyle');
				}
				$(e.memo.target).addClassName('testStyle');
				this.l_menu_id = e.memo.target;
				
				this.c_menu_id = e.memo.last_list_id;
				$(this.c_menu_id).show();
				
				break;
			case "headerOut":
				$(this.c_menu_id).hide();
				break;
		}
	},
	
	handleAreaEvents: function(e){
		e.stopPropagation();
		switch(e.type){
			case "mouseover":
				
				// show the active menu
				if(this.c_menu_id != null){
					$(this.c_menu_id).show();
				}
				
			
				break;
			case "mouseout":
				//$(this.c_menu_id).hide();
				// hide the active menu
				if(this.c_menu_id != null){
					$(this.c_menu_id).hide();
				
				}
				//this.c_menu_id = null;
				break;
			
		}
	},
	
	/**
	* Inject the generated html code into a specified div
	*/
	inject : function(){
		$(this.targetElement).update(this.html);
	},
	
	/**
	* Hides the menu background
	*/
	hideBG : function(){
		$(this.bg_id).hide();
	}
	

});

/**
 * Generates a menu section
 */
var Menu = Class.create(Core, {
	initialize:function($super,menuObj,bg_id,targetElement){
		$super(targetElement);
		this.menuObj 	 	= menuObj;
		this.id			 	= menuObj.id;
		this.header;
		this.header_id		= this.targetElement+'_'+this.id+'_header';
		this.header_url 	= menuObj.url;
		this.header_class	= menuObj.c;
		this.list_id		= this.targetElement+'_'+this.id+'_list';
		
	
		
		this.addItems();
		this.generate();
	},
	
	addItem : function(item){
		this.items.push(new MenuItem(item,this.targetElement+'_'+this.id+'_'+this.items.length));
	},
	
	addItems : function(){
		var h = this;
		this.addHeader(this.menuObj.name);
		this.menuObj.items.each(function(item){
			h.addItem(item);
		});
	},
	
	addHeader : function(item){
		this.header = "<div class='"+this.header_class+"'><a href='"+this.header_url+"' id='"+ this.header_id +"' class='"+this.header_class+"'>"+item +"</a></div>";
		//this.header = "<h1 id='"+ this.header_id+ "'>"+item +"</h1>";
	},
	
	generate: function(){
		var h = this;
		this.element.push("<div class='menu_section'>");
		this.element.push(this.header);
		this.element.push('<dl id="' + this.list_id + '">');
		this.items.each(function(item){
			h.element.push(item.getHTML());
		})
		this.element.push("</dl>");
		this.element.push("</div>")
		
		this.html = this.element.join("");
	},
	
	hideItems:function(){
		$(this.list_id).hide();
	},
	
	enable:function(){

		this.hideItems();
		
		// enable header events
		$(this.header_id).observe('mouseover',this.handleHeaderEvents.bind(this));
		$(this.header_id).observe('mouseout',this.handleHeaderEvents.bind(this));
		$(this.header_id).observe('click',this.handleHeaderEvents.bind(this));
		
		// enable menu events
		$(this.list_id).observe('mouseover',this.handleMenuEvents.bind(this));
		$(this.list_id).observe('mouseout',this.handleMenuEvents.bind(this));
	},
	
	/**
	* Header events
	*/
	handleHeaderEvents : function(e){
		e.stopPropagation();
		switch(e.type){
			case "mouseover":
				
			
				document.fire(this.targetElement+":headerIn",{type:'headerIn',last_list_id:this.list_id, id:this.id, target:e.element().id});

				break;
			case "mouseout":
				document.fire(this.targetElement+":headerOut",{type:'headerOut', last_list_id:this.list_id, id:this.id, target:e.element().id});
				break;
			case "click":
				location.href = this.header_url;
				break;
		}
	},	
	
	/**
	* Handles events relating to individual menu items
	*/
	handleMenuEvents :function(e){
		e.stopPropagation();
		switch(e.type){
			case "mouseover":
				document.fire(this.targetElement+":menuIn",{type:'menuIn',last_list_id:this.list_id});
				//$(this.list_id).show();
				break;
			case "mouseout":
				document.fire(this.targetElement+":menuOut",{type:'menuOut',last_list_id:this.list_id});
				break;
		}
	}	
});

/**
* Generates individual menu items
*/
var MenuItem = Class.create(Core,{
	initialize:function($super,menuItemObj,id){
		$super();
		this.item = menuItemObj; // object from which menu item is generated
		this.id = id;
		this.generate();
	},
	
	generate : function(){
		var fE = '<dd id="'+this.id+'"><a href="'+ this.item.url+'">';
		this.element.push(fE,this.item.content,"</a></dd>");
		this.html = this.element.join("");
	}
});



