var dropdownMenus = [];
var dropdownMenuAlignment = {
	TOP_LEFT		: 'tl',
	TOP_RIGHT		: 'tr',
	BOTTOM_LEFT		: 'bl',
	BOTTOM_RIGHT	: 'br'
};
var dropdownMenuAnimationType = {
	FADE			: 'f',
	TOP_TO_BOTTOM	: 'ttb',
	LEFT_TO_RIGHT	: 'ltr'
};

var DropdownMenu = $.Class.create({
	/******* PROPERTIES *******/
	_id : 0,
	_subMenus : null,
	_elMenu : null,
	_elShadows : null,
	_elTrigger : null,
	_timer : null,
	_menuAlignment : dropdownMenuAlignment.BOTTOM_LEFT,
	_animationType : dropdownMenuAnimationType.TOP_TO_BOTTOM,
	_expandedHeight : 0,
	_expandedWidth : 0,
	_manualLeftPad: 0,
	_manualTopPad: 0,
	
	/******* CONSTRUCTOR *******/
	initialize: function(properties){
		this._subMenus = [];
		
		if(properties.menuAlignment) this._menuAlignment = properties.menuAlignment;
		if(properties.animationType) this._animationType = properties.animationType;
		if(properties.manualLeftPad) this._manualLeftPad = properties.manualLeftPad;
		if(properties.manualTopPad) this._manualTopPad = properties.manualTopPad;
		
		var menu = properties.elMenu;
		this._elMenu = $('<div></div>');
		this._elMenu.css({
			'position'		: 'absolute',
			'top'			: '0px',
			'left'			: '0px'
		});
		menu.remove();
		this._elMenu.append(menu);
		$('body').append(this._elMenu);
		
		this._elTrigger = properties.elTrigger;
		
		this._id = dropdownMenus.length;
		dropdownMenus.push(this);
		
		menu.css('display', 'block');
		this._expandedHeight = menu.height() + 2;
		this._expandedWidth = menu.width() + 2;
		this._elMenu.css('overflow', 'hidden');
		this._elMenu.width(this._expandedWidth);
		this._elMenu.height(this._expandedHeight);
		
		this.alignMenu();
		
		this._elShadows = $('<div><div class="left_right"></div><div class="bottom"></div></div>');
		this._elShadows.addClass('nav_menu_shadows');
		this._elShadows.width(this._expandedWidth);
		this._elShadows.height(this._expandedHeight - 2);
		this._elShadows.css({
			'position'		: 'absolute',
			'top'			: '0px',
			'left'			: '0px'
		});
		$('body').append(this._elShadows);
		
		this._elMenu.remove();
		$('body').append(this._elMenu);

		//create submenus
		var menuItemLis = this._elMenu.find('ul[class~=nav_menu] > li');
		for(var i=0; i<menuItemLis.length; i++)
		{
			//get the menu
			var elMenu = $(menuItemLis[i]).find('> ul[class~=nav_menu]');
			if(elMenu.length == 0) continue;
			elMenu = $(elMenu[0]);
			
			//get the trigger
			var elTrigger = $(menuItemLis[i]).find('> a');
			if(elTrigger.length == 0) continue;
			elTrigger = $(elTrigger[0]);
			
			var submenu = new DropdownMenu({
				elMenu			: elMenu,
				elTrigger		: elTrigger,
				menuAlignment	: dropdownMenuAlignment.TOP_RIGHT,
				animationType	: dropdownMenuAnimationType.LEFT_TO_RIGHT,
				manualLeftPad	: 9
			});
			
			this._subMenus.push(submenu);
			submenu._elMenu.bind('shown', {self:this}, function(evt){
				evt.data.self.clearTimer();
			});
			
			submenu._elMenu.bind('hidden', {self:this}, function(evt, mouseX, mouseY){
				evt.data.self.subMenuHidden(mouseX, mouseY);
			});
		}
		
		this._elTrigger.bind('mouseover', {self: this}, function(evt){
			evt.data.self.show();
		});
		
		this._elMenu.bind('mouseover', {self: this}, function(evt){
			evt.data.self.show();
		});
		
		this._elTrigger.bind('mouseout', {self: this}, function(evt){
			evt.data.self.startHideTimer(evt);
		});
		
		this._elMenu.bind('mouseout', {self: this}, function(evt){
			if(!evt.data.self.mouseWithinMenu(evt.pageX, evt.pageY)) evt.data.self.startHideTimer(evt);
		});
		
		this.forceHide();
	},
	
	/******* ALIGNMENT *******/
	alignMenu: function(){
		var triggerAlignment = this._elTrigger.offset();
		
		var top = 0;
		var left = 0;
		
		//top
		if(this._menuAlignment == dropdownMenuAlignment.BOTTOM_LEFT || this._menuAlignment == dropdownMenuAlignment.BOTTOM_RIGHT)
		{
			top = triggerAlignment.top + this._elTrigger.height() + this._manualTopPad;
		}
		else
		{
			top = triggerAlignment.top;
		}
		
		//left
		if(this._menuAlignment == dropdownMenuAlignment.BOTTOM_LEFT || this._menuAlignment == dropdownMenuAlignment.TOP_LEFT)
		{
			left = triggerAlignment.left;
		}
		else
		{
			left = triggerAlignment.left + this._elTrigger.width() + this._manualLeftPad;
		}
		
		this._elMenu.css({
			top			: top + 'px',
			left		: left + 'px'
		});
		
		if(this._elShadows)
		{
			this._elShadows.css({
				top			: top + 'px',
				left		: left - 4 + 'px'
			});
		}
	},
	
	/******* SHOW *******/
	show: function(){
		
		this.clearTimer();
		this._elMenu.css('display', '');
		this._elShadows.css('display', '');
		this.alignMenu();
		
		this._elMenu.trigger('shown');
		
		if(true)//if($.browser.msie && $.browser.version <= 6)
		{
			if(this._animationType == dropdownMenuAnimationType.TOP_TO_BOTTOM) this._elMenu.height(this._expandedHeight);
			else if(this._animationType == dropdownMenuAnimationType.LEFT_TO_RIGHT) this._elMenu.width(this._expandedWidth);
			return;
		}
		
		var opts = {};
		
		if(this._animationType == dropdownMenuAnimationType.FADE)
		{
			opts = {
				opacity: 1
			};
		}
		else if(this._animationType == dropdownMenuAnimationType.TOP_TO_BOTTOM)
		{
			opts = {
				height:	this._expandedHeight,
				opacity: 1
			};
		}
		else if(this._animationType == dropdownMenuAnimationType.LEFT_TO_RIGHT)
		{
			opts = {
				width:	this._expandedWidth,
				opacity: 1
			};
		}
		
		this._elMenu.animate(opts, 150);
		
		//if(!$.browser.msie && false) this._elShadows.animate(opts, 150);
		if(false) this._elShadows.animate(opts, 150);
	},
	
	/******* HIDE *******/
	hide: function(mouseX, mouseY){
		
		this.clearTimer();
		var self = this;
		
		if(true)//if($.browser.msie && $.browser.version <= 6)
		{
			this.forceHide(mouseX, mouseY);
			return;
		}

		var opts = {};

		if(this._animationType == dropdownMenuAnimationType.FADE)
		{
			opts = {
				opacity: 0
			};
		}
		else if(this._animationType == dropdownMenuAnimationType.TOP_TO_BOTTOM)
		{
			opts = {
				height:	0,
				opacity: 0
			};
		}
		else if(this._animationType == dropdownMenuAnimationType.LEFT_TO_RIGHT)
		{
			opts = {
				width:	0,
				opacity: 1
			};
		}
		
		this._elMenu.animate(opts, 150, function(){
			self.forceHide(mouseX, mouseY);
		});
		
		this._elShadows.css('display', 'none');
		
		//if(!$.browser.msie && false) this._elShadows.animate(opts, 150);
		if(false) this._elShadows.animate(opts, 150);
	},
	
	forceHide: function(mouseX, mouseY){
		
		if(this._animationType == dropdownMenuAnimationType.TOP_TO_BOTTOM) this._elMenu.height(0);
		else if(this._animationType == dropdownMenuAnimationType.LEFT_TO_RIGHT) this._elMenu.width(0);
		
		this._elMenu.css('display', 'none');
		this._elShadows.css('display', 'none');
		this._elMenu.trigger('hidden', [mouseX, mouseY]);
	},
	
	subMenuHidden: function(mouseX, mouseY){
		if (this.mouseWithinMenu(mouseX, mouseY)) this.hide();
	},
	
	mouseWithinMenu : function(mouseX, mouseY){
		var offset = this._elMenu.offset();
		return !(mouseX < offset.left || mouseX >=offset.left + this._expandedWidth || mouseY < offset.top || mouseY > offset.top + this._expandedHeight);
	},
	
	/******* TIMER RELATED *******/
	startHideTimer: function(evt){
		
		var mouseX = evt.pageX;
		var mouseY = evt.pageY;
		this._timer = setTimeout('dropdownMenus['+this._id+'].hide(' + mouseX + ', ' + mouseY + ');', 100);
	},
	
	clearTimer: function(){
		if(this._timer == null) return;
		
		clearTimeout(this._timer);
		this._timer = null;
	}
});
