$j.Avaya.MenuOverlay = function(options){
	
	var self = this,
		presets = {
			$item : '.menu-overlay-item',
			$menus : '.menu-overlay-menu',
			
			$actionIn : 'mouseover',
			$actionOut : 'mouseleave',
			
			$position : {
				xaxis : 'inner-left', xoffset : 0,
				yaxis : 'inner-top', yoffset : 0
			},
			
			$intent : false,
			$intentInterval : 300,
			
			$follow_link : true,
			
			$uiblocker : false,
			$uiblocker_class : '.ui-blocker',
			
			$transition_on : false,
			$transition : {
				anim_in : 'fadeIn', anim_out : 'fadeOut',
				speed_in : 250, speed_out : 250
			},
			
			$replacer : '.menu-overlay-replacer',
			$replacerBody : '.menu-overlay-replacer-body',
			$onstate_replacer : false,
			$fluid_replacer : false,
			
			$initCallback : function(){},
			$openCallback : function(){},
			$closeCallback : function(){}
		};
	
	this.s = $j.extend(true, presets, options);
	this.open = false;
	
	
    var menu_item = $j(this.s.$item);
	
    
	if( $j.Avaya.global.TDetector && $j.Avaya.global.TDetector.detect() ) {
		
        this.s.$intent = false;
        
		$j( document )
            .bind( 'touchstart', function( e ) {
                
                var target_item = $j( e.target ).parents( self.s.$item );
                
                
                if( self.open && !target_item.size() ) {
                    
                    menu_item.trigger( 'MenuOverlay.close' );
                    
	}
	
            } )
			.bind( 'click', function( e ) {
				
                e.stopPropagation();
                
                var target_item = $j( e.target ).parents( self.s.$item );
	
	
                if( !self.open && target_item.size() ) {
                    
                    e.preventDefault();
                    
                    target_item.siblings().trigger( 'MenuOverlay.close' );
                    target_item.trigger( 'MenuOverlay.open' );
                    
                }
	
	});
	
	}
	
	
    if(this.s.$intent){
		this.intents = {};
		menu_item.each(function(ix){
			$j(this).attr('data-hoverid', $j(this).find('.menu-link').text() + ix);
			self.intents[$j(this).attr('data-hoverid')] = { el : $j(this) };
		});
	}
	
	
	menu_item
        .bind('MenuOverlay.open', function(){ _showMenu($j(this)); })
        .bind('MenuOverlay.close', function(){ _hideMenu($j(this)); })
        .bind('MenuOverlay.bind', function(){
            $j(this).bind('MenuOverlay.'+self.s.$actionIn, function(){ $j(this).trigger('MenuOverlay.open'); });
            $j(this).bind('MenuOverlay.'+self.s.$actionOut, function(){ $j(this).trigger('MenuOverlay.close'); });
        })
        .bind('MenuOverlay.intent.in', function(){ _hoverIntentIn($j(this)); })
        .bind('MenuOverlay.intent.out', function(){ _hoverIntentOut($j(this)); })
        .bind('MenuOverlay.intent.bind', function(){
		$j(this).bind('MenuOverlay.intent.'+self.s.$actionIn, function(){ $j(this).trigger('MenuOverlay.intent.in'); });
		$j(this).bind('MenuOverlay.intent.'+self.s.$actionOut, function(){ $j(this).trigger('MenuOverlay.intent.out'); });
        })
        .bind(this.s.$actionIn, function(e){
            if(self.s.$intent) $j(this).trigger('MenuOverlay.intent.'+self.s.$actionIn);
            else $j(this).trigger('MenuOverlay.'+self.s.$actionIn);
	});
	
	
	if(this.s.$actionIn == 'click'){
		menu_item.find('.menu-link').each(function(){
			$j(this).click(function(e){
				var el = $j(this).parents(self.s.$item);
				
				if(self.s.$uiblocker){
					if($j(self.s.$uiblocker_class).size() > 0){
						if(!self.s.$follow_link){
				e.preventDefault()
				e.stopPropagation();
							
							$j( document ).trigger( 'MenuOverlay.ui-blocker.remove' );
						}
				
						_removeBlockUI(el);
					} else {
						e.preventDefault()
						e.stopPropagation();
						
						$j( document ).trigger( 'MenuOverlay.ui-blocker.create' );
						
						_createBlockUI(el);
						
						el.click();
					}
				}
			});
		});
	}
	
	if(!this.s.$uiblocker){
		menu_item.bind(this.s.$actionOut, function(e){
			if(self.s.$intent) $j(this).trigger('MenuOverlay.intent.'+self.s.$actionOut);
			else $j(this).trigger('MenuOverlay.'+self.s.$actionOut);
		});
	}
	
	
	if(this.s.$uiblocker) $j(window).resize(function(){ if($j(self.s.$uiblocker_class).size() > 0) _positionBlockUI(); });
	
	
	if(this.s.$intent) menu_item.trigger('MenuOverlay.intent.bind');
	else menu_item.trigger('MenuOverlay.bind');
	
	
	
	// for tabbed navigation
	
	menu_item.children('a')
		.focus(function(){
			
			var trigger = ( self.s.$intent ) ? 'MenuOverlay.intent.'+self.s.$actionIn : self.s.$actionIn;
			
			
			$j(this).parent().trigger( trigger );
			
		})
		.blur(function(){
			
			if( self.s.$intent && !self.open ) {
				
				$j(this).parent().trigger( 'MenuOverlay.intent.'+self.s.$actionOut );
				
			}
			
	});
	
	menu_item.each(function(){
		
		var $anchors = $j(this).children(self.s.$menus).find('a'),
			$last = $anchors.size() - 1;
		
		
		if($anchors.size() === 0){
			
			$j( this ).children( 'a' )
				.blur(
					function() {
						
						$j( this ).parents( self.s.$item ).trigger( 'MenuOverlay.' + self.s.$actionOut );
					
					}
				);
			
		} else {
			
			$anchors.each(function(ix){
				
				if( ix == $last ) {
					
					$j( this ).blur(
						function() {
							
							$j( this ).parents( self.s.$item ).trigger( 'MenuOverlay.' + self.s.$actionOut );
						
						}
					);
					
				}

			});
			
		}
		
	});
	
	
	
	// dimension assignments
	
	if(this.s.$onstate_replacer && this.s.$fluid_replacer) {
		menu_item.each(function(){
			var $this = $j(this),
				oh = $this.children('a').outerHeight(0),
				mb = parseInt($this.find(self.s.$replacerBody).css('marginBottom')) +
					 parseInt($this.find(self.s.$replacerBody).css('marginTop'));
			
			$this.find(self.s.$replacer).height((oh+mb)+'px');
			$this.find(self.s.$replacerBody).eq(0).height(oh+'px');
		});
	}
	
	
	
	this.s.$initCallback.call(this);
	
	// check if flagged after init
	
	if( this.s.$id && ( new $j.Avaya.QueryString() ).key[ 'overlay' ] == this.s.$id ) {
		
		var first_input = menu_item.find( 'input:eq(0)' );
		
		
		menu_item.trigger( this.s.$actionIn );
		menu_item.find( '.menu-link' ).click();
		
		setTimeout(
			function() {
				
				if( first_input.size() ) first_input.focus();
				
			},
			1
		);
		
	}
	
	
	
	// Private Methods
	
	function _showMenu(el){
		var $menu = el.find(self.s.$menus),
			$menu_width = $menu.width(), $menu_height = $menu.height(),
			$css = {};
		
		
		$j( document ).trigger( 'MenuOverlay._showMenu' );
		
		el.trigger('MenuOverlay.bind').unbind('MenuOverlay.'+self.s.$actionIn);
		
		if(self.s.$onstate_replacer) _showReplacerItem(el);
		if(self.s.$transition_on) $menu.css(self.getCSSPosition($menu_width, $menu_height))[self.s.$transition.anim_in](self.s.$transition.speed_in);
		else $menu.css(self.getCSSPosition($menu_width, $menu_height)).show();
		
		self.open = true;
		
		self.s.$openCallback.call(self, el);
	}
	
	function _hideMenu(el){
		var $menu = el.find(self.s.$menus);
		
		self.open = false;
		
		if(self.s.$onstate_replacer) _hideReplacerItem(el);
		if(self.s.$transition_on) $menu[self.s.$transition.anim_out](self.s.$transition.speed_out);
		else $menu.hide();
		
		el.trigger('MenuOverlay.bind').unbind('MenuOverlay.'+self.s.$actionOut);
		
		self.open = false;
		
		self.s.$closeCallback.call(self, el);
	}
	
	function _hoverIntentIn(el){
		var hoverid = el.attr('data-hoverid');
		
		el.trigger('MenuOverlay.intent.bind').unbind('MenuOverlay.intent.'+self.s.$actionIn);
		
		if(self.intents[hoverid].out){ clearTimeout(self.intents[hoverid].out); }
		else {
			for(intent in self.intents){
				if(self.intents[intent].out){
					clearTimeout(self.intents[intent].out);
					self.intents[intent].out = null;
				}
			}
			
			self.intents[hoverid].enter = setTimeout(function(){
				for(intent in self.intents) _hoverIntentHide(intent);
				
				self.intents[hoverid].enter = null;
				_hoverIntentShow(hoverid);
			}, self.s.$intentInterval);
		}
		
		self.s.$openCallback.call(self, el);
	}
	
	function _hoverIntentOut(el){
		var hoverid = el.attr('data-hoverid');
		
		el.trigger('MenuOverlay.intent.bind').unbind('MenuOverlay.intent.'+self.s.$actionOut);
		
		if(self.intents[hoverid].enter){
			clearTimeout(self.intents[hoverid].enter);
			
			for(intent in self.intents){
				if(self.intents[intent].open && !self.intents[intent].enter)
					self.intents[intent].out = _hoverIntentGetOutTimeout(intent);
			}
			
			self.s.$closeCallback.call(self, el);
		} else {
			self.intents[hoverid].out = _hoverIntentGetOutTimeout(hoverid);
		}
	}
	
	function _hoverIntentGetOutTimeout(id){
		var timeout = setTimeout(function(){
			self.intents[id].out = null;
			_hoverIntentHide(id);
		}, self.s.$intentInterval);
		
		return timeout;
	}
	
	function _hoverIntentShow(id){
		self.intents[id].open = true;
		_showMenu(self.intents[id].el);
	}
	
	function _hoverIntentHide(id){
		if(typeof self.intents[id].el != 'undefined' && typeof self.intents[id].open != 'undefined' && self.intents[id].open){
			self.intents[id].open = false;
			_hideMenu(self.intents[id].el);
		}
	}
	
	function _showReplacerItem(el){ el.find(self.s.$replacer).show(); }
	
	function _hideReplacerItem(el){ el.find(self.s.$replacer).hide(); }
	
	function _createBlockUI(el){
		el.addClass('ui-blocker-on').parent().prepend(
			'<div class="' + self.s.$uiblocker_class.substr(1) + '" />'
		).click(function(e){
			e.stopPropagation();
		});
		
		$j(self.s.$uiblocker_class).add('#footer').bind('click', function(e){
			e.stopPropagation();
			_removeBlockUI(el)
		});
		
		_positionBlockUI();
	}
	
	function _positionBlockUI(){
		var uiblocker = $j(self.s.$uiblocker_class),
			reset = { left : 0, width : 1, height : 1 },
			page = $j('#page');
		
		uiblocker.css(reset).css({
			left : -(uiblocker.offset().left+1),
			width : page.width(),
			height : page.height()
		});
	}
	
	function _removeBlockUI(el){
		$j(self.s.$uiblocker_class).remove();
		el.removeClass('ui-blocker-on');
		_hideMenu($j(el));
	}

};


$j.Avaya.MenuOverlay.prototype = {
	
	getCSSPosition : function(w, h){
		var $css = {};
		
		switch(this.s.$position.yaxis){
			case 'outer-top':
				$css['top'] = (-h+this.s.$position.yoffset)+'px'; break;
			case 'inner-top':
				$css['top'] = this.s.$position.yoffset+'px'; break;
			
			case 'outer-bottom':
				$css['bottom'] = (-h+this.s.$position.yoffset)+'px'; break;
			case 'inner-bottom':
				$css['bottom'] = this.s.$position.yoffset+'px';
		}
		
		switch(this.s.$position.xaxis){
			case 'outer-left':
				$css['left'] = (-w+this.s.$position.xoffset)+'px'; break;
			case 'inner-left':
				$css['left'] = this.s.$position.xoffset+'px'; break;
			
			case 'outer-right':
				$css['right'] = (-w+this.s.$position.xoffset)+'px'; break;
			case 'inner-right':
				$css['right'] = this.s.$position.xoffset+'px';
		}
		
		return $css;
	}
	
};
