// Menu v4.2 - December 2008

// Copyright (c) 2008 Luca Reghellin - http://www.reghellin.com
// MIT-style license.

var Menu = new Class({

	Implements:Options,
	
	options:{
		menuId:"mainMenu",
		type:'bar',
		morph:false,
		fx:'default',
		propsNames:{
			overProps:'overProps',
			outProps:'outProps',
			activeProps:'activeProps',
			subOverProps:'subOverProps',	
			subOutProps:'subOutProps',	
			subActiveProps:'subActiveProps'			
		},
		props:{
			overProps:{'color':'#000'},
			outProps:{'color':'#000'},
			activeProps:{'color':'#000'},
			subOverProps:{'color':'#000'},
			subOutProps:{'color':'#000'},
			subActiveProps:{'color':'#000'}
		}
	},

	initialize:function(options){
		
		this.setOptions(options);
		var o = this.options;
		this.menuId = o.menuId;
		this.type = o.type;
		this.morph = o.morph;
		this.fx = o.fx;
				
		this.intId1 = null;
		this.mainButtons = null;
		this.subs = null;
		this.activeButton = null;
		this.busy = null;

		this.openOnOver = false; 
		this.startButton = null;  
		this.openSub = false;

		this.currentState = null;
		this.overButton = null;
		this.outButton = null;
		this.clickButton = null;
		this.currentOpener = null;

		var n=o.propsNames;
		var p=o.props;
		this.outProps = p[n.outProps] || p.outProps;
		this.overProps = p[n.overProps] || p.overProps;
		this.activeProps = p[n.activeProps] || p.activeProps;
		this.subOverProps = p[n.subOverProps] || p.subOverProps;
		this.subOutProps = p[n.subOutProps] || p.subOutProps;
		this.subActiveProps = p[n.subActiveProps] || p.subActiveProps;
		
		this.initMenu();
		
		this.fxOptions = {}; 
		this.fxFunction = this.setFx();
	},
	
	initMenu:function(){
		var mainMenu = $(this.menuId).getChildren();
		this.mainButtons = $$(mainMenu.map(function(li){ return li.getElement('a'); } ));
		this.subs = $$(mainMenu.map(function(li){ return li.getElement('div ul'); } ));

		this.mainButtons.each(function(b){
			b.sub = b.getParent().getElement('ul');
			
			if(b.sub){
				var submenu = b.sub.getElements('li a');
				$$(submenu).addEvents({
					'click':function(e){
						//GESTIRE IL CLICK DEI SUB AL MOMENTO NON SERVE: SERVE SOLO IN CONTESTI AJAX.
						//var b_sub=($(e.target).match('a')) ? $(e.target) : $(e.target).getParent('a');
						//b_sub.setStyles(this.subActiveProps);
						//b_sub.store('active',true);
						
						b.change(this.activeProps);
						b.store('active',true);
						this.activeButton = b;
						this.openOnOver = false;
						this.stopCloseTimer();
					}.bindWithEvent(this),
					
					'mouseover':function(e){
						var b_sub=($(e.target).match('a')) ? $(e.target) : $(e.target).getParent('a');
						if(!b_sub.retrieve('active')){ b_sub.setStyles(this.subOverProps); }
					}.bindWithEvent(this),
					
					'mouseout':function(e){
						var b_sub=($(e.target).match('a')) ? $(e.target) : $(e.target).getParent('a');
						if(!b_sub.retrieve('active')){ b_sub.setStyles(this.subOutProps); }
					}.bindWithEvent(this)
					
				});
			}
			
			if(this.morph){
				b.set('morph',{duration:'short',transition:'linear',link:'cancel'});
				b.change = this.morphFx;
			} else { b.change = this.styleFx; }
			
			
		},this);
		
		this.mainButtons.addEvents({
			'click':function(e){
				var b=($(e.target).match('a')) ? $(e.target) : $(e.target).getParent('a');
				this.currentState = 'click';
					
				if($chk(b.sub)){ e.preventDefault(); }
								
				if(b == this.activeButton && b != this.startButton){
					return; 
				} else if( b == this.currentOpener ){
					this.closeMenu(b);
					this.openOnOver = false;
					this.currentOpener = null;
				} else {
					this.openMenu(b);
					if($chk(b.sub) && this.type == "bar"){ 
						this.openOnOver = true; 
					} else { this.openOnOver = false; }
				}
				
				this.clickButton = b;

			}.bindWithEvent(this),
			
			'mouseover':function(e){
				var b=($(e.target).match('a')) ? $(e.target) : $(e.target).getParent('a');
								
				if(b == this.activeButton){ return; }
				
				this.currentState = 'over';

				if(this.type == 'bar' && this.openOnOver){ this.openMenu(b); }
				else{ b.change(this.overProps); }
				
				this.overButton = b;

			}.bindWithEvent(this),
			
			'mouseout':function(e){				
				var b=($(e.target).match('a')) ? $(e.target) : $(e.target).getParent('a');
				
				this.currentState = 'out';
				
				if(b == this.activeButton || (this.type == 'bar' && $chk(b.sub) && this.openOnOver == true) ){ 
					return;
				} else { b.change(this.outProps); }
				
				this.outButton = b;
				
			}.bindWithEvent(this)
		});
		
	},
	

	openMenu:function(b){

		if(this.currentState == 'click'){

			if(this.activeButton){
				this.closeMenu(this.activeButton);
			}

			if($chk(b.sub)){
				this.fxFunction(b.sub,1);
				b.change(this.overProps);
				this.currentOpener = b;
				this.startCloseTimer(b);
			} 

			if(!$chk(b.sub) || this.type == "accordion"){
				this.stopCloseTimer();
				b.change(this.activeProps);
				this.activeButton = b;
			}			
		}
		
		if(this.currentState == 'over'){
		
			if($chk(this.currentOpener) && this.currentOpener != b && this.currentOpener != this.activeButton){
				this.closeMenu(this.currentOpener,false);
			}
			
			if($chk(b.sub) && this.openOnOver){
				this.fxFunction(b.sub,1);
				this.currentOpener = b;
				this.startCloseTimer(b);
			}
			
			b.change(this.overProps);
		}
				
	},
	
	closeMenu:function(b,timerCall){

		if(timerCall){
			this.fxFunction(b.sub,0);
			this.currentOpener = null;
			this.activeButton = null;
			this.openOnOver = false;
		}

		if(this.currentState == 'click'){

			if($chk(b.sub)){ 
				this.stopCloseTimer();
				this.fxFunction(b.sub,0);
				this.currentOpener = null
			}
						
			this.activeButton = null;
		}
		
		if(this.currentState == 'over'){
				this.fxFunction(b.sub,0);
				this.currentOpener = null;
		}
		
		b.change(this.outProps);
	},
	
	startCloseTimer:function(b){
		if(this.type == 'bar'){
			this.stopCloseTimer();
			this.intId1 = this.closeMenu.delay(5000,this,[b,true]);
		}	
	},
	
	stopCloseTimer:function(b){
		if(this.type == 'bar'){
			if($chk(this.intId1)){ $clear(this.intId1); }
		}	
	},

	morphFx:function(props){ this.morph(props); },
	styleFx:function(props){ this.setStyles(props); },
	
	defaultFx:function(sub,type){
		if(type == 1){ sub.setStyle('display','block'); }
		else{ sub.setStyle('display','none'); }
	},

	fadeFx:function(sub,type){
		if(type == 1){ sub.tween('opacity',1); }
		else{ 
			if(this.type == 'bar'){ sub.tween('opacity',0); }
			else { sub.setStyles({'opacity':0,'display':'none'}); }
		}
	},
	
	slideFx:function(sub,type){
		if(type == 1){ sub.slide('in'); }
		else{ sub.slide('out'); }
	},
	
	blindFx:function(sub,type){
		if(type == 1){ sub.tween('height',sub.h); }
		else{ sub.tween('height',0); }
	},
	
	prepareFadeFx:function(){
		this.fxOptions = { 
			'link':'cancel',
			'transition':'sine:out',
			'onStart':function(){ if(this.element.getStyle('opacity') == 0){ this.element.setStyle('display','block'); } },
			'onComplete':function(){ if(this.element.getStyle('opacity') == 0){ this.element.setStyle('display','none'); } }
		}
		
		this.subs.setStyles({'opacity':0});
		this.subs.set('tween',this.fxOptions);
	},
	
	prepareSlideFx:function(){
		this.fxOptions = { 'link':'cancel','transition':'sine:out' }
		this.subs.set('slide',this.fxOptions);
		this.subs.setStyles({'visibility':'hidden','display':'block'});
		this.subs.slide('hide').setStyle('visibility','visible');
	},
	
	prepareBlindFx:function(){
		this.fxOptions = { 'link':'cancel','transition':'quint:out' }
		this.subs.set('tween',this.fxOptions);
		this.subs.setStyles({'overflow':'hidden','display':'block'});
		this.subs.each(function(s){ s.h = s.getSize().y; /*console.log(s.h)*/ });
		this.subs.setStyle('height',0);
	},
	
	
	setFx:function(){
		switch(this.fx){
			case 'fade':
				this.prepareFadeFx();
				return this.fadeFx;
				break;
			case 'slide':
				this.prepareSlideFx();
				return this.slideFx;
				break;
			case 'blind':
				this.prepareBlindFx();
				return this.blindFx;
				break;
			default:
				this.fxtype = 'default';
				return this.defaultFx;
		}
	},


	setStartButton:function(o){
		var b= ($chk(o.mainIndex)) ? this.mainButtons[o.mainIndex] : ($chk(this.activeButton)) ? this.activeButton : null;
		if(b == null){ alert('Error: mainMenu :: setStartButton : options error'); return; }
		this.startButton = b;
		
		var subIndex = ($chk(o.subIndex)) ? o.subIndex : null;
		
		if(b.sub && subIndex != null){
			var b_sub = b.sub.getElements('a')[subIndex];
			b_sub.setStyles(this.subActiveProps);
			b_sub.store('active',true);
		}
		
		if($chk(o.openSub)){
			this.fxFunction(b.sub,1);
			b.change(this.overProps);
			this.currentOpener = b;
			this.openSub = true;
		}
		
		else { 
			b.change(this.activeProps);
		}
		
		this.activeButton = b;
	}

});



