/*
 *         developed by Matteo Bicocchi on JQuery
 *         © 2002-2008 Open Lab srl, Matteo Bicocchi
 *			    www.open-lab.com - info@open-lab.com
 *       	version 1.0
 *       	tested on: 	Explorer and FireFox for PC
 *                  		FireFox and Safari for Mac Os X
 *                  		FireFox for Linux
 *         GPL (GPL-LICENSE.txt) licenses.
 */
document.oncontextmenu = function() { return false };
$.mbMenu = {
	actualMenuOpener:false,
	options: {
		template:"yourMenuVoiceTemplate",// the url that returns the menu voices via ajax. the data passed in the request is the "menu" attribute value as "menuId"
		additionalData:"",
		menuSelector:".menuContainer",
		menuWidth:150,
		openOnRight:false,
		iconPath:"ico/",
		hasImages:true,
		fadeTime:100,
		menuTop:0,
		menuLeft:0,
		submenuTop:0,
		submenuLeft:4,
		opacity:1,
		shadow:false,
		shadowColor:"black",
		openOnClick:true,
		shadowOpacity:.2
	},
	buildMenu : function (options){
		return this.each (function ()
		{
			var thisMenu =this;
			thisMenu.id = !this.id ? "menu_"+Math.floor (Math.random () * 1000): this.id;
			this.options = {};

			$.extend (this.options, $.mbMenu.options);
			$.extend (this.options, options);

			$(".menu").hide();
			thisMenu.clicked = false;
			thisMenu.rootMenu=false;
			thisMenu.clearClicked=false;
			thisMenu.actualOpenedMenu=false;
			thisMenu.menuvoice=false;
			var root=$(this);
			var openOnClick=this.options.openOnClick;

			//build roots
			$(root).each(function(){
				thisMenu.menuvoice=$(this).find("[menu]");
				$(thisMenu.menuvoice).each(function(){
					$(this).addClass("rootVoice");
					$(this).attr("nowrap","nowrap");
				});
				var action= openOnClick?"click":"mouseover";
				$(thisMenu.menuvoice).bind(action,function(){
					if (!$(this).attr("isOpen")){
						$(this).buildMbMenu(thisMenu,$(this).attr("menu"));
					}
					$(this).attr("isOpen","true");
					return false;
				});
				if (!openOnClick){
					$(thisMenu).bind("mouseout",function(){
						//$(thisMenu.rootMenu).remove();
						// $(this).removeMbMenu(thisMenu);  // todo: delete menu if out
					})
				}
				var mouseOver=$.browser.msie?"mouseenter":"mouseover";
				var mouseOut=$.browser.msie?"mouseleave":"mouseout";
				$(thisMenu.menuvoice).bind(mouseOver,function(){
					if (!openOnClick) $(thisMenu).find(".selected").removeClass("selected");
					if(thisMenu.actualOpenedMenu){ $(thisMenu.actualOpenedMenu).removeClass("selected");}
					$(this).addClass("selected");
					if(thisMenu.clicked && !$(this).attr("isOpen")){
						clearTimeout(thisMenu.clearClicked);
						$(this).buildMbMenu(thisMenu,$(this).attr("menu"));
					}
				})
				$(thisMenu.menuvoice).bind(mouseOut,function(){
					if(!thisMenu.clicked)
						$(this).removeClass("selected");
					$(document).bind("click",function(){
						$(this).removeMbMenu(thisMenu);
					})
				})
			})
		})
	},
	buildContextualMenu :  function (options){
		return this.each (function ()
		{
			var thisMenu = this;
			thisMenu.id = !this.id ? "menu_"+Math.floor (Math.random () * 100): this.id;
			this.options = {};
			$.extend (this.options, $.mbMenu.options);
			$.extend (this.options, options);
			thisMenu.clicked = false;
			thisMenu.rootMenu=false;
			thisMenu.clearClicked=false;
			thisMenu.actualOpenedMenu=false;
			thisMenu.menuvoice=false;
			var cMenuEls= $("[cMenu]");
			$(cMenuEls).each(function(){
				$(this).css({cursor:"default"});
				//$(this).bind("contextmenu",function(){event.stopPropagation(); event.cancelBubble=true})
				$(this).bind("contextmenu","mousedown",function(event){
					if (event.which==3){
						event.preventDefault();
						event.stopPropagation();
						event.cancelBubble=true;
						if ($.mbMenu.options.actualMenuOpener) {
							$(thisMenu).removeMbMenu($.mbMenu.options.actualMenuOpener);
						}
						$(this).buildMbMenu(thisMenu,$(this).attr("cMenu"),"cm",event);
						$(this).attr("isOpen","true");						
					}
				})
			})
		})
	}
}

$.fn.extend({
	buildMbMenu: function(op,m,type,e){
		var msie6=$.browser.msie && $.browser.version=="6.0";
		var mouseOver=$.browser.msie?"mouseenter":"mouseover";
		var mouseOut=$.browser.msie?"mouseleave":"mouseout";
		$().bind("click",function(){$(document).removeMbMenu(op)})
		if (e) {
			this.mouseX=$(this).getMouseX(e);
			this.mouseY=$(this).getMouseY(e);
		}
		if ($.mbMenu.options.actualMenuOpener && $.mbMenu.options.actualMenuOpener!=op)
			$(op).removeMbMenu($.mbMenu.options.actualMenuOpener);
		$.mbMenu.options.actualMenuOpener=op;

		if(!type || type=="cm")	{
			if (op.rootMenu) {
				$(op.rootMenu).remove();
				$(op.actualOpenedMenu).removeAttr("isOpen")
			}
			op.clicked=true;
			op.actualOpenedMenu=this;
			$(op.actualOpenedMenu).attr("isOpen","true")
			$(op.actualOpenedMenu).addClass("selected");
		}
		var opener=this;
		var where=(!type|| type=="cm")?$(document.body):$(this).parent().parent();

		var menuClass= op.options.menuSelector.replace(".","")
		where.append("<div class='menuDiv'><div class='"+menuClass+"' style='display:table'></div></div>");
		this.menu  = where.find(".menuDiv");
		this.menuContainer  = $(this.menu).find(op.options.menuSelector);
		$(this.menuContainer).bind(mouseOver,function(){
			$(opener).addClass("selected");
		})
		$(this.menuContainer).css({
			position:"absolute",
			opacity:op.options.opacity
		});
		if (!$("#"+m).html()){
			$.ajax({
				type: "POST",
				url: op.options.template,
				cache: false,
				async: false,
				data:"menuId="+m+(op.options.additionalData!=""?"&"+op.options.additionalData:""),
				success: function(html){
					$("body").after(html);
					$("#"+m).hide();
				}
			});
		}
		$(this.menuContainer).hide();
		this.voices= $("#"+m).find("a").clone();

		if (op.options.shadow) {
			var shadow = $("<div class='menuShadow'></div>").hide();
			if(msie6)
				shadow = $("<iframe class='menuShadow'></iframe>").hide();
		}

		// build each voices of the menu
		$(this.voices).each(function(i){
			var voice=this;
			var imgPlace="";

			var isText=$(voice).attr("rel")=="text";
			var isTitle=$(voice).attr("rel")=="title";
			var isDisabled=$(voice).is("[disabled]");
			var isSeparator=$(voice).attr("rel")=="separator";

			if (op.options.hasImages && !isText){
				var imgPath=$(voice).attr("img")?$(voice).attr("img"):"blank.gif";
				imgPath=(imgPath.length>3 && imgPath.indexOf(".")>-1)?"<img class='imgLine' src='"+op.options.iconPath+imgPath+"'>":imgPath;
				imgPlace="<td class='img'>"+imgPath+"</td>"
			}
			var line="<table id='"+m+"_"+i+"' class='line"+(isTitle?" title":"")+"' cellspacing='0' cellpadding='0' border='0' style='width:100%; display:table' width='100%'><tr>"+imgPlace+"<td class='voice' nowrap></td></tr></table>";
			if(isSeparator)
				line="<div class='separator' style='width:100%; display:inline-block'><img src='"+op.options.iconPath+"blank.gif' width='1' height='1'></div>"
			if(isText)
				line="<div style='width:100%; display:table' class='line' id='"+m+"_"+i+"'><div class='voice'></div></div>";

			$(opener.menuContainer).append(line);

			if(!isSeparator){
				$(opener.menuContainer).find("#"+m+"_"+i).find(".voice").append(this);
				if($(this).attr("menu")){
					$(opener.menuContainer).find("#"+m+"_"+i).find(".voice a").wrap("<div class='menuArrow'></div>");
					$(opener.menuContainer).find("#"+m+"_"+i).find(".menuArrow").addClass("subMenuOpener");
					$(opener.menuContainer).find("#"+m+"_"+i).css({cursor:"default"})
					this.isOpener=true;
				}
				if(isText){
					$(opener.menuContainer).find("#"+m+"_"+i).find(".voice").addClass("textBox");
					this.isOpener=true;
				}
				if(isDisabled){
					$(opener.menuContainer).find("#"+m+"_"+i)
						.addClass("disabled")
						.css({cursor:"default"})
				}

				if(!(isText || isTitle || isDisabled)){
					$(opener.menuContainer)
						.find("#"+m+"_"+i)
						.css({cursor:"pointer"})
						.bind("mouseover",function(event){
						$(this).addClass("selected");
						if(opener.menuContainer.actualSubmenu && !$(voice).attr("menu")){
							$(opener.menu).find(".menuDiv").remove();
							$(opener.menuContainer.actualSubmenu).removeClass("selected");
							opener.menuContainer.actualSubmenu=false;
							return false;
						}
						if ($(voice).attr("menu")){

							if(opener.menuContainer.actualSubmenu && opener.menuContainer.actualSubmenu!=this){
								$(opener.menu).find(".menuDiv").remove();
								$(opener.menuContainer.actualSubmenu).removeClass("selected");
								opener.menuContainer.actualSubmenu=false;
							}
							if (!$(voice).attr("action")) $(opener.menuContainer).find("#"+m+"_"+i).css("cursor","default")
							if (!opener.menuContainer.actualSubmenu || opener.menuContainer.actualSubmenu!=this){
								$(opener.menu).find(".menuDiv").remove();
								opener.menuContainer.actualSubmenu=false;
								$(this).buildMbMenu(op,$(voice).attr("menu"),"sm",event);
								opener.menuContainer.actualSubmenu=this;
							}
							$(this).attr("isOpen","true")
							return false;
						}
					})
					$(opener.menuContainer).find("#"+m+"_"+i).bind(mouseOut,function(){
						$(this).removeClass("selected");
					})
				}
				if(isDisabled || isTitle){
					$(this).removeAttr("href");
					$(opener.menuContainer).find("#"+m+"_"+i).bind(mouseOver,function(){
						$(document).unbind("click");
						if(opener.menuContainer.actualSubmenu){
							$(opener.menu).find(".menuDiv").remove();
							opener.menuContainer.actualSubmenu=false;
						}
					}).css("cursor","default")
				}
				$(opener.menuContainer).find("#"+m+"_"+i).bind("click",function(){
					if (($(voice).attr("action") || $(voice).attr("href")) && !isDisabled){
						eval($(voice).attr("action"));
						$(this).removeMbMenu(op);
						//return false;
					}else if($(voice).attr("menu"))
						return false;
				})
			}
		})
		//positioning opened
		var t=0,l=0
		$(this.menuContainer).css({
			width:op.options.menuWidth
		})
		if ($.browser.msie) $(this.menuContainer).css("width",$(this.menuContainer).width()+2);


		switch(type){
			case "sm":
				t=$(this).position().top+op.options.submenuTop;

				l=$(this).position().left+$(this).width()-op.options.submenuLeft;
				break;
			case "cm":
				t=this.mouseY-5;
				l=this.mouseX-5;
				break;
			default:
				if (op.options.openOnRight){
					t=$(this).offset().top-($.browser.msie?2:0)+op.options.menuTop;
					l=$(this).offset().left+$(this).outerWidth()-op.options.menuLeft-($.browser.msie?2:0);
				}else{
					t=$(this).offset().top+$(this).outerHeight()-(!$.browser.mozilla?2:0)+op.options.menuTop;
					l=$(this).offset().left+op.options.menuLeft;
				}
				break;
		}

		$(this.menu).css({
			position:"absolute",
			top:t,
			left:l
		})

		if (!type || type=="cm") op.rootMenu=this.menu;
		$(this.menuContainer).bind(mouseOut,function(){
			$(document).bind("click",function(){$(document).removeMbMenu(op)})
		})

		if (op.options.fadeTime>0) $(this.menuContainer).fadeIn(op.options.fadeTime);
		else $(this.menuContainer).show();

		if (op.options.shadow) {
			$(this.menu).prepend(shadow)
			shadow.css({
				width:$(this.menuContainer).outerWidth(),
				height:$(this.menuContainer).outerHeight()-1,
				position:'absolute',
				backgroundColor:op.options.shadowColor,
				border:0,
				opacity:op.options.shadowOpacity
			}).show();
		}

		var wh=$(window).height();
		var ww=$(window).width();
		var mh=$(this.menuContainer).outerHeight();
		var mw=shadow?shadow.outerWidth():$(this.menuContainer).outerWidth();

		var actualX=$(where.find(".menuDiv:first")).offset().left;
		var actualY=$(where.find(".menuDiv:first")).offset().top;
		switch(type){
			case "sm":
				if ((actualX+mw)>= ww){
					l-=((op.options.menuWidth*2)-(op.options.submenuLeft*2))
				}
				break;
			case "cm":
				if ((actualX+(op.options.menuWidth*1.5))>= ww){
					l-=((op.options.menuWidth*2)-(op.options.submenuLeft))
				}
				break;
			default:
				if ((actualX+mw)>= ww){
					l-=($(this.menuContainer).offset().left+mw)-ww;
				}
				break;
		}
		if ((actualY+mh)>= wh-10){
			t-=((actualY+mh)-wh)+30;
		}

		$(this.menu).css({
			top:t,
			left:l
		})
	},
	removeMbMenu: function(op){
		if(!op)op=$.mbMenu.options.actualMenuOpener;
		if (op.rootMenu) {
			$(op.actualOpenedMenu)
				.removeAttr("isOpen")
				.removeClass("selected")
			$(op.rootMenu).remove();
			op.rootMenu=false;
			op.clicked=false
			$(document).unbind("click");
		}
	},

	//mouse  Position
	getMouseX : function (e){
		var mouseX;
		if ($.browser.msie)mouseX = event.clientX + document.body.scrollLeft;
		else mouseX = e.pageX;
		if (mouseX < 0) mouseX = 0;
		return mouseX;
	},
	getMouseY : function (e){
		var mouseY;
		if ($.browser.msie)	mouseY = event.clientY + document.body.scrollTop;
		else mouseY = e.pageY;
		if (mouseY < 0)	mouseY = 0;
		return mouseY;
	}
})
$.fn.buildMenu = $.mbMenu.buildMenu;
$.fn.buildContextualMenu = $.mbMenu.buildContextualMenu;