//MenuViewCtrl (c) 2003-2009 Zucchetti Spa
//vers. 6.8
//by Maurizio Sanguinetti, Cristian Sicuteri, Daniele Baldi, Christian Faillace

// TODO
// Modalita Horizontal2: sul primo livello del menu sono ammesse solo voci con figli (submenu)

// Main control
if (typeof(ZtVWeb.MenuViewCtrl)=='undefined'){
ZtVWeb.MenuViewCtrl=function(form,id,name,x,y,w,h,font,font_size,font_weight,font_color,font_color_smenu,bg_color,overcolor,textovercolor,menu_type,tag_node,max_level,link_secondary,target_default,close_level,css,className,root_value,separator,separator_vert,sx_btn_image,dx_btn_image,sx_btnover_image,dx_btnover_image,arrow_image,bg_color_smenu,over_color_smenu,textover_color_smenu,btn_imageWidth,z_index,btn_image,btnover_image,anchor,emitter_name){
	//Proprieta del control MenuView
	this.form = form;
	this.id = id;
	this.name = name;
	this.font=LRTrim(font);
	this.bg_color=LRTrim(bg_color);
	this.max_level=max_level;
	this.link_secondary=LRTrim(link_secondary);
	this.target_default=LRTrim(target_default);
	this.close_level=LRTrim(close_level);
	this.css=LRTrim(css);
	this.className=LRTrim(className);
	this.font_color_smenu=LRTrim(font_color_smenu);
	this.textover_color_smenu = LRTrim(textover_color_smenu);
	this.bg_color_smenu = LRTrim(bg_color_smenu);
	this.over_color_smenu = LRTrim(over_color_smenu);
	this.arrow_image = LRTrim(arrow_image);
	this.btn_image = LRTrim(btn_image);
	this.btnover_image = LRTrim(btnover_image);
	this.sx_btn_image = LRTrim(sx_btn_image);
	this.sx_btnover_image = LRTrim(sx_btnover_image);
	this.dx_btn_image = LRTrim(dx_btn_image);
	this.dx_btnover_image = LRTrim(dx_btnover_image);
	this.separator = LRTrim(separator);
	this.separator_vert = LRTrim(separator_vert);
	this.root_value=root_value;
	this.btn_imageWidth=btn_imageWidth;
	this.z_index=0+z_index;
	this.tag_node=tag_node;
	this.menu_type=menu_type; // Flat, horizontal, horizontal2,vertical,slide
	this.next_to_action='';
	// x compatibilita con versioni precedenti
	if (menu_type=="true" || menu_type=="false") {
		this.menu_type=(eval(menu_type) ? "horizontal": "vertical");
	}
	this.overcolor=LRTrim(overcolor);
	this.textovercolor=LRTrim(textovercolor);
	this.fontweight=LRTrim(font_weight);
	this.fontsize=font_size;
	this.font_color=LRTrim(font_color);
	this.emitter_name=emitter_name;

	this.selectedId="";
	this.querynode=null;
	this.querynodesList=new Array(); //Lista dei nodi sui quali eseguire la query. Serve per avere una coda dei nodi
	this.datasource=null;
	this.paramconsumers=new Array();
	this.dataconsumers=new Array();

	this.level_old = 0; //Variabile che serve per discriminare quando passo dal livello principale ai sottolivelli.
	this.level_compare=0; //Variabile che contiene il livello di comparazione con level_old. Puo essere ridefinito sui figli.
	this.over = false; // Attiva e disattiva l'aperture al mouseover dei sottomenu.

	this.currentHeight=null; //Altezza corrente del controllo. Serve per ridimensionare in maniera opportuna form.
	this.minheight=h;

	this.enableOver=true; // Variabile che mi indica se abilitare l'over sulla barra orizzontale; per default è abilitato.

	// Le variabili definite sotto vengono utilizzate dal menu orizzontale e da quello a due livelli per ridimensionare e aprire correttamente i sottomenu
	// ---
	//Variabili per controllare l'apertura dei sottomenu: indica che ho iniziato ad apire a sinistra
	this.openLeft=0;
	//Array che contiene tutti i nodi modificati con la creazione del nodo fittizio
	this.modifiedNodes;
	//Variabile che contiene il nodo del padre corrente
	this.nodeCurrentFather;
	//Variabile che contiene il nodo del padre corrente del submenu aperto
	this.nodeSubMenuCurrentFatherId;
	//Indice del nodo fittizio
	this.indexNodeAdd=-1; //Inizializzato ad un valore non valido
	//Dimensioni finestra iniziali
	this.windowInitialSize;

	//Variabile che mi permette di disegnare i figli del nodo anche se il nodo corrente non è il querynode (utilizzata dalla tipologia flat)
	this.bypassView=0;
	this.submenuActivity=null; // Timer per gestire la cancellazione del menu
	// ----

	this.Value=function(v){
		if(typeof(v)!="undefined"){
			this.Tree.currentnode.nodeid=Trim(v);
		}
		if(this.querynodesList.length!=0){
			this.querynode=this.querynodesList.shift();
			return this.querynode.nodeid;
		}
		else if(typeof(this.Tree.currentnode)!='undefined'){
			return this.Tree.currentnode.nodeid;
		}
		return"";
	}

	// Albero contenente tutti i nodi del menu
	this.tree=function(ctrl){
		this.ctrl=ctrl;
		this.allnodes=new Array();
		this.root=new tree_node(this,ctrl.root_value,-1,"");
		this.currentnode=this.root;
		this.getRoot=function(){
			return this.root;
		}

		// Rendering tree view menu
		this.render=function(){
			var domObj=document.getElementById(this.ctrl.id);
			domObj.style.zIndex=this.ctrl.z_index;
			this.ctrl.form.Ctrl.style.zIndex=this.ctrl.z_index;
			this.root.opened=true;

			this.ctrl.viewRoot(this.root);
			this.ctrl.adjustFormHeight();
		}


	}

	function tree_node(tree,nodeid,level,descr,childnum,nodeseq,link,target,icon,expr,exprNot,parent,nodeFather,cssClass){
		this.tree=tree;
		tree.allnodes.push(this);
		this.index=tree.allnodes.length-1;	// index node
		this.nodeseq=nodeseq;		//sequenza nodo
		this.nodeid=nodeid;			// id node
		this.parent=parent;			// node parent
		this.descr=descr;			//caption
		this.childnum=childnum;		//numero figli
		this.link=link;				// link
		this.target=target;			// target
		this.icon=icon;				// icona
		this.cssClass=cssClass			// classe CSS
		this.expr=expr;
		this.exprNot=exprNot;
		this.children=new Array();		// node children
		this.level=level				//livello
		this.executequery= false;
		this.opened=false;
		
		//Carico la risorsa tramite ajax
		this.bAjaxContainer = false;

		this.nodeFather=nodeFather;	//Nodo padre utilizzato per ricostruire il percorso

		this.setExecuteQuery=function(value){
			//Setto se devo eseguire la query a partire dal nodo corrente
			this.executequery=value;
		}

		this.setOpened=function(value){
			//Setto se il nodo e stato aperto o meno
			this.opened=value;
		}

		// Add new node child
		this.addChild=function(nodeid,level,descr,childnum,nodeseq,link,target,icon,expr,exprNot,parent,nodeFather,cssClass,next_to_action){
			var newnode=new tree_node(this.tree,nodeid,level,descr,childnum,nodeseq,link,target,icon,expr,exprNot,parent,nodeFather,cssClass);
			if(Empty(next_to_action))
				this.children.push(newnode);
			else for(var i=0;i<this.children.length;i++) {
				if(this.children[i].link && (this.children[i].link.indexOf('SendData("'+next_to_action+'")') != -1 || this.children[l].link.indexOf("SendData('"+next_to_action+"')") != -1)){
					this.children.splice(i,0,newnode);
					break;
				}
			}
			return newnode;
		}

		this.rightSelectNode=function(evt,index){

			var mbtn = (window.Event) ? evt.which : evt.button;
			if(mbtn > 1) {
				// Devo valorizzare l'href
				this.tree.ctrl.makeLink(index);
			}
		}

		this.selectNode=function(evt){
			try{
				//Metto tra try catch perche potrei chiamare questo metodo senza passargli l'evento.
				if(evt.stopPropagation)
					evt.stopPropagation();
				else
					evt.cancelBubble = true;
			}
			catch(e){}
			this.tree.currentnode=this;
			//Evidenzio selezione se tale funzione e definita nei figli
			this.tree.ctrl.highlightSelection(this.level);
			if(this.childnum=='0' || ((this.level+1 )>= this.tree.ctrl.max_level && this.tree.ctrl.max_level > 0)){
				this.tree.ctrl.over=false;
				this.tree.ctrl.onMenuClick();
			} else {
				this.tree.ctrl.over=true;
				if (this.executequery){
					this.opened=true;
					this.fillNode()
				} else {
					this.opened=!this.opened;
					this.tree.ctrl.view(this);
				}
			}
		}

		this.checkCondition=function(){
			// Controlla la visibilita condizionata delle voci di menu
			// return true se devo far vedere la voce di menu
			var visualizer=true;
			if (this.expr.length>0 || this.exprNot.length>0) {
				try{
					visualizer = eval(this.tree.ctrl.form.formid+"."+this.tree.ctrl.name+"_Validate('"+this.expr+"','"+this.exprNot+"')");
				}catch(e){}
			}
			return visualizer;
		}

		this.prepareCallBackSelectNode=function(){
			return this.tree.ctrl.form.formid+"."+this.tree.ctrl.name+".Tree.allnodes["+this.index+"].selectNode(event)";
		}

		this.prepareCallBackRightSelectNode=function(){
			return this.tree.ctrl.form.formid+"."+this.tree.ctrl.name+".Tree.allnodes["+this.index+"].rightSelectNode(event,"+this.index+")";
		}

		this.prepareCallBackOverNode=function(enableView){

			return this.tree.ctrl.form.formid+"."+this.tree.ctrl.name+".Tree.allnodes["+this.index+"].overNode("+enableView+")";

		}

		this.prepareCallBackSelectOut=function(){
			return this.tree.ctrl.form.formid+"."+this.tree.ctrl.name+".select_out(event)";
		}

		this.overNode=function(enableView){
			this.tree.currentnode=this;
			this.tree.ctrl.highlightCurrentNode();
			if(this.tree.ctrl.over&&enableView) {
				if (this.executequery){
					this.fillNode();
				} else {
					this.tree.ctrl.view(this);
				}
			}
		}

		this.fillNode=function(){
			this.tree.ctrl.querynodesList.push(this);
			//this.tree.ctrl.querynode=this;
			this.executequery=false;
			this.tree.ctrl.markLoading({level:this.level,index:this.index});
			//Differenzio la chiamata della query qunado chiamo un xmldata provider
			if(this.tree.ctrl.datasource.isxmldata)
				setTimeout(this.tree.ctrl.form.formid+'.'+this.tree.ctrl.name+'.datasource.Query("'+this.nodeid+'")',1);
			else
				setTimeout(this.tree.ctrl.form.formid+'.'+this.tree.ctrl.name+'.datasource.QueryTimeStamp("'+this.nodeid+'")',1);
		}
	}//-- Qui finisce la classe nodo

	this.viewRoot=function(root){
		//Metodo astratto ridefinito nei figli
	}

	this.view=function(nodeView){
		//Metodo astratto ridefinito nei figli
	}

	this.highlightSelection=function(level){
		//Metodo astratto ridefinito nei figli
	}

	//Metodo che ritorna l'indice di aggancio alla barra orizzontale.
	//Tale metodo puo essere ridefinito nei figli se tale indice cambia.
	this.getIndexBarCoupling=function(){
		return this.Tree.root.level+1;
	}
	this.getCtrlElementSubMenu=function(level){
		return document.getElementById(this.id+"_"+level+"_sub");
	}

	//Visualizza barra orizzontale. Questa funzione è utilizzata solo dal menu orizzontale e da quello a due livelli.
	this.viewHorizontalBar=function(objAnchor,nodeView,enableOver){
		this.enableOver=enableOver;

		var tablefloat;
		//Se è stato selezionato un ancoraggio a destra la tablella deve essere flottata a destra, a sinistra in tutti gli altri casi
		switch(this.anchor)
		{
			default:
			tablefloat='left';
			break;
			case 'top-right':
			tablefloat='right';
			break;
			case 'bottom-right':
			tablefloat='right';
			break;
		}

    var html="<table style='float:"+tablefloat+";' border='0' cellspacing='0' cellpadding='0' marginheight='0' marginwidth='0' topmargin='0' leftmargin='0'><tr><td>"+"<table border='0' marginheight='0' marginwidth='0' topmargin='0' leftmargin='0' class='menuview_border' cellpadding='0' cellspacing='0'><tr id="+this.id+"_rowcontent>";
		//Costruisco l'id per agganciarci il livello successivo
		var idlevel=this.id+"_"+LRTrim(Str(nodeView.level+1))+"_sub";
		html+="</tr></table></td></tr><tr><td id='"+idlevel+"'></td></tr></table>";

		//Aggancio all'HTML la struttura della tabella.
		objAnchor.innerHTML=html;

		//Setto la dimensione massima della barra orizzontale. E' pari alla dimensione dell'oggetto di riferimento.
		var maxWidthBar=objAnchor.offsetWidth;
		if(maxWidthBar==0){
			//Prendo la dimensione impostata sul componente
			maxWidthBar=parseInt(objAnchor.style.width)
		}

		//Resetto i nodi modificati
		this.modifiedNodes=new Array();
		//Resetto l'indice del nodo fittizio
		this.indexNodeAdd=-1;
		//Disegno la riga della tabella
		this.drawRow(nodeView,maxWidthBar);
		//Resetto le dimensioni iniziali della finestra
		this.windowInitialSize=document.body.offsetWidth;
	}

	//Funzione che crea il markup HTML per il nodo. Questa funzione è utilizzata solo dal menu orizzontale e da quello a due livelli.
	this.createNodeMarkup=function(objRow,node,flagSeparator){
		//Img sinistra
		var td="";
		td=document.createElement('td');
		td.setAttribute("height",h);
		td.setAttribute("id",this.id+"_"+node.index+"_sx");
		td.setAttribute("align","bottom");
		td.className="menuview_img_sx";
		objRow.appendChild(td);
		//End img sx

		// Icona voce menu
		if (!Empty(this.field_Icons)){
			td=document.createElement('td');
			td.setAttribute("height",h);
			td.setAttribute("id",this.id+"_"+node.index+"_icons");
			td.className="menuview_icon";
			objRow.appendChild(td);
			if (!Empty(node.icon)){
				var img=document.createElement('img');
				img.setAttribute("src","../"+node.icon);
				td.appendChild(img);
			}
		}
		//End Icona voce di menu

		//Cella contenente la voce di menu
		td=document.createElement('td');
		td.setAttribute("style","height:"+h);
		td.setAttribute("id",this.id+"_"+node.index);
		td.className="menuview_font "+node.cssClass;
		if (td.addEventListener){
			td.addEventListener("click", new Function("event",node.prepareCallBackSelectNode()), false);
			td.addEventListener("mousedown", new Function("event",node.prepareCallBackRightSelectNode()),false);
		}
		else if (td.attachEvent){
			td.attachEvent("onclick", new Function("event",node.prepareCallBackSelectNode()));
			td.attachEvent("onmousedown", new Function("event",node.prepareCallBackRightSelectNode()));
		}
		if(this.enableOver){
			if (td.addEventListener){
		   		td.addEventListener("mouseover", new Function(node.prepareCallBackOverNode(true)), false);
		    	td.addEventListener("mouseout", new Function("event",node.prepareCallBackSelectOut()), false);
			}
			else if (td.attachEvent){
				td.attachEvent("onmouseover", new Function(node.prepareCallBackOverNode(true)));
				td.attachEvent("onmouseout", new Function("event",node.prepareCallBackSelectOut()));
			}
		}

		objRow.appendChild(td);
		//End cella contenente la voce di menu

		//Creo il div per gestire la scomparsa del sottomenu
		div=document.createElement('div');
		if (div.addEventListener){
			div.addEventListener("mouseover", new Function(this.prepareCallBackOverDiv()), false);
		   	div.addEventListener("mouseout", new Function("event",this.prepareCallBackOutDiv()), false);
		}
		else if (div.attachEvent){
			div.attachEvent("onmouseover", new Function(this.prepareCallBackOverDiv()));
			div.attachEvent("onmouseout", new Function("event",this.prepareCallBackOutDiv()));
		}
		td.appendChild(div);

		//Tabella contenente l'immagine di background
		var table=document.createElement('table');
		table.setAttribute("id",this.id+"_"+node.index+"_back")
		table.setAttribute("cellspacing",0);
		table.setAttribute("cellpadding",0);
		table.setAttribute("margin",0);
		table.setAttribute("height",h);
		table.className="menuview_img";
		// Appendo la tabella al div
		div.appendChild(table);
		//End tabella contenente immagine

		var tbody=document.createElement("tbody");
		table.appendChild(tbody);

		//Creo riga voce menu
		var tr=document.createElement("tr");
		tbody.appendChild(tr)
		//End creazione riga

		// Voce menu
		td=document.createElement('td');
		td.setAttribute("id",this.id+"_"+node.index+"_descr");
		td.style.whiteSpace="nowrap";

		td.className="menuview_font";
		td.setAttribute("valign","middle");

		tr.appendChild(td);
		//End voce di menu

		//Link
		var link=node.link;
		var anchor;
		if(!Empty(link) &&(link.indexOf('function')< 0 && link.indexOf('javascript')) < 0){
			if (link.indexOf('http://') !=0 && link.indexOf('https://') !=0 ){
				link='../servlet/'+link;
			}
			// HREF per uso da tasto destro
			anchor=document.createElement("a");
			anchor.style.textDecoration="none";
			anchor.setAttribute("href",link);
			anchor.setAttribute("id",this.id+"_"+node.index+"_link");
			anchor.setAttribute("target",node.target);
			anchor.onclick=function(){return false;}
			td.appendChild(anchor);
		}
		//End Link

		//Text
		if(anchor)
			anchor.appendChild(document.createTextNode(node.descr));
		else
			td.appendChild(document.createTextNode(node.descr));
		//End Text


		//Img destra
		td=document.createElement('td');
		td.setAttribute("height",h);
		td.setAttribute("id",this.id+"_"+node.index+"_dx");
		td.setAttribute("align","bottom");
		td.className="menuview_img_dx";
		objRow.appendChild(td);
		//End Img destra

		// Separatore
		if(flagSeparator){
			td=document.createElement('td');
			td.setAttribute("id",this.id+"_"+node.index+"_separator");
			td.setAttribute("height",h);
			objRow.appendChild(td);
			if (this.separator!="") {
				var img=document.createElement('img');
				img.setAttribute("src",this.separator);
				td.appendChild(img);
			}
			else {
				td.className="menuview_sep";
			}
		}
	}

	// Sono col mouse fuori dal div contenente una delle voci del menu di livello 1 quindi faccio scomparire tutto il menu
	this.prepareCallBackOutDiv=function(){
		return this.form.formid+"."+this.name+".submenuOff(\""+this.id+"\")";
	}

	// Sono col mouse dentro al div contenente una delle voci del menu di livello 1, il menu rimane a schermo
	this.prepareCallBackOverDiv=function(enableView){
		return this.form.formid+"."+this.name+".submenuOn()";
	}

	//Funzione che elimina il markup per il nodo. Questa funzione è utilizzata solo dal menu orizzontale e da quello a due livelli.
	this.deleteNodeMarkup=function(objRow,node,flagSeparator){
		var objToDelete;

		//Elimino cella immagine sx
		objToDelete=document.getElementById(this.id+"_"+node.index+"_sx");
		objRow.removeChild(objToDelete);

		//Elimino icona voce di menu
		if (!Empty(this.field_Icons)){
			objToDelete=document.getElementById(this.id+"_"+node.index+"_icons");
			objRow.removeChild(objToDelete);
		}

		//Elimino voce di menu
		objToDelete=document.getElementById(this.id+"_"+node.index);
		objRow.removeChild(objToDelete);

		//Elimino cella immagine dx
		objToDelete=document.getElementById(this.id+"_"+node.index+"_dx");
		objRow.removeChild(objToDelete);

		//Elimino separatore
		if(flagSeparator){
			objToDelete=document.getElementById(this.id+"_"+node.index+"_separator");
			objRow.removeChild(objToDelete);
		}
	}

	//Funzione che disegna la riga della barra orizzontale.
	this.drawRow=function(nodeFather,refWidth){
		var objRow=document.getElementById(this.id+"_rowcontent"); //Riga alla quale devo agganciare il markup creato.
		var newNode; //Variabile contenente il nodo fittizio
		var createdNodeAdd=0; //Variabile che discrimina se il nodo fittizio è stato creato
		var widthCompare=0;
		//Setto il padre corrente
		this.nodeCurrentFather=nodeFather;
		// Loop sui figli del nodo
		for(var i=0;i<nodeFather.children.length;i++){
			var node=nodeFather.children[i];
			if(createdNodeAdd==0){
				if (node.checkCondition() && node.descr.indexOf('-----')!=0 ){
					//controllo ultima posizione per separatore
					var separator=false;
					if(i<nodeFather.children.length-1 && node.parent==nodeFather.children[i+1].parent){
						separator=true;
					}

					//Costruisco il markup per il nodo
					this.createNodeMarkup(objRow,node,separator);
				}

				//Setto la larghezza di comparazione. Questo settaggio mi serve quando vado a inserire il nodo di raggruppamento
				//perchè potrebbe succedere che la dimensione di comparazione torni minore della dimensione di riferimento.
				//15 px è la dimensione del nodo fittizio
				widthCompare=(objRow.offsetWidth>=widthCompare?objRow.offsetWidth:widthCompare);
				if(widthCompare+15>refWidth && i!=0){
					//Creo nodo fittizio per raggruppare le voci aggiuntive. L'ID assegnatogli è xyzwghtysd
					newNode=nodeFather.addChild("xyzwghtysd",nodeFather.level+1);
					newNode.expr="";
					newNode.exprNot="";
					newNode.descr=">>";
					newNode.link="";
					newNode.parent=nodeFather.id;
					newNode.nodeFather=nodeFather;
					this.indexNodeAdd=newNode.index;

					this.deleteNodeMarkup(objRow,node,false);
					//var widthCellAdd=refWidth-objRow.offsetWidth;
					this.createNodeMarkup(objRow,newNode,false);

					//Metto immagine per nodo fittizio, ne setto dimensioni e allineo a destra.
					var objDescrNewNode=document.getElementById(this.id+"_"+newNode.index);
          objDescrNewNode.style.width="15px";//(widthCellAdd)+"px"
					objDescrNewNode.style.textAlign="right";

					//Setto la variabile che indica che è stato creato il nodo fittizio
					createdNodeAdd=1;

					//Costruisco l'array delle voci aggiuntive
					if(typeof(newNode)!="undefined"){
						newNode.children.push(node);
						//Inserisco il nodo corrente nei nodi modificati
						this.modifiedNodes.push({node:node,level:node.level,father:node.nodeFather});
						//cambio livello e padre del nodo corrente e dei suoi figli
						node.level=node.level+1;
						node.nodeFather=newNode;
						this.changeChildLevel(node);
					}
				}
			}
			else {
				//Dopo aver creato il nodo fittizio inserisco gli ulteriori nodi come suoi figli
				if(node.nodeid!="xyzwghtysd"){
					this.modifiedNodes.push({node:node,level:node.level,father:node.nodeFather});
					newNode.children.push(node);
					//cambio livello e padre del nodo corrente e dei suoi figli
					node.level=node.level+1;
					node.nodeFather=newNode;
					this.changeChildLevel(node);
				}
			}

		}
		//Setto il numero di figli del nuovo nodo
		if(typeof(newNode)!="undefined"){
			newNode.childnum=(newNode.children.length)+'';
		}
	}

	// Cambio il livello dei figli già caricati
	this.changeChildLevel=function(node){
		for(var i=0;i<node.children.length;i++){
			node.children[i].level=node.level+1;
			this.changeChildLevel(node.children[i]);
		}
	}

	//Funzione che elimina i riferimenti al nodo fittizio e ripulisce il padre corrente
	this.cleanNode=function(){
		//Ripristino i vecchi nodi
		if(this.modifiedNodes){
			for(var i=0;i<this.modifiedNodes.length;i++){
				var node=this.modifiedNodes[i].node;
				node.level=this.modifiedNodes[i].level;
				node.nodeFather=this.modifiedNodes[i].father;
				this.changeChildLevel(node);
			}
		}
		//Elimino i riferimenti al nodo aggiuntivo
		if(this.indexNodeAdd!=-1){
			delete this.Tree.allnodes[this.indexNodeAdd];
			this.nodeCurrentFather.children.splice(this.nodeCurrentFather.children.length-1,1);
		}
	}

	//Funzione chiamata quando ridimensiono la finestra
	this.resize=function(ctrl){
		var objRow=document.getElementById(this.id+"_rowcontent");
		// Nel caso il menu è nascosto
		if (objRow != null){
			// Trovo la coordinata "x" della riga
			var x=findX(objRow);
			if(x+objRow.offsetWidth>document.body.offsetWidth || (this.windowInitialSize<document.body.offsetWidth&&this.indexNodeAdd!=-1)){
				//Ripulisco
				this.cleanNode();
				//Ridisegno a partire dalla root_value
				this.viewHorizontalBar(ctrl,this.nodeCurrentFather,this.enableOver);

			}
		}
	}

	//Riposiziono il sottomenu. Questa funzione viene chiamata se non rieso a disegnare il sottomenu a destra.
	this.adjustPositionSubmenu=function(nodeView){
		var objSubmenu=document.getElementById(this.id+"_"+nodeView.index+"_submenu_table");
		var widthSub=objSubmenu.offsetWidth;
		//Trovo la coordinata "x" del sottomenu
		var x=findX(objSubmenu);

		var widthBody=document.body.offsetWidth;
		if(nodeView.level==this.getIndexBarCoupling()){
			this.openLeft=0;
		}
		if((widthSub+x>widthBody)||(this.openLeft==1)){
			var newPaddingLeft=0;
			if(nodeView.level==this.getIndexBarCoupling()){
				//Il primo livello lo allineo a destra riducendo il padding
				var objSelection=document.getElementById(this.selectedId);
				var objLeftPadding=document.getElementById(this.id+"_"+nodeView.index+"_submenu_leftpadding");
				newPaddingLeft=objLeftPadding.offsetWidth-(widthSub-objSelection.offsetWidth);
				objLeftPadding.firstChild.style.width=newPaddingLeft+"px";
			}
			if(nodeView.level!=this.getIndexBarCoupling() ){
				var objAnchorSubmenu=this.getCtrlElementSubMenu(nodeView.level);
				//Shifto indietro due volte il sottomenu
				objAnchorSubmenu.style.left=- (objAnchorSubmenu.parentNode.parentNode.previousSibling.offsetWidth + widthSub + 2)+"px";
			}
			this.openLeft=1;
		}
	}


	// Il mouse è fuori dal menu, non c'è attivitò dell'utente
	this.submenuOff=function(id){
		clearTimeout(this.submenuActivity);
		this.submenuActivity = setTimeout(this.resetMenu, 2000);
	}

	// Il mouse è all'interno di uno dei div del menu, c'è attività  dell'utente
	this.submenuOn=function(){
		clearTimeout(this.submenuActivity);
	}

	// Visualizza un sottomenu
	this.viewSubmenu=function(nodeView,spaceLeft){
    	var html="";

		// Sotto voci menu da disegnare su questo menu (inline)
		if (nodeView.children.length>0 ){

			var Selection=document.getElementById(this.selectedId);
			var top=Selection.offsetTop;
			var left=Selection.offsetLeft;
			if(left>0&&spaceLeft)
        html+="<table border='0' cellspacing='0' cellpadding='0'><tr><td id='"+this.id+"_"+nodeView.index+"_submenu_leftpadding'><div style='width:"+left+"px;z-index:"+this.z_index+"'></div></td><td id='"+this.id+"_"+nodeView.index+"_submenu'>";
			if(top>0) {
				//Aggiungo questo div per disegnare i sottomenu nella posizione corretta
        html+="<div style='font-size:0;margin:0px;border:0px;padding:0px;height:"+top+"px;z-index:"+this.z_index+"'></div>";
			}
      html+="<table border='0' cellspacing='0' cellpadding='0'><tr><td valign='top'>";

			//div per il controllo del timer
			html+="<div onmouseover='"+this.form.formid+"."+this.name+".submenuOn()' onmouseout='"+this.form.formid+"."+this.name+".submenuOff(\""+this.id+"\")'>"

      html+="<table id='"+this.id+"_"+nodeView.index+"_submenu_table' border='0' class='menuview_sub_border' cellpadding='3' cellspacing='0'>";
			//Loop
			for(var i=0;i<nodeView.children.length;i++){
				var node=nodeView.children[i];
				if (node.checkCondition()){

					//Controllo che la voce precedente non sia gia un separatore
					if(node.descr.indexOf("-----")==0){
						if (i<nodeView.children.length-1){
							html+="<tr id='"+this.id+"_"+node.index+"' class='menuview_sub_font "+node.cssClass+"' ";
              html+="><td colspan='3'><div class='menuview_sub_sep'>&nbsp;</div></td>";
						}
					}else{
						html+="<tr id='"+this.id+"_"+node.index+"' class='menuview_sub_font "+node.cssClass+"' onmousedown='"+node.prepareCallBackRightSelectNode()+"' onclick='"+node.prepareCallBackSelectNode()+"'";
						html+=" onmouseover='"+node.prepareCallBackOverNode(true)+"'>";
						// Icona voce menu
						if (!Empty(node.icon))
							html+="<td class='menuview_sub_icon' id='"+this.tree.id+"_"+node.index+"_icons' ><img src='../"+node.icon+"'></td>";
						else
							html+="<td class='menuview_sub_icon' id='"+this.id+"_"+node.index+"_icons'></td>";
						// Caption
						var item=node.descr;
						//Link
						var link=node.link;
						if(!Empty(link) &&link.indexOf('function')<0 && link.indexOf('javascript')){
							if (link.indexOf('http://') !=0 && link.indexOf('https://') !=0 ){
								link='../servlet/'+link;
							}
							// HREF per uso da tasto destro
							item="<a style='text-decoration:none' href='"+link+"' target='"+node.target+"' onclick='return false'>"+node.descr+"</a>";
						}
						html+="<td id='"+this.id+"_"+node.index+"_descr'>"+item+"</td>"
						//Arrow image
						if(parseInt(node.childnum)>0){
							if (!Empty(this.arrow_image))
								html+="<td><img id='"+this.id+"_"+node.index+"_img' src='"+this.arrow_image+"'></img></td>";
							else
								html+="<td><div id='"+this.id+"_"+node.index+"_img' class='menuview_sub_arrow'>&nbsp;</div></td>";
						}else{
							html+="<td></td>";
						}
						html+="</tr>";

					}
				}
			}
			//Costruisco l'id per agganciarci il livello successivo
			var idlevel=this.id+"_"+LRTrim(Str(nodeView.level+1))+"_sub";
      html+="</table></div></td><td valign='top'><div style='position:relative'><div id='"+idlevel+"' style='position:absolute;top:0px;left:0px'></div></div></td></tr></table>";
			if(spaceLeft&&left>0) html+="</tr></table>";
		}

		return html;
	}

	//Costruisco il loading
	this.markLoading=function(args){
		var level=args["level"];
		if(typeof(level)!="undefined"){
			var Selection;
			var top=0,left=0;
			var ctrl=document.getElementById(this.id+"_"+level+"_sub");
			Selection=document.getElementById(this.selectedId);
			top=Selection.offsetTop;
			left=Selection.offsetLeft;
      ctrl.innerHTML='<div id="__LOADING__" style="padding-top:'+top+'px;padding-left:'+left+'px;font-family:sans-serif;font-size:8pt;">Loading...</div>';
			ctrl.style.display='block';
		}
	}

	//Funzione che calcola il percorso
	this.getPath=function(node){
		var current=node;
		var pathNode=new Array();
		while(typeof(current.nodeFather)!="undefined"){
			pathNode.push(current);
			current=current.nodeFather;
		}
		pathNode.reverse();
		return pathNode;
	}

	//Funzione che restituisce il percorso in formato JSON
	this.getPathJSON=function(){
		var path=this.getPath(this.Tree.currentnode);
		var field=new Array("ID","CAPTION");
		var data=new Array();
		for(var i=0;i<path.length;i++){
			var dataValue=new Array(path[i].nodeid,path[i].descr);
			data.push(dataValue);
		}
		var parmsObj={Fields:field,Data:data};
		return parmsObj;
	}

	//Chiude il menu all'uscita dai sottomenu
	this.select_out=function(evt){
		el=GetEventSrcElement(evt);
		//Deseleziono se l'elemento non ha id
		if(Empty(el.id)){
			this.deselect_all(false);
		}
	}

	this.highlightCurrentNode=function() {
		//Deseleziona il vecchio
		if (this.selectedId!=''){
			var oldSelId=this.selectedId;
			var deCtrl=document.getElementById(oldSelId);
			//Controllo se sto navigando su livello di comparazione o se sto lasciando il livello di comparazione
			if(this.level_old==this.level_compare){

				//Menu principale.
				try{
					document.getElementById(deCtrl.id+"_back").className="menuview_img";
				}
				catch(e){}
				try{
					document.getElementById(deCtrl.id+"_sx").className="menuview_img_sx";
				}
				catch(e){}
				try{
					document.getElementById(deCtrl.id+"_dx").className="menuview_img_dx";
				}
				catch(e){}
				try{
					document.getElementById(deCtrl.id+"_icons").className="menuview_icon";
				}catch(e){}
				//Ripristino text
				try{
					var classes=deCtrl.className.replace("menuview_font_over","menuview_font");
					deCtrl.className=classes;
					document.getElementById(deCtrl.id+"_descr").className="menuview_font";
				}
				catch(e){}
				try{
					document.getElementById(this.selectedId+"_arr").className="menuview_font";
				}
				catch(e){}
			}
			else{
				try{
					// Submenu.
					deCtrl.className=deCtrl.className.replace("menuview_sub_font_over","menuview_sub_font");
				}
				catch(e){}
			}
			this.selectedId='';
		}

		// Salvo il nodo padre corrente in una variabile temporanea
		var nodeSubMenuCurrentFatherIdTmp = this.id+"_"+this.Tree.currentnode.index;
		// Salva la classe del nodo padre corrente
		try{
		var nodeSubMenuCurrentFatherClass = document.getElementById(this.nodeSubMenuCurrentFatherId+"_descr").className;
		}catch(e){};

		// Se sono nel menu orizzontale di livello 1 e il nodo padre è cambiato
		if(this.Tree.currentnode.level == 1 && nodeSubMenuCurrentFatherIdTmp != this.nodeSubMenuCurrentFatherId){

			// Controllo se sono sul menu orizzontale aiutandomi con la classe css, non devo essere in un submenu
			if(this.nodeSubMenuCurrentFatherId && (nodeSubMenuCurrentFatherClass=='menuview_font_over' || nodeSubMenuCurrentFatherClass=='menuview_font')){

				//Porto alla condizione iniziale il vecchio padre
				try{
					document.getElementById(this.nodeSubMenuCurrentFatherId+"_back").className="menuview_img";
				}catch(e){}
				try{
					document.getElementById(this.nodeSubMenuCurrentFatherId+"_sx").className="menuview_img_sx";
				}catch(e){}
				try{
					document.getElementById(this.nodeSubMenuCurrentFatherId+"_dx").className="menuview_img_dx";
				}catch(e){}
				try{
					document.getElementById(this.nodeSubMenuCurrentFatherId+"_icons").className="menuview_icon";
				}catch(e){}
				//Ripristino text
				try{
					document.getElementById(this.nodeSubMenuCurrentFatherId+"_descr").className="menuview_font";
				}catch(e){}
				try{
					document.getElementById(this.nodeSubMenuCurrentFatherId+"_arr").className="menuview_font";
				}catch(e){}
			}

			// Assegno il nuovo padre
			this.nodeSubMenuCurrentFatherId = nodeSubMenuCurrentFatherIdTmp;
		}

		// Sono in un sottomenu verticale e voglio che il menu principale di livello 1 selezionato rimanga evidenziato
		// Controllo se sono sul menu orizzontale aiutandomi con la classe css, non devo essere in un submenu
		if(this.nodeSubMenuCurrentFatherId && (nodeSubMenuCurrentFatherClass=='menuview_font_over' || nodeSubMenuCurrentFatherClass=='menuview_font')){
			//Evidenzio il padre dei sottomenu corrente
			try{
				document.getElementById(this.nodeSubMenuCurrentFatherId+"_back").className="menuview_img_over";
			}catch(e){}
			try{
				document.getElementById(this.nodeSubMenuCurrentFatherId+"_sx").className="menuview_img_sx_over";
			}catch(e){}
			try{
				document.getElementById(this.nodeSubMenuCurrentFatherId+"_dx").className="menuview_img_dx_over";
			}catch(e){}
			try{
				document.getElementById(this.nodeSubMenuCurrentFatherId+"_icons").className="menuview_icon_over";
			}catch(e){}
			//Ripristino text
			try{
				document.getElementById(this.nodeSubMenuCurrentFatherId+"_descr").className="menuview_font_over";
			}catch(e){}
			try{
				document.getElementById(this.nodeSubMenuCurrentFatherId+"_arr").className="menuview_font";
			}catch(e){}
		}

		// Seleziona il nuovo
		this.level_old=this.Tree.currentnode.level;
		this.selectedId=this.id+"_"+this.Tree.currentnode.index;
		var Selection=document.getElementById(this.selectedId);
		var SelectionBack=document.getElementById(this.selectedId+"_back");
		var SelectionSx=document.getElementById(this.selectedId+"_sx");
		var SelectionDx=document.getElementById(this.selectedId+"_dx");
		var SelectionArr=document.getElementById(this.selectedId+"_arr");
		var SelectionDescr=document.getElementById(this.selectedId+"_descr");
		var SelectionIcons=document.getElementById(this.selectedId+"_icons");

		if(this.Tree.currentnode.level==this.level_compare){

			//Menu principale
			var classes=Selection.className.replace("menuview_font","menuview_font_over");
			Selection.className=classes;
			if(SelectionDescr!=null){
				SelectionDescr.className="menuview_font_over";
			}

			if(SelectionArr!=null){
				SelectionArr.className="menuview_font_over";
			}

			SelectionBack.className="menuview_img_over";
			SelectionSx.className="menuview_img_sx_over";
			SelectionDx.className="menuview_img_dx_over";
			if (SelectionIcons != null)
				SelectionIcons.className="menuview_icon_over";
		}
		else{
			// Submenu
			Selection.className=Selection.className.replace("menuview_sub_font","menuview_sub_font_over");
		}

	}

	//Disabilita le voci di menu principali e i sottomenu (click su portlet e su voce menu - mouseout dalle voci senza figli)
	this.deselect_all=function(click_portlet){
		var deCtrl;
		if(this.Tree.currentnode.level!=0 || click_portlet){
			// Remove sub menu
			var index=this.getIndexBarCoupling();
			deCtrl=this.getCtrlElementSubMenu(index);
			if(deCtrl!=null)
				deCtrl.innerHTML="";
		} else{
			var idNode = this.id+"_"+this.Tree.currentnode.index;
			deCtrl=document.getElementById(idNode);

			document.getElementById(deCtrl.id+"_back").className="menuview_img";
			document.getElementById(deCtrl.id+"_sx").className="menuview_img_sx";
			document.getElementById(deCtrl.id+"_dx").className="menuview_img_dx";

			//Ripristino text
			var SelectionDescr=document.getElementById(deCtrl.id+"_descr");
			var classes=deCtrl.className.replace("menuview_font_over","menuview_font");
			deCtrl.className=classes;
			if (SelectionDescr!=null){
				SelectionDescr.className="menuview_font";
			}
			var SelectionArr=document.getElementById(this.selectedId+"_arr");
			if (SelectionArr!=null && deCtrl.id!=this.selectedId) {
				SelectionArr.style.backgroundColor=this.bg_color;
			}else{
				if (SelectionArr!=null) {
					SelectionArr.className="menuview_font";
				}
			}
			try{
				document.getElementById(deCtrl.id+"_icons").className="menuview_icon";
			}catch(e){}
		}
	}

	// Calcola il link del nodo attuale valorizzandolo
	this.makeLink=function(index){
			// Normalize node_link
			var node_link= (this.Tree.currentnode.link) ? this.Tree.currentnode.link : this.Tree.allnodes[index].link;
			var frame=this.Tree.currentnode.target;
			while(node_link.indexOf('|')>-1) node_link=node_link.replace('|',',');
			if (Substr(node_link,1,9) == "function:" ){
				// Funzione javascript definita nel portlet
				node_link = Strtran(node_link,"function:","");
				node_link = "javascript:ZtVWeb.getPortlet(\"" +this.form.portletname + "\")." +node_link;
			}
			else{
				if (node_link.indexOf('http://') !=0 && node_link.indexOf('https://') !=0 && !Empty(node_link && node_link.indexOf('javascript'))){
					node_link='../servlet/'+node_link;
				}
			}
			// Tolgo spazi in fondo
			node_link = node_link.replace(/\s+$/g,"");
			// Valorizzo i parametri racchiusi trai i caratteri %
			var param_name, param_value;
			var node_link_par = node_link.split('%');
			for(var i=1; i < node_link_par.length; i+=2){
				param_name = node_link_par[i];
				try{
					//getParameter e una funzione di callback che se definita sul portlet in cui e instanziato il menu
					//permette di decodificare i parametri passati da link
					if(typeof(this.form["getParameter"])!="undefined"){
						param_value = eval("this.form.getParameter('"+param_name+"')");
					}
					else{
						param_value = eval("this.form." + param_name + ".Value()");
					}
					node_link = Strtran(node_link,'%'+param_name +'%',escape(param_value));
				}catch(e){}
			}

			// Se devo eseguire una funzione javascript la eseguo ed esco
			if (node_link.indexOf("javascript:") > -1){
				eval(node_link);
				return false;
			}

			// Se nell'URL e presente il parametro m_cAction aggiungo al node_link i seguenti parametri:
			// &m_cMode=hyperlink&m_cParameterSequence=oarametro1,parametro2,...
			if (node_link.indexOf("m_cAction") > -1){
				// Recupero l'elenco di parametri da inserire nel m_cParameterSequence
				var params = node_link.substring(node_link.indexOf("?") + 1).split("&");
				var m_cParameterSequence = "";
				for (var i = 0; i < params.length; i++){
					if (params[i].indexOf("m_c") == -1){
						m_cParameterSequence = m_cParameterSequence + params[i].substring(0,params[i].indexOf("=")) + ",";
					}
				}
				// Rimuovo la virgola in fondo
				m_cParameterSequence = Left(m_cParameterSequence, m_cParameterSequence.length - 1);
				node_link = node_link + "&m_cMode=hyperlink&m_cParameterSequence=" + m_cParameterSequence;
			}

			//Invio sulla request il nome della finestra se questa e main.
			//Potrebbe essere utile lato server
			if(!Empty(this.target_default)&&frame.indexOf('dialogwindow')==-1)
				node_link+=(node_link.indexOf("?")!=-1)?"&m_cWindowName="+this.target_default:"?m_cWindowName="+this.target_default;

			//Modifica l'href per l'apertura su altra pagina
			var hrefId = this.id+"_"+index+"_link";
			if(document.getElementById(hrefId))
				document.getElementById(hrefId).href=node_link;

			return node_link;
	}

	this.onMenuClick=function(){
		//Sollevo evento prima del click
		this.dispatchEvent('BeforeClick');

		if(Empty(this.Tree.currentnode.link) && !Empty(this.link_secondary)){
			//Apertura menu secondario
			var submenu_name=this.Tree.currentnode.descr;
			var submenu_id=this.Tree.currentnode.nodeid;
			window.open(LRTrim(this.link_secondary)+"&start_uid="+submenu_id+"&start="+submenu_name,this.target_default);
		}
		else{

			var node_link = this.makeLink();
			if(!node_link) return;
			var frame=this.Tree.currentnode.target;

			// Normalize frame
			if(Empty(frame)){
				frame=(!Empty(this.target_default))?this.target_default:"_self"
			}
			
			//Include resource AJAX
			if(this.Tree.currentnode.bAjaxContainer){
				var objContainer = eval("this.form."+frame);
				if(typeof(objContainer) != "undefined")
					ZtVWeb.Include(node_link,objContainer.Ctrl,true);
				return;
			}
			
			//Open window
			var width = frame.substring(frame.indexOf('|')+1,frame.lastIndexOf('|'));
			var height = frame.substr(frame.lastIndexOf('|')+1,frame.length);
			if (frame.indexOf('dialogwindow') == 0){
				// Il TARGET mi arriva nel formato dialogwindow|altezza|larghezza
				if ((width.length > 0) && (height.length > 0))
					window.open(node_link,'','toolbar=no,scrollbars=yes,resizable=yes'+','+'width='+width+','+'height='+height);
				else
					window.open(node_link,'','toolbar=no,scrollbars=yes,resizable=yes');
			}else{
				try{
					var iframes=document.getElementsByName(frame);
					var found=false;
					for(var i=0; iframes[i]; i++) {
						if (iframes[i].tagName.toLowerCase() =="iframe"){
							iframes[i].src=node_link;
							found=true;
						}
					}
					if (!found)
						window.open(node_link,frame,'toolbar=no,scrollbars=yes,resizable=yes');
				}catch(e){}
			}
		}

		//Refresh del menu
		this.deselect_all(false);
		this.dispatchEvent('Click');
		//Calcolo il percorso e emmetto evento da passare al breadcrumb
		if(!Empty(this.emitter_name)&&this.Tree.currentnode.target!="_blank"){
			var parmsObj=this.getPathJSON();
			//Sollevo evento
			ZtVWeb.raiseEvent(this.emitter_name,parmsObj);
		}
	}

	/*TODO Aggiustare questa funzione*/
	this.NavXML = function (pNode,pLevel,pNodeXML,pNodeID,pParentID) {
		var level=pLevel;
		var nodeID,parentID;
		var node,NodeID,NodeName,NodeChild,NodeParent,Icons,Frame,NodeLink,NodeCssClass;
		nodeID=pNodeID;
		parentID=pParentID;
		for (var i=0; i < pNodeXML.childNodes.length;i++) {
			Frame='';
			var nodechild=pNodeXML.childNodes.item(i);
			if(i==0)level++;	//Incremento il livello se ci sono figli
			if (nodechild.nodeName==this.tag_node) {
				var index=nodeID;
				nodeID++;
				NodeID=getTagValue(nodechild,this.field_NodeID); //Tag del nodo
				NodeName=getTagValue(nodechild,this.field_NodeDescr); // Caption
				NodeChild= getTagValue(nodechild,this.field_ChildCount);	// Numero Childs (elements)
				NodeParent=parentID;	//ID Padre
				if(!Empty(this.field_Icons)) {
				    var value=getTagValue(nodechild,this.field_Icons);
					if (value.indexOf(".")>0)
						Icons=value; // percorso immagine
					else
						Icons="";
				}
				var oLink = new ItemLink(getTagValue(nodechild,this.field_NodeLink));
				NodeLink = oLink.link + (oLink.parameters.length > 0 ? '?'+oLink.parameters : '')	// Link
				NodeCssClass = getTagValue(nodechild,this.field_CssClass); //Classe CSS del nodo
				if(!(Empty(this.field_Frame)))
					Frame=getTagValue(nodechild,this.field_Frame);
				if(Empty(Frame)) Frame = oLink.target;	// target
				if (Empty(Frame)) Frame=this.target_default;
				node=pNode.addChild(NodeID,level,NodeName,NodeChild,"",NodeLink,Frame,Icons,"","",NodeParent,pNode,NodeCssClass,this.next_to_action);
				//Setto se il nodo deve fare chiamata AJAX
				node.bAjaxContainer = oLink.bAjaxContainer;
				returnID=this.NavXML(node,level,nodechild,nodeID,NodeID);
				nodeID=returnID;
			}
		}
		//Se il nodo ha figli ma non sono ancora presenti nel datasource setto che devo eseguire la querynode
		if ((pNode.childnum!='0' && pNode.children.length==0)||pNode.childnum==null){
			pNode.setExecuteQuery(true);
		}
		returnID=nodeID;
		return returnID;
	}

	this.getNodesChildSQL = function (pNodeID){
		var idxFieldNodeParent=this.datasource.getFldIdx(this.field_NodeParent);
		var Nodes = new Array();
		var i=0;
		// Seek root. Mi posiziono direttamente sul padre perche il datasource e ordinato per parent
		while (i<this.datasource.nRecs && this.datasource.Data[i][idxFieldNodeParent]!=pNodeID) i++;
		// Loop
		while (i<this.datasource.nRecs && this.datasource.Data[i][idxFieldNodeParent]==pNodeID){
			Nodes.push(this.datasource.Data[i]);
			i++;
		}
		return Nodes;
	}

	this.NavSQL = function (pNode,pLevel) {
		var level=pLevel;
		var node,NodeID,NodeName,NodeChild,NodeSeq,NodeParent,Icons,Expr,ExprNot,Frame,NodeLink,CssClass;
		var idxFieldNodeID=this.datasource.getFldIdx(this.field_NodeID);
		var idxFieldNodeName=this.datasource.getFldIdx(this.field_NodeDescr);
		var idxFieldChildNum=this.datasource.getFldIdx(this.field_ChildCount);
		var idxFieldNodeSeq=this.datasource.getFldIdx(this.field_NodeSeq);
		var idxFieldNodeParent=this.datasource.getFldIdx(this.field_NodeParent);
		var idxFieldIcons=this.datasource.getFldIdx(this.field_Icons);
		var idxFieldExpr=this.datasource.getFldIdx(this.field_Expr);
		var idxFieldExprNot=this.datasource.getFldIdx(this.field_ExprNot);
		var idxFieldFrame=this.datasource.getFldIdx(this.field_Frame);
		var idxFieldNodeLink=this.datasource.getFldIdx(this.field_NodeLink);
		var idxFieldCssClass=this.datasource.getFldIdx(this.field_CssClass);
		var NodesChild=this.getNodesChildSQL(pNode.nodeid);
		for (var i=0; i<NodesChild.length; i++) {
			if(i==0)level++;	//Incremento il livello se ci sono figli
			NodeID=Trim(NodesChild[i][idxFieldNodeID]);
			NodeName=Trim(NodesChild[i][idxFieldNodeName]);
			if (idxFieldChildNum!=-1) NodeChild=Trim(NodesChild[i][idxFieldChildNum]);
			NodeSeq=Trim(NodesChild[i][idxFieldNodeSeq]);
			NodeParent=Trim(NodesChild[i][idxFieldNodeParent]);
			Icons=Trim(NodesChild[i][idxFieldIcons]);
			Expr=Trim(NodesChild[i][idxFieldExpr]);
			ExprNot=Trim(NodesChild[i][idxFieldExprNot]);
			Frame=Trim(NodesChild[i][idxFieldFrame]); // target
			CssClass=Trim(NodesChild[i][idxFieldCssClass]); // classe CSS
			var oLink = new ItemLink(NodesChild[i][idxFieldNodeLink]);
			if (Frame.length==0) Frame = oLink.target;	// target
			if (Frame.length==0) Frame = this.target_default;
			NodeLink = oLink.link + (oLink.parameters.length > 0 ? '?'+oLink.parameters : '')	// Link
			node=pNode.addChild(NodeID,level,NodeName,NodeChild,NodeSeq,NodeLink,Frame,Icons,Expr,ExprNot,NodeParent,pNode,CssClass,this.next_to_action);
			//Setto se il nodo deve fare chiamata AJAX
			node.bAjaxContainer = oLink.bAjaxContainer;
			
			this.NavSQL(node,level);
		}
		//Se il nodo ha figli ma non sono ancora presenti nel datasource setto che devo eseguire la querynode
		if ((pNode.childnum!='0' && pNode.children.length==0)||pNode.childnum==null){
			pNode.setExecuteQuery(true);
		}
	}

	//Ritorna il nodo dato l'id
	this.getNodeByID=function(nodeid){
		for(i=0;i<this.Tree.allnodes.length;i++){
			tmpnode=this.Tree.allnodes[i];
			if(tmpnode!=null && tmpnode.nodeid==nodeid)
				return tmpnode;
		}
		return null;
	}

	this.log=function(){
	}

	this.FillData=function(data){
		this.datasource=data;
		//Rcupero da quale nodo mi proviene la query
		var nodeFromTimestamp = this.getNodeByID(this.datasource.lastTimestamp);
		var root=(this.querynode!=null?nodeFromTimestamp:this.Tree.getRoot());
		if(typeof(this.datasource.Data) != 'undefined'){
			// SQLDataProvider
			this.NavSQL(root,root.level);
		}else{
			// XMLDataProvider
			var xmlDoc = this.datasource.xmlDoc;
			var nodeXMLRoot=xmlDoc.documentElement.selectSingleNode(this.datasource.root);
			// root description
			this.Tree.descr=getTagValue(nodeXMLRoot,this.field_NodeDescr);
			this.NavXML(root,root.level,nodeXMLRoot,0,-1);
		}
		if(root.children.length!=0){
			if(this.querynode==null){
				this.Tree.render();
			}
			else if((root.nodeid==this.Tree.currentnode.nodeid)||(this.bypassView==1)){
				this.view(root);
			}
		}
	}

	this.setRowsCols=function(NodeID,ChildCount,NodeDescr,NodeSeq,NodeParent,Icons,Expr,ExprNot,Frame,NodeLink,CssClass){
		this.field_NodeID=NodeID;
		this.field_ChildCount=ChildCount;
		this.field_NodeDescr=NodeDescr;
		this.field_NodeSeq=NodeSeq;
		this.field_NodeParent=NodeParent;
		this.field_Icons=Icons;
		this.field_Expr=Expr;
		this.field_ExprNot=ExprNot;
		this.field_Frame=Frame;
		this.field_NodeLink=NodeLink;
		this.field_CssClass=CssClass;
	}

	// Crea l'albero
	this.Tree=new this.tree(this) ;

	//Funzioni richiamabili per ridimensionare il form in base alle dimensioni del componente
	this.adjustFormHeight=function(cnt){
		if(this.form.Ctrl.offsetHeight==0 && (cnt==null || cnt<10)) {
			setTimeout(this.form.formid+'.'+this.name+'.adjustFormHeight('+(cnt==null?0:cnt+1)+')',200);
		} else {
			this.form.queueAdjustHeight(50);
			if (parent.ZtVWeb)
				parent.ZtVWeb.windowResized();
		}
	}

	this.getRenderHeight=function(){
		var ctrl = document.getElementById(this.id+"_main_menu");
		if(ctrl!=null){
			var h=ctrl.offsetHeight;
			return (h>this.minheight?h:null)
		}
		else{
			return null;
		}
	}

	this.Ctrl_mousedown=function(evt){
		el =GetEventSrcElement(evt);
		if(id.substr(0,id.indexOf("_"))==el.id){
			//Ho fatto click sul portlet contenente il menu
			this.over=false;
			this.deselect_all('true');
		}
	}
	
	// Write in console
	this.log = function(str) {
	
		if(!this.console) return false;
		
		// Date
		var date = new Date();
		
		// Get console
		var console = document.getElementById('console');
		
		// H:M:S
		var h = date.getHours();
		var m = date.getMinutes();
		var s = date.getSeconds();
		
		if(h<10) h = 0 + "" + h;
		if(m<10) m = 0 + "" + m;
		if(s<10) s = 0 + "" + s;
		
		// Update console
		console.innerHTML = h + ':' + m + ':' + s + ' - ' + str + "<br/>" + console.innerHTML;
	}
	
	// Init console
	this.initConsole = function() {

		if(!this.console) this.console = true;
		
		// Create console area
		var div = document.createElement('div');
		div.id = "console";
		div.style.position = "absolute";
		div.style.top = "0px";
		div.style.left = "0px";
		div.style.width = "100%";
		div.style.height = "100px";
		div.style.background = "#ececec";
		div.style.border = "1px solid gray";
		div.style.fontFamily = "Verdana";
		div.style.overflow = "auto";
		div.style.fontSize = "7pt";
		div.style.color = "gray";
		div.style.zIndex = "999999";
		document.body.appendChild(div);	

		var div = document.createElement('div');
		div.id = "consoleReset";
		div.style.position = "absolute";
		div.style.top = "86px";
		div.style.left = "0px";
		div.style.width = "40px";
		div.style.height = "14px";
		div.style.fontFamily = "Verdana";
		div.style.background = "gray";
		div.style.overflow = "hidden";
		div.style.fontSize = "7pt";
		div.style.color = "#fff";
		div.innerHTML = "<a style=\"margin-left:5px;color:fff;text-decoration:none;\" href=\"#\" onclick=\"document.getElementById('console').innerHTML='';\">Reset</a>";
		document.body.appendChild(div);	
	}
	
	

}

/**************Funzioni di libreria***************/
function ItemLink(item) {
	this.link='';
	this.target='';
	this.parameters="";
	var as=item.split('?');
	this.bAjaxContainer = false;
	if (as.length > 0) this.link=as[0];
	if (as.length > 1) {
		var ap=as[1].split('&');
		for (var i=0; i<ap.length; i++) {
			if (ap[i].indexOf('target=') >=0) {
				this.target=ap[i].substr(7);
			}
			else if (ap[i].indexOf('target_container=') >=0) {
				this.target=ap[i].substr(17);
				this.bAjaxContainer = true;
			} else {
				this.parameters+=(this.parameters.length==0 ? '' : '&')+ap[i];
			}
		}
	}
}

function getTagValue(nodechild,tagname) {
   try {
		return LRTrim(nodechild.selectSingleNode(tagname).firstChild.nodeValue);
	} catch(e) {
		return "";
	}
}

function findX(element){
	var parent=element;
	var x=0;
	while(parent.offsetParent){
		x+=parent.offsetLeft;
		parent=parent.offsetParent;
	}
	return x;
}

ZtVWeb.MenuViewCtrl.prototype=new ZtVWeb.StdControl;
}

