/*
 *         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.
 */

var mbclosetimer=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.menuvoice).bind("mouseout",function(){
                        // $(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){
                    event.preventDefault();
                    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";

        $(document).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=''></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){
			$(this).bind(mouseOut,function(){
						function mb_timerclose() {
							return function() {
								$(this).removeMbMenu(op);
							}
						}
						mbclosetimer = window.setTimeout(mb_timerclose(), 1000);
                    });
			$(this).bind(mouseOver,function(){
						window.clearTimeout(mbclosetimer);
                    });
		
		
            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 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'><tr>"+imgPlace+"<td class='voice' nowrap></td></tr></table>";
			var line="<div style='width:100%;' class='line' id='"+m+"_"+i+"'><div class='voice' nowrap></div></div>";
            if(isSeparator)
                line="<div class='separator' style='width:100%; display:inline-block'></div>"
            if(isText)
                line="<div style='width:100%;' class='line' id='"+m+"_"+i+"'><div class='voice' nowrap></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){
                    $(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;
                })
            }
        })
		
		$(opener.menuContainer).find('.line:last').addClass('line_last');
		
        //positioning opened
        var t=0,l=0
        /*$(this.menuContainer).css({
            width:op.options.menuWidth
        })*/
		/*$(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 tmp_w = 0;
		$(this.menuContainer).find('a').each( function () {
			if (tmp_w < $(this).width())
				tmp_w = $(this).width();
		});
		tmp_w = tmp_w + 30;
		$(this.menuContainer).css('width', tmp_w + 'px');
		$(this.menuContainer).find('a').each( function () {
			$(this).css('float', 'none');
		});

        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;
