Tradizio_Menu_Model = { 
_registry : new Hash(), 
_strCurrent : null, 

register : function(strIdentifier, objMenu) { 
  this._registry.set(strIdentifier, objMenu); 
  return this; 
}, 

registered : function(strIdentifier) { 
  return this._registry.keys().indexOf(strIdentifier) > -1; 
}, 

registry : function(strIdentifier) { 
  return this._registry.get(strIdentifier); 
}, 

setCurrent : function(strIdentifier) { 
  this._strCurrent = strIdentifier; 
}, 

hasCurrent : function(strIdentifier) { 
  return this._strCurrent != null; 
}, 

getCurrent : function(strIdentifier) { 
  return this._strCurrent; 
} 
}; 

Tradizio_Menu_EventHandler = { 
_objMouseMovementFunctions : new Hash(), 
   
onShow : function(strIdentifier) { 
  if( Tradizio_Menu_Model.getCurrent() == strIdentifier ) 
  { 
	return; 
  } 
   
  if( Tradizio_Menu_Model.hasCurrent() ) 
  { 
	this.onHide(Tradizio_Menu_Model.getCurrent()); 
  } 

  Tradizio_Menu_Model.setCurrent(strIdentifier); 
  var objCurrent = Tradizio_Menu_Model.registry(strIdentifier); 
  objCurrent.show(); 


  var fncMouseMove = 
this.handleBoundedMouseMovement.bindAsEventListener( 
	this,  
	objCurrent.getBoundedCoords(), 
	objCurrent.getIdentifier() 
  ); 
   
  this._objMouseMovementFunctions.set( 
	objCurrent.getIdentifier(),  
	fncMouseMove 
  ); 
   
  document.observe('mousemove', fncMouseMove); 
}, 

onHide : function(strIdentifier) { 
  if( this._objMouseMovementFunctions.keys().indexOf(strIdentifier) > 1 ) 
  { 
	document.stopObserving( 
	  'mousemove',  
	  this._objMouseMovementFunctions.get(strIdentifier) 
	); 
	 
	this._objMouseMovementFunctions.unset(strIdentifier); 
  } 
   
  if( Tradizio_Menu_Model.registered(strIdentifier) ) 
  { 
	Tradizio_Menu_Model.registry(strIdentifier).hide(); 
	if( Tradizio_Menu_Model.getCurrent() == strIdentifier ) 
	{ 
	  Tradizio_Menu_Model.setCurrent(null); 
	} 
  } 
}, 

handleBoundedMouseMovement : function(objEvent, objCoords, strIdentifier) { 
  var objPointer = objEvent.pointer(); 

  var isInHorizontal = ( 
	objPointer.x > objCoords.get('X1')  
	&& objPointer.x < objCoords.get('X2') 
  ); 

  var isInVertical = ( 
	objPointer.y > objCoords.get('Y1')  
	&& objPointer.y < objCoords.get('Y2') 
  ); 

  if( !isInHorizontal || !isInVertical ) 
  {         this.onHide(strIdentifier); 
  } 
} 
}; 

Tradizio_Menu = Class.create({ 
_strIdentifier : null, 
_elListItem : null, 
_elSubMenu : null, 

initialize : function(elAnchor) { 
  this._elListItem = elAnchor.up(); 
  this._strIdentifier = this._elListItem.identify(); 
  this._elSubMenu = this._elListItem.select('ul.sub').first(); 
  Tradizio_Menu_Model.register(this._strIdentifier, this); 

  this._elListItem.observe( 
	'mouseover',  
	this.onMouseOver.bindAsEventListener(this) 
  ); 
}, 

getIdentifier : function() { 
  return this._strIdentifier; 
}, 
 
getBoundedCoords : function() { 
  var arrPositionedOffset = this._elListItem.positionedOffset(); 
  var objListItemDimensions = this._elListItem.getDimensions(); 
  var objSubMenuDimensions = this._elSubMenu.getDimensions(); 

  return $H({ 
	X1 : arrPositionedOffset[0], 
	X2 : ( 
	  arrPositionedOffset[0] + objSubMenuDimensions.width 
	), 
	Y1 : arrPositionedOffset[1], 
	Y2 : ( 
	  arrPositionedOffset[1]  
	  + objListItemDimensions.height  
	  + objSubMenuDimensions.height 
	) 
  }); 
}, 
 
onMouseOver : function(objEvent) { 
  Tradizio_Menu_EventHandler.onShow(this._strIdentifier); 
  Event.stop(objEvent); 
},  
show : function() { 
  this._elListItem.addClassName('active');
  this._elSubMenu.show();     }, 

hide : function() { 
  this._elListItem.removeClassName('active'); 
  this._elSubMenu.hide(); 
} 
}); 

document.observe('dom:loaded', function(){ 
$$('ul.menu.hor>li>a').each(function(el) { 
  new Tradizio_Menu(el); 
}); 
}); 	
