

// ------------------------------------------------------------ class SubMenu
function SubMenu(button, panel) {
	
	//------------------------------------------------------------- variables
	this.button = $(button);
	// hereby binding SubMenu object to button
	// to find SubMenu object without context, just by button id
	this.button.data('SubMenuObj', this); 
	this.panel = $(panel);
	this.timer = null;
	this.height = null;
	this.visible = false;
	this.interval = 500;
			
	//--------------------------------------------------------------- methods
	this.show = function() {
		if (this.height == null) {
			this.panel.show();
			this.height = this.panel.outerHeight();
			this.panel.hide();
		}
		var x = this.button.offset().left;
		var y = this.button.offset().top - this.height;
		this.panel.css({ top: y, left: x });
		this.visible = true;
		this.panel.fadeIn("slow");		
	};
	
	this.hide = function() {
		this.visible = false;
		this.panel.fadeOut("slow");		
	};
	
	this.mouseIn = function() {
		clearTimeout(this.timer);
		this.timer = null;
	};
	
	this.mouseOut = function() {
		if (this.visible) {
			var cmd = 'SubMenu_hide($("#' + this.button.attr('id') + '"));';
			this.timer = setTimeout(cmd, this.interval);
		}
	};

	//-------------------------------------------------------- event handlers
	// alias for this (as "this" is overridden in event handlers)
	var th = this; 	
	this.button.mouseover(function() {
		if (th.visible)
			th.mouseIn();
		else 
			th.show(); 
	});
	this.panel.mouseout(function() { th.mouseOut(); });
	this.panel.mouseover(function() { th.mouseIn(); });
	this.button.mouseout(function() { th.mouseOut(); });
}

// SubMenu_hide calls SubMenu.hide() without context
function SubMenu_hide(elem) {
	var sm = elem.data('SubMenuObj');
	sm.hide();
}

// extend jQuery
jQuery.fn.extend({
	attachMenu: function(panel) {
		sm = new SubMenu(this, panel);
	}
});
