/*
 *         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.
 *
 * =================================================================
 * MODIFICATION : FC 2009-01-25
 *
 * Remplacement des baslises a déclarer 'a' par 'div'
 * this.voices= $("#"+m).find("a").clone(); => this.voices= $("#"+m).find("div").clone();
 *
 * Ajout de l'effet caher sur mouseOut dans les sections principales.
 *
 * Changement du comportement 'openOnRight' si il est mis a false le menu apparait maintenant a gauche.
 *
 * Ajout du delay sur le mouseout du menu.
 *
 * =================================================================
 */

;(function($){

$.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,
        submenuWidth:200,
        openOnRight:false,
        iconPath:"ico/",
        hasImages:true,
        fadeTime:0,
        menuTop:0,
        menuLeft:0,
        submenuTop:0,
        submenuLeft:4,
        opacity:1,
        shadow:false,
        shadowColor:"black",
        openOnClick:true,
        shadowOpacity:.2,
        menuItemClass:"menu",
        menuHideDelay: 1000
    },
    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);

            $("."+this.options.menuItemClass).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('closerTimeout') ){
                        clearTimeout($(this).attr('closerTimeout'));
                    }

                    if ( $(this).attr("isOpen") != true ){
                        $(this).buildMbMenu(thisMenu, this); //$(this).attr("menu")
                        $(this).attr("isOpen","true");
                    } else {
                        $(this).removeMbMenu(thisMenu);
                    }

                    return false;
                });

                var mouseOver=$.browser.msie?"mouseenter":"mouseover";
                var mouseOut=$.browser.msie?"mouseleave":"mouseout";

                if (!openOnClick){
                    /*$(thisMenu.menuvoice).bind(mouseOut,function(){

                        $(this).removeMbMenu(thisMenu);  // todo: delete menu if out
                    });*/

                    $(this).find('td').bind(mouseOver,function(){
                        if(!$(this).attr("isOpen") ){
                        	$(this).removeMbMenu(thisMenu);
                    	}
                        return false;
                    });
                }
                $(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); //$(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,"cm",event); //$(this).attr("cMenu")
                    $(this).attr("isOpen","true");
                })
            })
        })
    }
}

$.fn.extend({
    buildMbMenu: function(op,trigger,type,e){

        if( type == 'cm' ) {
            var m = $(this).attr("cMenu");
        } else {
            var m = $(this).attr("menu");
        }

        // Verify that the menu is build
        if( $('#'+m).attr('isMenuBuilt') ) {
            var opener = this;
            var where = (!type|| type=="cm")?$(document.body):$(this).parent().parent();
            this.menu  = where.find("."+m+"menuDiv");
            //this.menuContainer  = $(this.menu).find(op.options.menuSelector);
            this.menuContainer  = $(this.menu).find('.'+m+op.options.menuSelector);

            // Close menu onClick anywhere else on the page.
            $(document).bind("click",function(){$(document).removeMbMenu(op)});
        } else {
            $('#'+m).attr('isMenuBuilt', "true");
            //alert('just built  : '+$(m));
            var msie6=$.browser.msie && $.browser.version=="6.0";
            var mouseOver=$.browser.msie?"mouseenter":"mouseover";
            var mouseOut=$.browser.msie?"mouseleave":"mouseout";

            if (e) {
                this.mouseX=$(this).getMouseX(e);
                this.mouseY=$(this).getMouseY(e);
            }

            $.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 = m+op.options.menuSelector; //.replace(".","")
            where.append("<div class='"+m+"menuDiv'><div class='"+menuClass+"' style='display:table'></div></div>");
            this.menu  = where.find("."+m+"menuDiv");
            this.menuContainer  = $(this.menu).find('.'+menuClass);//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("div").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 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'></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("."+m+"menuDiv").hide(); //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("."+m+"menuDiv").hide(); //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("."+m+"menuDiv").remove();
                                    opener.menuContainer.actualSubmenu=false;
                                    $(this).buildMbMenu(op,$(voice),"sm",event); //.attr("menu")
                                    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("."+m+"menuDiv").hide(); //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;
                    })
                }
            })

            // close menu after short timeout
            $(this.menuContainer).bind(mouseOut,function(){
                $(trigger).attr('closerTimeout', setTimeout(function() {
                    $(document).removeMbMenu(op);
                }, op.options.menuHideDelay));
                //$(document).bind("click",function(){$(document).removeMbMenu(op)})
            })
            // cancel timeout onmouseout to close menu
            $(this.menuContainer).bind(mouseOver,function(){
                clearTimeout($(trigger).attr('closerTimeout'));
            });

            $(this.menuContainer).css({
                width:op.options.menuWidth
            })
        }

        //positioning opened
        var t=0,l=0
        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;
                    /*if( ($(this).offset().left - $(this.menu).find('div:last').width()) > 0 )
                    {
                    	l=($(this).offset().left - $(this.menu).find('div:last').width())+op.options.menuLeft;
                    }
                    else*/
                    {
                    	l=($(this).offset().left - op.options.menuWidth); // +op.options.menuLeft
                    }
                }
                break;
        }

        $(this.menu).css({
            position:"absolute",
            top:t,
            left:l
        })

        if (!type || type=="cm") op.rootMenu=this.menu;

        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("."+m+"menuDiv:first")).offset().left;
        var actualY=$(where.find("."+m+"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
        })
        $(this.menu).show();
    },
    removeMbMenu: function(op){
        if(!op)op=$.mbMenu.options.actualMenuOpener;
        if (op.rootMenu) {
            $(op.actualOpenedMenu)
                    .removeAttr("isOpen")
                    .removeClass("selected")
            //$(op.rootMenu).remove();
            $(op.rootMenu).hide();
            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;
})(jQuery);

