/*-----------------------------------------------------------
* Function to create copies of objects which are
* normally passed around by references (Arrays for example)
-------------------------------------------------------------*/
function arrayCopy(input)
{
	var output = new Array(input.length);

	for (i in input) 
	  if (typeof(input[i]) == 'array') 
			output[i] = arrayCopy(input[i]);
		else
			 output[i] = input[i];

	return output;
}

/*======================================================================
* JSMenu class
========================================================================*/
	function JSMenu(iconpath, myname, usePersistence, noTopLevelImages, vertical)
	{
		// Properties
		this.iconpath         = iconpath;		// for the decoration of the menu hierarchy
		this.myname           = myname;
		this.usePersistence   = usePersistence;
		this.noTopLevelImages = noTopLevelImages;
		this.isVertical       = vertical;
		this.n                = new Array(); //children
		this.output           = '';

		this.nodeRefs         = new Array();
		this.branchesID       = new Array();	// table of all the branches ID
		this.isBranchExpanded = new Array();
		this.children         = new Array();
		this.parent           = new Array();
		this.cookieStatuses   = new Array();
		this.timeout          = new Array();


		this.preloadImages();
	}

/*-------------------------
* Adds a node to the tree
--------------------------*/
	JSMenu.prototype.addItem = function (newNode)
	{
		newIndex = this.n.length;
		this.n[newIndex] = newNode;
		
		return this.n[newIndex];
	}

/*---------------------------------
* Preload images hack for Mozilla
-----------------------------------*/
	JSMenu.prototype.preloadImages = function ()
	{
		var plustop    = new Image; plustop.src    = this.iconpath + '/plustop.gif';
		var plusbottom = new Image; plusbottom.src = this.iconpath + '/plusbottom.gif';
		var plus       = new Image; plus.src       = this.iconpath + '/plus.gif';
	
		var minustop    = new Image; minustop.src    = this.iconpath + '/minustop.gif';
		var minusbottom = new Image; minusbottom.src = this.iconpath + '/minusbottom.gif';
		var minus       = new Image; minus.src       = this.iconpath + '/minus.gif';
	
		var branchtop    = new Image; branchtop.src    = this.iconpath + '/branchtop.gif';
		var branchbottom = new Image; branchbottom.src = this.iconpath + '/branchbottom.gif';
		var branch       = new Image; branch.src       = this.iconpath + '/branch.gif';
	
		var linebottom = new Image; linebottom.src = this.iconpath + '/linebottom.gif';
		var line       = new Image; line.src       = this.iconpath + '/line.gif';
	}

/*-------------------------------------------------
* Main function that draws the menu 
* recursive function
----------------------------------------------------*/
	JSMenu.prototype.drawMenu = function ()// OPTIONAL ARGS: nodes = [], level = [], prepend = '', expanded = false, visbility = 'block', parentNodeID = null
	{
		/**
	    * Necessary variables
	    ----------------------*/
		var output        = '';
		var tagmodifier   = '';
		var nodeID       = '';
		var parentNodeID = '';
	
		/**
	    * Parse any optional arguments
	    ------------------------------*/
		var nodes         = arguments[0] ? arguments[0] : this.n
		var level         = arguments[1] ? arguments[1] : [];
		var prepend       = arguments[2] ? arguments[2] : '';
		var expanded      = arguments[3] ? arguments[3] : false;
		var visibility    = arguments[4] ? arguments[4] : true;
		var parentNodeID  = arguments[5] ? arguments[5] : null;

		var currentlevel  = level.length;


	  /* parcourir l'ensembles noeuds a ce niveau
	  --------------------------------------------*/
		for (var i=0; i<nodes.length; i++) 
		  {
			level[currentlevel] = i+1;
			nodeID = this.myname + '_' + 'node_' + this.implode('_', level);

			/**
      * Store this object in the nodeRefs array
      ------------------------------------------*/
			this.nodeRefs[nodeID] = nodes[i];

			/**
	    * Store the child/parent relationship
	    -------------------------------------*/
			this.parent[nodeID] = parentNodeID;
	
			
			/*
	    * Tag Gifimage modifier (append to the name of the icon)
	      to draw arborescent file-system-like decoration
	      only in vertical menus
	    ---------------------------------------------------------*/
      if(this.isVertical == true)
			  {
				if (i == 0 && parentNodeID == null) 
				  tagmodifier = nodes.length > 1 ? "top" : 'single';
			  else if(i == (nodes.length-1)) 
				  tagmodifier = "bottom";
		    else
				  tagmodifier = "";
	      }
	    
			/**
	     * check whether this node is expanded or not
	     --------------------------------------------*/
	     if(this.isVertical ==false)
	       expanded = false; 
	     else
	     	 {  
			   if (!this.doesMenu() || (parentNodeID == null && (nodes.length == 1 || this.noTopLevelImages))) 
				   expanded = true;
			   else if (nodes[i].expanded) 
				   expanded = true;
		     else
				   expanded = false;
				 }  
	
			/**
	     * Make sure visibility is correct based on parent status
	     ----------------------------------------------------------*/
			visibility =  this.checkParentVisibility(nodeID) ? visibility : false;
      /* visibility is dealt with differently between horizontal and vertical menus
    	    For vertical menus : display is either "block" or "none" to show or not the nodes
	    For Horinzontal Menus : the submenus uses Visibility "visible" or "hidden"
	    -------------------------------------------------------------------------------------*/
	    var vis_display;
	    var vis_visibility;
      if(visibility == true)
        {
        if(this.isVertical == true)
          vis_display = 'block';
        else
      	  vis_visibility = 'visible';
        }
      else
        {
        if(this.isVertical == true)
          vis_display = 'none';
        else
      	  vis_visibility = 'hidden';
        }   	  	  

			/**
	    * Setup branch status and build an indexed array
			* of branch node ids
	    --------------------------------------------------*/
			if (nodes[i].n.length > 0) 
			  {
				this.isBranchExpanded[nodeID] = expanded;
				this.branchesID[this.branchesID.length] = nodeID;
			  }
	
			/**
	     * Setup toggle relationship
	     * if the father has not yet alink to this node, then create it
	     --------------------------------------------------------------*/
			if (!this.children[parentNodeID]) 
				this.children[parentNodeID] = new Array();
			this.children[parentNodeID][this.children[parentNodeID].length] = nodeID;
	
			/**
	     *tag arborescence
	     ---------------------*/
	    var gifname  = nodes[i].n.length && this.doesMenu() && nodes[i].isDynamic ? (expanded ? 'minus' : 'plus') : 'branch';


      /**
      * icon to the menu item 
      * it can be normal or expanded
      ----------------------------------------------------*/
      var iconName = '';
      var iconimg = '';      
			iconName = expanded && nodes[i].expandedIcon ? nodes[i].expandedIcon : nodes[i].icon;
			iconimg  = nodes[i].icon ? this.stringFormat('<img src="{0}"  align="top" id="icon_{1}">', iconName, nodeID) : '';


      /* Define mouse action on the menu item
      -----------------------------------------*/      
	    var onMouseAction = '';
      if(this.doesMenu() && nodes[i].n.length  && nodes[i].isDynamic && (this.isVertical == true))
        {
			   // Vertical menus
			   // on a click on the menu item is used to force expansion
			    onMouseAction = this.stringFormat('onclick="{0}.forceExpansion(\'{1}\')" ', this.myname, nodeID);
        }
      else
      	{ // Horintal menus
      		// actions vary whether it is a terminal level or not
      		if (this.doesMenu() && nodes[i].n.length  && nodes[i].isDynamic && (this.isVertical == false))
      	   {
      	   onMouseAction =  this.stringFormat('onmouseover="{0}.forceExpansion(\'{1}\')" ', this.myname, nodeID ) +		
     	                    this.stringFormat('onmouseout="{0}.trigTimerToCollapse(\'{1}\')" ', this.myname, nodeID );
           }
          else
           { // si c'est un noeud terminal	
          if (this.doesMenu() && (nodes[i].n.length == 0) && nodes[i].isDynamic && (this.isVertical == false))   
             onMouseAction = //this.stringFormat('onmouseover="{0}.killTimerToCollapse(\'{1}\')" ', this.myname,parentNodeID)  +
                             this.stringFormat('onfocus="{0}.killTimerToCollapse(\'{1}\')" ', this.myname,parentNodeID)  +
                            // this.stringFormat('onmouseout="{0}.trigTimerToCollapse(\'{1}\')" ',  this.myname,parentNodeID) +
                             this.stringFormat('onblur="{0}.trigTimerToCollapse(\'{1}\')" ',  this.myname,parentNodeID);		
            }
          if(nodes[i].cookie_name != 'null')
          {  
          onMouseAction += this.stringFormat(' onclick="{0}.saveACookie(\'{1}\',\'{2}\')" ', this.myname, nodes[i].cookie_name,nodes[i].cookie_value);  
      	  
      	  }
      	}   
	 	
     

	    
	    /* Definition of the containers to hold the menu items
	    -------------------------------------------------------*/
	    var Div ='';
	    var EndDiv='';
	    var imgTag = '';  
	    if(this.isVertical == true)
	        { 
	        // Menu Vertical : we use DIV boxes with a display block (to show) and display none (to hide)	
          if(this.doesMenu())
            {
            stylediv = this.stringFormat('style="display:{0};"',vis_display);	
		        Div  = this.stringFormat('<div id="{0}" {1} class="{2}" >', nodeID, stylediv,(nodes[i].cssClass ? nodes[i].cssClass : this.defaultClass)) ;
		        }
		      else
		        Div = this.stringFormat('<div class="{0}">', nodes[i].cssClass ? nodes[i].cssClass : this.defaultClass);
		      EndDiv = '</div>';  
          /*defintion of the "tag" items */
      		var onMDown   = this.doesMenu() && nodes[i].n.length  && nodes[i].isDynamic ? this.stringFormat('onmousedown="{0}.toggleBranchExpansion(\'{1}\', true)" ', this.myname, nodeID) : '';
			    imgTag    = this.stringFormat('<img src="{0}/{1}{2}.gif"  align="top" border="0" name="img_{3}" {4}>', this.iconpath, gifname, tagmodifier, nodeID, onMDown);
          }
        else
        	{
        	// Menu Horizontal : we distinguish the first level which is always displayed
        	//                   and the subsequent ones which are hidden using visibility attribute	

          if(this.doesMenu())
            {
      	    if(parentNodeID == null) // top level - arrangement sur une ligne on encadre toute la colonne par un div
	      	     {
	      	     // first the UL grouping the item at that level (top level)	
	      	     if(i==0)  
                 {                 
			           this.output += this.stringFormat('\n<UL class="{0}">',(nodes[i].cssClass ? nodes[i].cssClass : this.defaultClass));
			           }
			         // then the item themselves (li)	   	
	      	     //stylediv = this.stringFormat('style="display:inline; list-style:none; padding-left:0px; position:relative"'); 
	      	     Div  = this.stringFormat('\n<LI  {0}  class="{1}" >', onMouseAction,(nodes[i].cssClass ? nodes[i].cssClass : this.defaultClass)) ;
	      	     EndDiv = '\n';  
	      	     }
	      	  else										// subsequent levels
	      		  {
			         if(i==0)
			         	 {
			         	 this.output += this.stringFormat('\n<UL id="{0}" class={2} style="visibility:{1};">',parentNodeID,vis_visibility,(nodes[i].cssClass ? nodes[i].cssClass : this.defaultClass));	
			         	 }
	      		  	
	      		 // stylediv = this.stringFormat('style="display:block; float:none; list-style:none;"');
	      		  Div  = this.stringFormat('\n<LI  {0} class="{1}" >', onMouseAction,(nodes[i].cssClass ? nodes[i].cssClass : this.defaultClass)) ;
	      		  if(nodes[i].n.length) // si il y a des sous elements
	      		     EndDiv = '\n';
	      		  else
	      		  	 EndDiv = '</LI>\n'; //si c'est une branch terminale    
	      		  }    
		        }
		      else // does not do Menu in Horizontal Menu
		      	{
		        Div = this.stringFormat('<div {0} class="{1}">', onMouseAction,nodes[i].cssClass ? nodes[i].cssClass : this.defaultClass);
        	  EndDiv='</div>';
        	  }
          }  


      /* Definition of the action itself */
      /*---------------------------------*/
			var linkTarget= nodes[i].linkTarget ? nodes[i].linkTarget : "_self";
			if(linkTarget == "_self")
        var linkStart = nodes[i].page ? this.stringFormat('<a href="index.php?page={0}" target="_self">', nodes[i].page) : '<a href="index.php" target="_self">';	
			else
				var linkStart = nodes[i].page ? this.stringFormat('<a href="{0}" target="{1}">', nodes[i].page, linkTarget) : '';
		  var linkEnd   = nodes[i].page ? '</a>' : '';

      
      /* Generation de la chaine du neoud du menu */
      /*-------------------------------------------*/ 

			this.output += this.stringFormat('{0}<nobr>{1}{2}  {3}<span {4}> {5} {6}</span>{7}</nobr>',
			                  Div,                  /* 0 */
							          prepend,              /* 1 */
			                  parentNodeID == null && (this.noTopLevelImages) ? '' : imgTag,							          
							          linkStart,            /* 3 */
							          this.isVertical ? onMouseAction : '',        /* 4 */
							          iconimg,              /* 5 */
							          nodes[i].title,       /* 6 */
							          linkEnd);             /* 7 */
			if(this.isVertical == true)
			   this.output += '<br>';				          
			this.output += EndDiv;				          
			
          
			/**
	     * Si ce node a des fils, il faut egalement les dessiner
	     ---------------------------------------------------------*/
			if (nodes[i].n.length) 
			{
				/*
	      * Determine how many vertical bars | before the next object
	        and recursive call to the next level
	      --------------------------------------------------------------*/
	      if(this.isVertical == true) /* no tag if horizontal menu */
	        {
				  if (parentNodeID == null && (nodes.length == 1 || this.noTopLevelImages)) 
				    {
					  var newPrepend = '';    /* only one node or no symbols to be drawn */
            }
          else if (i < (nodes.length - 1)) 
            { /* add a vertical line */
					  var newPrepend = prepend + this.stringFormat('<img src="{0}/line.gif" align="top">', this.iconpath);
            }
          else 
            { /* add an empty vertical line a upper level was the last of its kind */
					  var newPrepend = prepend + this.stringFormat('<img src="{0}/linebottom.gif" align="top">', this.iconpath);
				    }
          }
          
				this.drawMenu(nodes[i].n,
				              arrayCopy(level),
				              newPrepend,
				              nodes[i].expanded,
				              expanded ? true : false,
				              nodeID);

        if((this.isVertical == false) && this.doesMenu())
			    {
	      	this.output += '\n\n</LI>';	
			    }
			    
			    
      }  	  
			// for horintal lower level menu items
			// close the top level box
			if((this.isVertical == false) && this.doesMenu())
			   {      	     	
	      if(i == nodes.length-1)  
            {                 
			      this.output += '\n</UL>';
			      }
		     }
		     
		     
       }
					   
	}

/*-----------------------------------------------------
* Writes the output generated by drawMenu() to the page
-------------------------------------------------------*/
	JSMenu.prototype.writeOutput = function ()
	{
		//alert(this.output);
		document.write(this.output);
	}

/*--------------------------------------------------
* Initiate a timer before the sub menu disappears
---------------------------------------------------*/
	JSMenu.prototype.trigTimerToCollapse = function (nodeID)
	{      	  

		this.timeout[nodeID] = setTimeout(this.stringFormat('{0}.forceCollapse(\'{1}\')', this.myname, nodeID),650);  /* 650 milliseconds */
	}

/*-------------------------------------------------
* Kill the timer
--------------------------------------------------*/
  JSMenu.prototype.killTimerToCollapse = function (nodeID)
   {	
 	
	 if (this.timeout[nodeID])
	  {
		clearTimeout(this.timeout[nodeID]);
	  }
   }
/*--------------------------------------------------------------
* Force the expansion of a branch
* If alraeady the case => do nothing
* If not call toggleBranchExpansion
----------------------------------------------------------------*/
	JSMenu.prototype.forceExpansion = function (nodeID)
	{
		this.killTimerToCollapse(nodeID);
		
		if(this.isBranchExpanded[nodeID] == false)
		  {
      this.toggleBranchExpansion(nodeID,true);
      this.isBranchExpanded[nodeID] = true;
      }
       
	}

/*--------------------------------------------------------------
* Force the expansion of a branch
* If alraeady the case => do nothing
* If not call toggleBranchExpansion
----------------------------------------------------------------*/
	JSMenu.prototype.forceCollapse = function (nodeID)
	{

//  for (var i=0; i<this.n.length; i++) 
//		  {
//			traversenodeID = this.myname + '_' + 'node_' + (i+1);

   	  if(this.isBranchExpanded[nodeID] == true)
   	     {
         this.toggleBranchExpansion(nodeID,true);
         this.isBranchExpanded[nodeID] = false;
        }  
 //     }
	}
		
/*--------------------------------------------------------------
* Toggles a branches visible status. Called from resetBranches()
* and also when a +/- graphic is clicked.
----------------------------------------------------------------*/
	JSMenu.prototype.toggleBranchExpansion = function (nodeID, updateStatus)
	{
		
  if(this.isVertical == true)
	  {
		var currentDisplay = this.getLayer(nodeID).style.display;
		var newDisplay     = (this.isBranchExpanded[nodeID] && currentDisplay == 'block') ? 'none' : 'block';


    /* pour toutes les dependances
    //  si elle est expanded, alors la changer */
		for (var i=0; i<this.children[nodeID].length; i++) 
		  {
			if (this.isBranchExpanded[this.children[nodeID][i]]) 
			    {
				  this.toggleBranchExpansion(this.children[nodeID][i], false);
			    }
			this.getLayer(this.children[nodeID][i]).style.display = newDisplay;
		  }	
		if (updateStatus) 
		    {
			  this.isBranchExpanded[nodeID] = !this.isBranchExpanded[nodeID];
			  if (this.doesPersistence() && this.usePersistence) 
			    {
				  this.setExpandedStatusForCookie(nodeID, this.isBranchExpanded[nodeID]);
			    }			    
		 	  this.swapTag(nodeID);
		    }
		this.swapIcon(nodeID);
	  }
	else  
		{
			
		// horizontal menu
		//------------------	
		var currentVisibility = this.getLayer(nodeID).style.visibility;
		var newVisibility     = (this.isBranchExpanded[nodeID] && currentVisibility == 'visible') ? 'hidden' : 'visible';

    // There is no need to traverse all children,
    // the manegemnt of visbility is performed through the UL block visibility 
    // (i.e. all submenu items)
    // 
    this.getLayer(nodeID).style.visibility = newVisibility;
	
		if (updateStatus) 
		    {
			  this.isBranchExpanded[nodeID] = !this.isBranchExpanded[nodeID];
		    }
		this.swapIcon(nodeID);	
	  }	  
	}

/*-----------------------------------
* Swaps the plus/minus branch images
-------------------------------------*/
	JSMenu.prototype.swapTag = function (nodeID)
	{
		var imgSrc = document.images['img_' + nodeID].src;
	
		var re = /^(.*)(plus|minus)(bottom|top|single)?.gif$/
		if (matches = imgSrc.match(re)) {
	
			document.images['img_' + nodeID].src = this.stringFormat('{0}{1}{2}{3}',
			                                                matches[1],
															matches[2] == 'plus' ? 'minus' : 'plus',
															matches[3] ? matches[3] : '',
															'.gif');
		}
	}

/*--------------------------------------------
* Swaps the icon for the expanded icon if one
* has been supplied.
----------------------------------------------*/
	JSMenu.prototype.swapIcon = function (nodeID)
	{
		if (document.images['icon_' + nodeID]) 
		  {
			var imgSrc = document.images['icon_' + nodeID].src;
	
			if (this.nodeRefs[nodeID].icon && this.nodeRefs[nodeID].expandedIcon) 
			  {
				var newSrc = (imgSrc.indexOf(this.nodeRefs[nodeID].expandedIcon) == -1 ? this.nodeRefs[nodeID].expandedIcon : this.nodeRefs[nodeID].icon);
				document.images['icon_' + nodeID].src =  newSrc;
			  }
		  }
	}

/*----------------------------------------
* Can the browser handle the dynamic menu?
------------------------------------------*/
	JSMenu.prototype.doesMenu = function ()
	{
		return (is_ie4up || is_nav6up || is_gecko || is_opera7);
	}

/*---------------------------------------------
* Can the browser handle save the branch status
-----------------------------------------------*/
	JSMenu.prototype.doesPersistence = function ()
	{
		return (is_ie4up || is_gecko || is_nav6up || is_opera7);
	}

/*--------------------------------------
* Returns the appropriate layer accessor
---------------------------------------*/
	JSMenu.prototype.getLayer = function (nodeID)
	{
	if (is_ie4) 
		  {
			return document.all(nodeID);
			}
	 else if (document.getElementById(nodeID)) 
	 	  {
			return document.getElementById(nodeID);
	    }
	 else if (document.all && document.all(nodeID)) 
	 	  {
			return document.all(nodeID);
		  }
	}

/*------------------------------
* Save the status of the node
-------------------------------*/
	JSMenu.prototype.setExpandedStatusForCookie = function (nodeID, expanded)
	{
		this.cookieStatuses[nodeID] = expanded;
		this.saveCookie();
	}

/*---------------------------------
* Load the status of the node
----------------------------------*/
	JSMenu.prototype.getExpandedStatusFromCookie = function (nodeID)
	{
		if (this.cookieStatuses[nodeID])
			return this.cookieStatuses[nodeID];

		return false;
	}

/*-------------------------------------------------------------
* Saves the cookie that holds which branches are expanded.
* Only saves the details of the branches which are expanded.
--------------------------------------------------------------*/
	JSMenu.prototype.saveCookie = function ()
	{
		var cookieString = new Array();

		for (var i in this.cookieStatuses) 
			if (this.cookieStatuses[i] == true) 
				cookieString[cookieString.length] = i;

		document.cookie = 'isBranchExpanded=' + cookieString.join(':');
	}

/*------------------------------------------
* Reads cookie parses it for status info and
* stores that info in the class member.
-------------------------------------------*/
	JSMenu.prototype.loadCookie = function ()
	{
		var cookie = document.cookie.split('; ');

		for (var i=0; i < cookie.length; i++) 
		{
			var crumb = cookie[i].split('=');
			if ('isBranchExpanded' == crumb[0] && crumb[1]) 
			{
				var expandedBranches = crumb[1].split(':');
				for (var j=0; j<expandedBranches.length; j++) 
				    {
					  this.cookieStatuses[expandedBranches[j]] = true;
				    }
			}
		}
	}

/*--------------------
* Reset branch status
---------------------*/
	JSMenu.prototype.resetBranches = function ()
	{
		if (!this.doesPersistence()) 
		    {
			  return false;
		    }
		
		this.loadCookie();

		for (var i=0; i<this.branchesID.length; i++) 
		{
			var status = this.getExpandedStatusFromCookie(this.branchesID[i]);
			
			/* Only update if it's supposed to be expanded and it's not already */
			if (status == true && this.isBranchExpanded[this.branchesID[i]] != true) 
			{
				if (this.checkParentVisibility(this.branchesID[i])) 
				    {
					  this.toggleBranchExpansion(this.branchesID[i], true, false);
				    }
				else 
				    {
					  this.isBranchExpanded[this.branchesID[i]] = true;
					  this.swapTag(this.branchesID[i]);
				    }
			}
		}
	}

/*----------------------------------------
* Checks whether a branch should be open
* or not based on its parents' status
-----------------------------------------*/
	JSMenu.prototype.checkParentVisibility = function (nodeID)
	{
		if (this.in_array(this.parent[nodeID], this.branchesID)
		    && this.isBranchExpanded[this.parent[nodeID]]
			&& this.checkParentVisibility(this.parent[nodeID]) ) 
			  {
			  return true;
	      }
	    else if (this.parent[nodeID] == null)
	      {
			  return true;
		    }
		
		return false;
	}

/*-------------------------------------
* New C# style string formatter
---------------------------------------*/
	JSMenu.prototype.stringFormat = function (strInput)
	{
		var idx = 0;
	
		for (var i=1; i<arguments.length; i++)
		  {
			while ((idx = strInput.indexOf('{' + (i - 1) + '}', idx)) != -1)
			  {
				strInput = strInput.substring(0, idx) + arguments[i] + strInput.substr(idx + 3);
			  }
		  }
		
		return strInput;
	}

/*----------------------------------------------
* the PHP implode() function
-----------------------------------------------*/
	JSMenu.prototype.implode = function (seperator, input)
	{
		var output = '';
	
		for (var i=0; i<input.length; i++) 
		  {
			if (i == 0) 
				output += input[i];
			else
				output += seperator + input[i];
		  }
		return output;
	}

/*----------------------------------------
* return true if the item is in the array
------------------------------------------*/
	JSMenu.prototype.in_array = function (item, arr)
	{
		for (var i=0; i<arr.length; i++) 
			if (arr[i] == item) 
				return true;

		return false;
	}

/*-------------------------------------------------------------
* Saves a cookie
--------------------------------------------------------------*/
	JSMenu.prototype.saveACookie = function (nom,lang)
	{
	var date_exp = new Date ();
  date_exp.setTime (date_exp.getTime() + (30 * 24 * 60 * 60 * 1000)); // 30 jours de validite 

  document.cookie = nom + '=' + escape(lang) +  ";expires=" + date_exp.toGMTString() ;
  // + ";domain=www.donzyhoahai.org"
          
	}

/*------------------------------------------
* Reads a cookie
-------------------------------------------*/
	JSMenu.prototype.loadACookie = function (nom)
	{
   var mon_cookie = document.cookie;
   var debut = mon_cookie.indexOf(nom+"=");
   var taille = debut + nom.length + 1;
   if ((!debut) && (nom != mon_cookie.substring(0,nom.length))) 
       return null;
   if (debut == -1)
       return null;
  var fin = mon_cookie.indexOf(";",taille);
  if (fin == -1)
       fin = mon_cookie.length;
  return unescape(mon_cookie.substring(taille, fin));
	}

/*===============================================================================
* Node Class
=================================================================================*/
	function Node(title, icon, page, cookie_name, cookie_value, expanded, isDynamic, cssClass, linkTarget, expandedIcon)
	{
		this.title        = title;
		this.icon         = icon;
		this.expandedIcon = expandedIcon;
		this.page         = page;
		this.cookie_name  = cookie_name;
		this.cookie_value = cookie_value;
		this.expanded     = expanded;
		this.isDynamic    = isDynamic;
		this.cssClass     = cssClass;
		this.linkTarget   = linkTarget;
		this.n            = new Array();
		this.events       = new Array();
		this.handlers     = null;
		this.oncollapse   = null;
		this.onexpand     = null;
		this.ontoggle     = null;
		
	}

/*-----------------------------------------
* Adds a node to an already existing node
-------------------------------------------*/
	Node.prototype.addItem = function (newNode)
	{
		newIndex = this.n.length;
		this.n[newIndex] = newNode;
		
		return this.n[newIndex];
	}


	

//<!--
// Ultimate client-side JavaScript client sniff. Version 3.03
// (C) Netscape Communications 1999-2001.  Permission granted to reuse and distribute.
// Revised 17 May 99 to add is_nav5up and is_ie5up (see below).
// Revised 20 Dec 00 to add is_gecko and change is_nav5up to is_nav6up
//                      also added support for IE5.5 Opera4&5 HotJava3 AOLTV
// Revised 22 Feb 01 to correct Javascript Detection for IE 5.x, Opera 4,
//                      correct Opera 5 detection
//                      add support for winME and win2k
//                      synch with browser-type-oo.js
// Revised 26 Mar 01 to correct Opera detection
// Revised 02 Oct 01 to add IE6 detection

// Everything you always wanted to know about your JavaScript client
// but were afraid to ask. Creates "is_" variables indicating:
// (1) browser vendor:
//     is_nav, is_ie, is_opera, is_hotjava, is_webtv, is_TVNavigator, is_AOLTV
// (2) browser version number:
//     is_major (integer indicating major version number: 2, 3, 4 ...)
//     is_minor (float   indicating full  version number: 2.02, 3.01, 4.04 ...)
// (3) browser vendor AND major version number
//     is_nav2, is_nav3, is_nav4, is_nav4up, is_nav6, is_nav6up, is_gecko, is_ie3,
//     is_ie4, is_ie4up, is_ie5, is_ie5up, is_ie5_5, is_ie5_5up, is_ie6, is_ie6up, is_hotjava3, is_hotjava3up,
//     is_opera2, is_opera3, is_opera4, is_opera5, is_opera5up
// (4) JavaScript version number:
//     is_js (float indicating full JavaScript version number: 1, 1.1, 1.2 ...)
// (5) OS platform and version:
//     is_win, is_win16, is_win32, is_win31, is_win95, is_winnt, is_win98, is_winme, is_win2k
//     is_os2
//     is_mac, is_mac68k, is_macppc
//     is_unix
//     is_sun, is_sun4, is_sun5, is_suni86
//     is_irix, is_irix5, is_irix6
//     is_hpux, is_hpux9, is_hpux10
//     is_aix, is_aix1, is_aix2, is_aix3, is_aix4
//     is_linux, is_sco, is_unixware, is_mpras, is_reliant
//     is_dec, is_sinix, is_freebsd, is_bsd
//     is_vms
//
// See http://www.it97.de/JavaScript/JS_tutorial/bstat/navobj.html and
// http://www.it97.de/JavaScript/JS_tutorial/bstat/Browseraol.html
// for detailed lists of userAgent strings.
//
// Note: you don't want your Nav4 or IE4 code to "turn off" or
// stop working when new versions of browsers are released, so
// in conditional code forks, use is_ie5up ("IE 5.0 or greater")
// is_opera5up ("Opera 5.0 or greater") instead of is_ie5 or is_opera5
// to check version in code which you want to work on future
// versions.


    // convert all characters to lowercase to simplify testing
    var agt=navigator.userAgent.toLowerCase();

    // *** BROWSER VERSION ***
    // Note: On IE5, these return 4, so use is_ie5up to detect IE5.
    var is_major = parseInt(navigator.appVersion);
    var is_minor = parseFloat(navigator.appVersion);

    // Note: Opera and WebTV spoof Navigator.  We do strict client detection.
    // If you want to allow spoofing, take out the tests for opera and webtv.
    var is_nav  = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1)
                && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1)
                && (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1));
    var is_nav6up = (is_nav && (is_major >= 5));
    var is_gecko = (agt.indexOf('gecko') != -1);


    var is_ie     = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
    var is_ie4    = (is_ie && (is_major == 4) && (agt.indexOf("msie 4")!=-1) );
    var is_ie4up  = (is_ie && (is_major >= 4));
	
	var is_opera  = (agt.indexOf("opera") != -1);
	var is_opera7 = (is_opera && is_major >= 7) || agt.indexOf("opera 7") != -1;

	// Patch from Harald Fielker
    if (agt.indexOf('konqueror') != -1) {
        var is_nav    = false;
        var is_nav6up = false;
        var is_gecko  = false;
        var is_ie     = true;
        var is_ie4    = true;
        var is_ie4up  = true;
    }
//--> end hide JavaScript
