/*****************************************************************/
/*******************MENU DYNAMIQUE MULTINIVEAUX*******************/
/*****************************************************************/

/****************structure HTML : ***************//*

		//fichiers javascript a inclure
	
<script type="text/javascript" src="inc/jquery-1.3.2.js"></script>		//http://docs.jquery.com/Downloading_jQuery
<script type="text/javascript" src="inc/jquery.metadata.js"></script>	//http://plugins.jquery.com/project/metadata
<script type="text/javascript" src="inc/jquery.easing.1.3.js"></script>	//http://gsgd.co.uk/sandbox/jquery/easing/
<script type="text/javascript" src="inc/menu.js"></script>
	
		//appel de la fonction d'ouverture des menus
		
<script type="text/javascript">
	$(function(){
		$("#myMenu").buildMenu(
		{
			menuWidth:200,					//largeur minimale des menus
			menuSelector: ".menuContainer",	//le nom de la class utilisé  pour le conteneur du menu
			minZindex:"auto",				//zindex minimum pour les menus. Mettre "auto" pour qu'il soit defini automatiquement
			opacity:.95,					//opacité des menus
			closeOnMouseOut:false,			//defini si le menu doit ou non etre fermé lorsque la souris quitte celui ci (sinon il sera fermé après un clic de souris hors du menu)
			closeAfter:500,					//temps d'attente en ms avant que le menu se ferme une fois que la souris est en dehors (seulement si closeOnMouseOut=true)
			effectIn:"animate",				//effet jQuery appliqué pour l'ouverture du menu ("animate" ou "fadeIn")
			effectInOption:"xy",			//option de l'effet animate lors de l'ouverture du menu ("xy", "x" ou "y")
			effectInTime:500,				//durée de l'effet appliqué pour l'ouverture du menu
			effectInMaths:"easeOutSine";	//fonction mathematique appliquée a l'effet animate (http://gsgd.co.uk/sandbox/jquery/easing/)
			effectOut:"fadeOut",			//effet jQuery appliqué pour la fermeture du menu ("fadeOut")
			effectOutTime:500,				//durée de l'effet appliqué pour la fermeture du menu
		});
	});
</script>

		//div contenant le menu général toujours visible

<div class="container" id="myMenu">
	<div class="rootVoices">
		<div class="rootVoice {menu: '[nom du sous menu]'}" >[nom menu 1]</div>		//[nom du sous menu] = valeur de l'attribut "id" de la div
		<div class="rootVoice {menu: '[nom du sous menu]'}" >[nom menu 2]</div>		//contenant le menu que l'on souhaire ouvrir en passant
		<div class="rootVoice {menu: '[nom du sous menu]'}" >[nom menu 3]</div>		//la souris sur cette div
	</div>
</div>

		//div pour un menu ouvrant supplementaire

<div id="[nom du sous menu]" class="menu">
	<a href="#" class="{}">[nom du lien]</a>
	<a href="#" class="{}">[nom du lien]</a>
	<a href="#" class="{}">[nom du lien]</a>
</div>

		//type de lien a mettre dans les menus ouvrant :
		
*sans metadonnées
	-un simple separateur :
		<a rel="separator"> </a>
	-un lien simple :
		<a href="#" class="{}">[nom du lien]</a>
*avec metadonnées
	-pour griser le lien : disabled:true|false
		<a href="#" class="{disabled:true}">[nom du lien]</a>
	-pour ouvrir un sous menu en mettant la souris sur ce lien : menu:'[nom du sous menu]'
		<a class="{menu:'[nom du sous menu a ouvrir]'}">[nom du lien]</a>

*//**************structure CSS : ****************//*
//CSS par defaut

*{padding : 0px;margin : 0px;}
body{font-family:sans-serif;font-size:13px;color:black;}
body .style a{color:gray;font-family:sans-serif;font-size:13px;text-decoration:none;}
.rootVoices{background-color : black;}
.rootVoices div.rootVoice {background-color:#999;width:120px;line-height:18px;font-family:Arial,Helvetica,sans-serif;color: gray;font-size:12px;padding:8px;padding-left:10px;cursor: pointer;float : left;}
.rootVoices div.selected{background-color:gray;color:#ffffff;cursor: pointer;font-size:14px;}
.menuContainer{background-color:gray;width : 100%;}
.menuContainer .line{background-color:white;}
.menuContainer td a{text-decoration:none;color: #000000;}
.menuContainer td.voice{border-top:1px solid #f3f3f3;font-family:Arial,Helvetica,sans-serif;font-size:12px;padding:5px;}
.menuContainer .separator{background-color:#f1f1f1;height:3px;}
.menuContainer .selected td{background-color:#f3f3f3;}
.menuContainer .selected td a{color:#000;}
.menuContainer .disabled td, .menuContainer .disabled td a {color: #cccccc;}
.menuContainer .subMenuOpener{background-image:url("../images/menuArrow.gif");background-repeat:no-repeat;background-position:right;}

*/


(function($) {
  $.Menu = {
    actualMenuOpener:false,
    options: {
			/*Valeur par defaut des options*/
			menuSelector:".menuContainer",
			menuWidth:150,
			opacity:1,
			closeOnMouseOut:true,
			closeAfter:500,
			minZindex:"auto",
			effectIn:"fadeIn",
			effectInTime:100,
			effectInOption:"xy",
			effectInMaths:'easeOutSine',
			effectOut:"fadeOut",
			effectOutTime:200
    },
    buildMenu : function (options){
      return this.each (function ()
      {
		//on recupere l'element courant
        var thisMenu =this;
		//on recupere l'id de l'element courant et si celui-ci n'est pas renseigné alors on lui fournit une id aleatoire
        thisMenu.id = !this.id ? "menu_"+Math.floor (Math.random () * 1000): this.id;
		//on initialise les options  de l'element courant
        this.options = {};
		//on rajoute les valeurs par defaut des options dans l'element courant
        $.extend (this.options, $.Menu.options);
		//on remplace les valeurs des options par celle renseignée dans le fichier HTML lorsque celles ci le sont
        $.extend (this.options, options);

		//on cache les sous-menus
        $(".menu").hide();
		//on initialise les parametres de l'element courant
        thisMenu.clicked = false;
        thisMenu.rootMenu=false;
        thisMenu.actualOpenedMenu=false;
        thisMenu.menuvoice=false;
		//on affecte l'element courant a la variable root
        var root=$(this);
		//on recupere la valeur de "closeOnMouseOut"
        var closeOnMouseOut=this.options.closeOnMouseOut;

        //build roots
        $(root).each(function(){
           /*using metadata plugin you can add attribut writing them inside the class attr with a JSON sintax
             for ex: class="rootVoice {menu:'menu_2'}" */
          
          if ($.metadata){
            $.metadata.setType("class");
            thisMenu.menuvoice=$(this).find(".rootVoice");
            $(thisMenu.menuvoice).each(function(){
              if ($(this).metadata().menu)
				$(this).attr("menu",$(this).metadata().menu);
            });
          }

          thisMenu.menuvoice=$(this).find("[menu]");

          $(thisMenu.menuvoice).each(function(){
            $(this).addClass("rootVoice");
            $(this).attr("nowrap","nowrap");
          });
		  
		  //modifie le nom des evenements pour les browser IE
          var mouseOver=$.browser.msie?"mouseenter":"mouseover";
          var mouseOut=$.browser.msie?"mouseleave":"mouseout";
		  //fonction a effectuer lorsque "mouseover"
          $(thisMenu.menuvoice).bind(mouseOver,function(){
            if (closeOnMouseOut) clearTimeout($.Menu.deleteOnMouseOut);
            $(thisMenu).find(".selected").removeClass("selected");
            if(thisMenu.actualOpenedMenu){$(thisMenu.actualOpenedMenu).removeClass("selected");}
            $(this).addClass("selected");
			//si le menu n'est pas encore ouvert
            if(1 && !$(this).attr("isOpen")){
			  //on appelle la fonction pour creer le menu
              $(this).buildMbMenu(thisMenu,$(this).attr("menu"));
              if ($(this).attr("menu")=="empty"){
                $(this).removeMbMenu(thisMenu);
                $(this).removeAttr("isOpen");
              }
            }
          });
		  //fonction a effectuer lorsque "mouseout"
          $(thisMenu.menuvoice).bind(mouseOut,function(){
            if (closeOnMouseOut)
              $.Menu.deleteOnMouseOut= setTimeout(function(){$(this).removeMbMenu(thisMenu,true);},$(root)[0].options.closeAfter);
            if(!thisMenu.clicked)
              $(this).removeClass("selected");
			//on appelle la fonction pour retirer le menu
            $(document).bind("click",function(){
              $(this).removeMbMenu(thisMenu,true);
            });
          });
        });
      });
    }
  };
  $.fn.extend({
    //fonction pour afficher le menu
    buildMbMenu: function(op,m,type,e){
	  //verification de si le navigateur utilisé est IE6
      var msie6=$.browser.msie && $.browser.version=="6.0";
	  //modifie le nom des evenements pour les browser IE
      var mouseOver=$.browser.msie?"mouseenter":"mouseover";
      var mouseOut=$.browser.msie?"mouseleave":"mouseout";
	  //lorsque l'on clic sur une entrée d'un menu on appelle la fonction pour retirer les menus
      $().bind("click",function(){$(document).removeMbMenu(op,true);});
	  //si il y a un evenement
      if (e) {
	    //on recupere les coordonnees de la souris
        this.mouseX=$(this).getMouseX(e);
        this.mouseY=$(this).getMouseY(e);
      }

	  //si le menu reellement ouvert est different du menu que l'ont souhaite afficher
      if ($.Menu.options.actualMenuOpener && $.Menu.options.actualMenuOpener!=op)
	    //on retire le menu reellement ouvert
        $(op).removeMbMenu($.Menu.options.actualMenuOpener);
	  //le menu que l'on souhaite ouvrir devient le menu reellement ouvert
      $.Menu.options.actualMenuOpener=op;
	  //si le menu n'a pas d'attribut "type" ou que celui vaut "cm"
      if(!type || type=="cm"){
        if (op.rootMenu){
          $(op.rootMenu).removeMbMenu(op);
          $(op.actualOpenedMenu).removeAttr("isOpen");
        }
        op.clicked=true;
        op.actualOpenedMenu=this;
        $(op.actualOpenedMenu).attr("isOpen","true");
        $(op.actualOpenedMenu).addClass("selected");
      }
	  //on affecte l'element courant a la variable "opener"
      var opener=this;
	  //on recupere l'elemet parent du menu que l'on souhaite afficher
      var where=(!type|| type=="cm")?$(document.body):$(this).parent().parent();

      // si l'attribut "menu" de l'element courant est vide
      if($(this).attr("menu")=="empty"){
	    //on quitte la fonction d'ouverture du menu
        return;
      }

	  //on affecte a une variable la valeur de l'option "menuselector" de l'element courant en supprimant le caractere "."
      var menuClass= op.options.menuSelector.replace(".","");
	  //on affiche le menu dans l'element parents
      where.append("<div class='menuDiv'><div class='"+menuClass+"' style='display:table'></div></div>");
	  //on affecte l'element a l'interieur du parent du menu actuel defini par la classe div a la variable "this.menu"
      this.menu  = where.find(".menuDiv");
	  //on modifie les propriété css width et height de cet element a 0
      $(this.menu).css({width:0, height:0});
	  //si l'option minZindex vaut autre chose que "auto"
      if (op.options.minZindex!="auto"){
	    //on modifie la propriété css "zindex" en incrementant la valeur de minZindex
        $(this.menu).css({zIndex:op.options.minZindex++});
	  //sinon
      }else{
		//on appelle la fonction qui permet de trouver automatiquement la valeur du zindex
        $(this.menu).mb_BringToFront();
      }
	  //on affecte l'element a l'interieur du menu defini par la classe qui a pour nom la valeur "menuSelector" a la variable "this.menuContainer"
      this.menuContainer  = $(this.menu).find(op.options.menuSelector);
	  
	  //fonction a effectuer lorsque l'element definit par "this.menuContainer" est "mouseover"
      $(this.menuContainer).bind(mouseOver,function(){
		//on ajoute la l'attribut class "selected" au menu courant
        $(opener).addClass("selected");
      });
	  // on modifie les propriété css position et opacity de l'element definit par "this.menuContainer"
      $(this.menuContainer).css({
        position:"absolute",
        opacity:op.options.opacity
      });

	  //on cache l'element definit par "this.menuContainer"
      $(this.menuContainer).hide();
	  //
      this.voices= $("#"+m).find("a").clone();

      /*
       *using metadata plugin you can add attribut writing them inside the class attr with a JSON sintax
       * for ex: class="rootVoice {menu:'menu_2'}"
       */
	   
	  //si il y a des metadonnees
      if ($.metadata){
        $.metadata.setType("class");
        $(this.voices).each(function(){
          if ($(this).metadata().disabled) $(this).attr("disabled",$(this).metadata().disabled);
          if ($(this).metadata().menu) $(this).attr("menu",$(this).metadata().menu);
          if ($(this).metadata().action) $(this).attr("action",$(this).metadata().action);
          if ($(this).metadata().disabled) $(this).attr("disabled",$(this).metadata().disabled);
        });
      }

      // build each voices of the menu
      $(this.voices).each(function(i){

        var voice=this;
        var isDisabled=$(voice).is("[disabled]");
        var isSeparator=$(voice).attr("rel")=="separator";

        var line="<table id='"+m+"_"+i+"' cellspacing='0' cellpadding='0' border='0' style='width:100%; display:table' width='100%'><tr><td class='voice' nowrap></td></tr></table>";
        if(isSeparator)
          line="<div class='separator' style='width:100%; display:inline-block'><img src='../images/blank.gif' width='1' height='1'/></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(isDisabled){
            $(opener.menuContainer).find("#"+m+"_"+i)
                    .addClass("disabled")
                    .css({cursor:"default"});
          }

          if(!(isDisabled)){
            $(opener.menuContainer)
                    .find("#"+m+"_"+i)
                    .css({cursor:"pointer"});
            $(opener.menuContainer).find("#"+m+"_"+i)
                    .bind("mouseover",function(event){
              clearTimeout($.Menu.deleteOnMouseOut);
              $(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){
            $(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){
              var target=$(voice).attr("target")?$(voice).attr("target"):"_self";
              if ($(voice).attr("href") && $(voice).attr("href").indexOf("javascript:")>-1){
                $(voice).attr("action",$(voice).attr("href").replace("javascript:",""));
                $(voice).removeAttr("href");
              }
              var link=$(voice).attr("action")?$(voice).attr("action"):"window.open('"+$(voice).attr("href")+"', '"+target+"')";
              $(voice).removeAttr("href");
              eval(link);
              $(this).removeMbMenu(op,true);
            }else if($(voice).attr("menu"))
              return false;
          });
        }
      });

      // Close on Mouseout

      var closeOnMouseOut=$(op)[0].options.closeOnMouseOut;
      if (closeOnMouseOut){
        $(opener.menuContainer).bind("mouseenter",function(){
          clearTimeout($.Menu.deleteOnMouseOut);
        });
        $(opener.menuContainer).bind("mouseleave",function(){
          var menuToRemove=$.Menu.options.actualMenuOpener;
          $.Menu.deleteOnMouseOut= setTimeout(function(){$(this).removeMbMenu(menuToRemove,true);},$(op)[0].options.closeAfter);
        });
      }


      //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;
          l=$(this).position().left+$(this).width();
          break;
        case "cm":
          t=this.mouseY-5;
          l=this.mouseX-5;
          break;
        default:
          t=$(this).offset().top+$(this).outerHeight()-(!$.browser.mozilla?2:0);
          l=$(this).offset().left;
          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,true);});
      });
	  $(this.menuContainer).hide();
/////////////////////////////////////////////////////////ouverture////////////////////////////////////////////////////
      if (op.options.effectInTime>0){
		if (op.options.effectIn == "animate"){
			$(this.menuContainer.parent()).css("overflow", "hidden");
			$(this.menuContainer).css("display","block");
			$(this.menuContainer).attr("id", "opening");
			var h = document.getElementById("opening").clientHeight;
			var w = op.options.menuWidth;
			$('#opening *').each(function() {
				if (this.offsetWidth > w)
					w = this.offsetWidth;
			});
			$(this.menuContainer).css('width', w+'px');
			$(this.menuContainer).removeAttr("id");
			$(this.menuContainer).parent().css("overflow", "visible");
			if(op.options.effectInOption == "x"){
				$(this.menuContainer).parent().css('height', h+'px');
			}
			if(op.options.effectInOption == "y"){
				$(this.menuContainer).parent().css('width', w+'px');
			}
			if (op.options.effectInTime>0){
				$(this.menuContainer).parent().animate({height: h + 'px', width : w + 'px'}, {queue : false, duration : op.options.effectInTime, easing : op.options.effectInMaths});
			}else $(this.menuContainer).show();
		}else $(this.menuContainer).fadeIn(op.options.effectInTime);
	  }else $(this.menuContainer).show();

      var wh=$(window).height();
      var ww=$(window).width();
      var mh=$(this.menuContainer).outerHeight();

      var actualX=$(where.find(".menuDiv:first")).offset().left-$("body").scrollLeft();
      var actualY=$(where.find(".menuDiv:first")).offset().top-$("body").scrollTop();
      switch(type){
        case "sm":
          if ((actualX)>= ww){
            l-=(op.options.menuWidth*2);
          }
          break;
        case "cm":
          if ((actualX+(op.options.menuWidth*1.5))>= ww){
            l-=(op.options.menuWidth*2);
          }
          break;
        default:
          if ((actualX)>= 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
      });
    },
	//fonction pour retirer le menu
    removeMbMenu: function(op,effect){
      if(!op)op=$.Menu.options.actualMenuOpener;
      if (op.rootMenu) {
        $(op.actualOpenedMenu)
                .removeAttr("isOpen")
                .removeClass("selected");
        $(op.rootMenu).css({width:1, height:1});
/////////////////////////////////////////////////////////fermeture////////////////////////////////////////////////////

			if (effect) $(op.rootMenu).fadeOut(op.options.effectOutTime,function(){$(this).remove();});
			else $(op.rootMenu).remove();
        op.rootMenu=false;
        op.clicked=false;
        $(document).unbind("click");
      }
    },

    //recupere la position en X de la souris
    getMouseX : function (e){
	  //definition de la variable dans laquelle sera stockée la position en X de la souris
      var mouseX;
	  //recuperation de la valeur de la position en X de la souris pour IE
      if ($.browser.msie) mouseX = e.clientX + document.body.scrollLeft;
	  //recuperation de la valeur de la position en X de la souris pour les autres navigateurs
      else mouseX = e.pageX;
	  //si la valeur est negative alors on lui affecte 0
      if (mouseX < 0) mouseX = 0;
	  //retourne la valeur de la position en X de la souris
      return mouseX;
    },
	//recupere la position en Y de la souris
    getMouseY : function (e){
	  //definition de la variable dans laquelle sera stockée la position en Y de la souris
      var mouseY;
	  //recuperation de la valeur de la position en Y de la souris pour IE
      if ($.browser.msie) mouseY = e.clientY + document.body.scrollTop;
	  //recuperation de la valeur de la position en Y de la souris pour les autres navigateurs
      else mouseY = e.pageY;
	  //si la valeur est negative alors on lui affecte 0
      if (mouseY < 0)	mouseY = 0;
	  //retourne la valeur de la position en Y de la souris
      return mouseY;
    },
    //recupere le z-index maximum actuellement utilisé sur la page
    mb_BringToFront: function(){
	  //initialisation de la variable de la valeur du z-index a 10
      var zi=10;
	  //pour tout les element de la page
      $('*').each(function() {
		//si l'element est positioné en absolut
        if($(this).css("position")=="absolute"){
		  //on recupere la valeur courante du z-index
          var cur = parseInt($(this).css('zIndex'));
		  //la variable de la valeur du z-index recupere la valeur du z-index de l'element si celle-ci est superieure
          zi = cur > zi ? parseInt($(this).css('zIndex')) : zi;
        }
      });
	  //on ajoute la propriété css z-index a l'element courant
      $(this).css('zIndex',zi+=10);
    }

  });
  $.fn.buildMenu = $.Menu.buildMenu;
})(jQuery);