	/**
	 * Mostra un elemento dato il suo ID
	 *
	 * @param elementId : id dell'elemento
	 */
	function hideElementById(elementId) {
		var div = document.getElementById(elementId);
		if(div){
			div.style.display="none";
		}
	}
	
	/**
	 * Nasconde un elemento dato il suo ID
	 *
	 * @param elementId : id dell'elemento
	 */
	function showElementById(elementId) {
		var div = document.getElementById(elementId);
		if(div){
			div.style.display="";
		}
	}

	/**
	 * Funzione che inserisce una pagina renderizzata in un container div
	 * 		JSP 						/jsp/catalogo/online/main.jsp
	 *		Form di riferiemento		catalogcategoriesform
	 * Usato per il menu del catalogo BTicino, svolge una chiamata asincrona.
	 * 
 	 * @param category		: categoria selezionata, il cui categoryId è da aggiornare
	 * @param categoryId	: categoryId da aggiornare
	 * @param renderer		: render di visualizzazione della pagina
	 * @param conteinerId	: contenitore della pagina renderizzata
	 */

	function drawCategoryOnDiv(category, categoryId, renderer, containerId) {

		resetTechChars();
		
		var cf = document.catalogcategoriesform;
								
		setAnchorStyleClass(category, categoryId, 'selected','');	// aggiorno il path di selezione
		setSearchCategory(category, categoryId);					// imposto lo stato nella searchform
		
		cf.categoryId.value = categoryId;
		cf.renderer.value = renderer;
		
		if (containerId != '') {
			loadHTMLOnElementId(cf, containerId);
		}
	}
	
	/**
	 * Funzione che imposta il codice di una categoria nella searchform
	 * 		JSP							/jsp/catalogo/online/main.jsp
	 *		Form di riferimento			searchform
	 * NOTA: vengono annullati i valori di categoria della searchform per i branch di livello più basso
	 *
 	 * @param category				 : categoria selezionata, il cui categoryId è da aggiornare
	 * @param categoryId			 : categoryId da aggiornare
	 */
	function setSearchCategory(category, categoryId) {
	
		var sf = document.catalogsearchform;
	 		
		// ottengo gli oggetti associati agli input hidden della search form 			
		var elementCat0 = sf.cat2;
		var elementCat1 = sf.cat3;
		var elementCat2 = sf.cat4;
		var elementCat3 = sf.cat5;	
		
		// costruisco una cascata che va dal livello minore a quello maggiore, dove vengono annullati
		// i valori che corrispondono ad una categoria di livello basso non ancora selezionata
		if (elementCat3.name == category) elementCat3.value = categoryId;
		else {
			elementCat3.value = '';
			if (elementCat2.name == category) elementCat2.value = categoryId;
			else {
				elementCat2.value = '';
				if (elementCat1.name == category) elementCat1.value = categoryId;
				else {
					elementCat1.value = '';
					if (elementCat0.name == category) elementCat0.value = categoryId;
					else {
						elementCat0.value = '';
					}
				}
			}
		}		
	}
	
	/**
	 * Funzione che imposta lo stile dell'anchor corrente.
	 * NOTA: vengono reimpostati gli stili degli altri elementi del gruppo.
	 *
	 * @param category				 : categoria selezionata, il cui stile associato al categoryId è da aggiornare
	 * @param categoryId			 : categoryId da aggiornare
	 * @param styleSelectedClass	 : stile dell'anchor
 	 * @param styleUnselectedClasses : stile degli anchor appartenti alla categoria
	 */
	function setAnchorStyleClass(category, categoryId, styleSelectedClass, styleUnselectedClasses) { 	
		if (document.getElementById(categoryId) != null) {
			var sf = document.catalogsearchform;	 
		
			// imposto l'elemento precedentemente selezionato in modo che sia deselezionato   	  	
	    for (var i = 0; i < sf.elements.length; i++) {
				if (sf.elements[i].type == 'hidden') {				
					if (sf.elements[i].name == category && sf.elements[i].value != '') {
						if (document.getElementById(sf.elements[i].value) != null) {
							document.getElementById(sf.elements[i].value).className = styleUnselectedClasses;
						}
					}
				}			
			}
	                                                                                        
			// imposta selezionato l'attributo di classe dell'anchor        	        
			document.getElementById(categoryId).className = styleSelectedClass;	
		}	
	}
	
	
	/**
	 * Funzione che submitta la search form
	 * 
	 * @param reset : reset dei parametri di browse delle pagine
	 */
	function search(reset, searchType) {	
	
		// seleziono la form destinata al motore di ricerca
		if(searchType == 'fulltextsearch') 
			sf = document.catalogfulltextsearchform;
		else 
			sf = document.catalogsearchform;
		
		if (reset) {
			sf.currentPage.value = 1;
			sf.rowMin.value = 0;
			sf.rowMax.value = sf.pageSize.value;
		}

		loadHTMLOnElementId(sf, 'results');
	}
	
	function searchPatch(reset, searchType) {	
		search(reset, searchType);
	}
	
	/**
	 * Funzione necessaria al caricamento paginato degli articoli, consente il cambiamento del page set
	 *
	 * @param currentPageSet : pagina corrente da settare
	 * @param mode			 : 'up' o 'down'
 	 * @param searchType	 : tipo di motore di ricerca 
	 */
	function changePageSet(currPageSet, mode, searchType){
		
		// seleziono la form destinata al motore di ricerca
		if(searchType == 'fulltextsearch') 
			sf = document.catalogfulltextsearchform;
		else 
			sf = document.catalogsearchform;
		
		// imposto l'ultimo evento
		setLastEvent("changePage", searchType);
		
		var pageToGo = ((currPageSet + 1) * sf.pagesPerSet.value) + 1;
	
		if(mode == 'up'){
			// next page set
			pageToGo = ((currPageSet + 1) * sf.pagesPerSet.value) + 1;
		}else{
			// previous page set
			pageToGo = ((currPageSet - 1) * sf.pagesPerSet.value) + 1;
		}
	
		sf.currentPage.value = pageToGo;
		sf.rowMin.value = (sf.pageSize.value * (pageToGo - 1));
		sf.rowMax.value = (sf.pageSize.value * pageToGo);
		
		// submitto la search form
		search(false, searchType);	
	}
	
	/**
	 * Funzione necessaria al caricamento paginato degli articoli, consente il cambiamento delle pagine
	 *
	 * @param currentPageSet : pagina corrente da settare
	 * @param mode			 : 'up' o 'down' 
	 * @param searchType	 : tipo di motore di ricerca
	 */
	function changePage(pageToGo, searchType){
	
		var sf = null;

		// seleziono la form destinata al motore di ricerca
		if(searchType == 'fulltextsearch') 
			sf = document.catalogfulltextsearchform;
		else 
			sf = document.catalogsearchform;
		
		// imposto l'ultimo evento
		setLastEvent("changePage", searchType);			 
	
		sf.currentPage.value = pageToGo;

		// set rowMin and rowMax
		sf.rowMin.value = (sf.pageSize.value * (pageToGo - 1));
		sf.rowMax.value = (sf.pageSize.value * pageToGo);
		
		// submitto la search form
		search(false, searchType);		
	}
	
	/**
	 * Funzione che inserisce una pagina renderizzata in un container div e submitta la ricerca
	 * 		JSP 						/jsp/catalogo/online/main.jsp
	 *		Form di riferiemento		catalogcategoriesform
	 * Usato per il menu del catalogo BTicino, svolge una chiamata asincrona.
	 * 
 	 * @param category		: categoria selezionata, il cui categoryId è da aggiornare
	 * @param categoryId	: categoryId da aggiornare
	 * @param renderer		: render di visualizzazione della pagina
	 * @param conteinerId	: contenitore della pagina renderizzata
	 */
	function drawCategoryAndSearch(category, categoryId, renderer, containerId) {
		// imposto l'ultimo evento
		setLastEvent("search");
		drawCategoryOnDiv(category, categoryId, renderer, containerId);
		search(true);
	}
	
	/**
	 * Funzione che imposta nella form di ricerca la variabile contenente l'ultimo evento
	 * @param lastEvent		: ultimo evento
 	 * @param searchType	 : tipo di motore di ricerca 
	 */
	 
	 function setLastEvent(event, searchType){
	 
		if(searchType == 'fulltextsearch') 
			sf = document.catalogfulltextsearchform;
		else 
			sf = document.catalogsearchform;		
		
		// imposto l'ultimo evento
		sf.lastEvent.value = event;	 	 	
	 }

	 /**
	  * Funzione che disegna le select contenenti le caratteristiche tecniche
	  * Il metodo colleziona i campi della catalogsearchform e compone l'url
	  * verso la action che colleziona le caratteristiche tecniche
	  *
	  * @param catalogType: "online" o "standalone"
	  * 
	  */
	 
	 function drawTechChars(catalogType){	 	
		var sf = document.catalogsearchform;
		var originalAction = sf.action;
		var appContext = "";
		
		if(originalAction.indexOf("http://") != -1){
			appContext = originalAction.substr("http://".length);
			appContext = appContext.split("/")[1];
		}else{
			appContext = originalAction.split("/")[1];
		}
		
	 	sf.action = '/' + appContext + '/catalog/' + catalogType + '/collecttechchars.do';
	 	
		showElementById('techchars');

		loadHTMLOnElementId(sf, 'techchars');	 	
		
		//	reimposto la action originale
		sf.action = originalAction;
	 }


	/*
	 * Funzione che valorizza il campo techChars nella catalogsearchform in base alle selezioni
	 * delle caratteristiche tecniche
	 *
	 */


	function setTechChars(){
		var sf = document.catalogsearchform;
		var tcf = document.catalogtechcharsform;

		//	resetto il campo della catalogsearchform contenente le caratteristiche
		//	tecniche potenzialmente impostate in una precedente ricerca
		sf.techChars.value = '';

		var currEl = null;
		for (i = 0; (tcf != null) && (i < tcf.elements.length); i++){			
			currEl = tcf.elements[i];
			if((currEl.value != null) && (currEl.value != "") && (currEl.type != "button")
				&& (currEl.type != "submit")){
				sf.techChars.value += currEl.value + "|";				
			}
		}
		
		//	elimino l'ultima pipe
		if(sf.techChars.value != ''){
			sf.techChars.value = sf.techChars.value.substring(0, sf.techChars.value.length - 1); 
		}
	}


	function resetTechChars(){
		var techcharsdiv = document.getElementById("techchars");
		var sf = document.catalogsearchform;
		var tcf = document.catalogtechcharsform;

		//	svuoto il div delle caratteristiche tecniche
		techcharsdiv.innerHTML = '';

		//	resetto la form delle caratteristiche tecniche
		//	la form esisterà solo quando si clicca sull'ultima gerarchia e, poiché questo
		//	metodo viene invocato ogni volta che vengono disegnate le sottocategorie
		//	è necessario controllare l'esistenza della catalogtechcharsform
		for (i = 0; (tcf != null) && (i < tcf.elements.length); i++){			
			tcf.elements[i].value = '';
		}	

		//  svuoto il campo techChars della catalogsearchform
		sf.techChars.value = '';
	}
	

	/** TEXT TRUNCATE */

	/**
	 * funzione troncatrice delle voci di menu mette i '...' dopo un certo tot di lettere in modo
	 * da non sconfinare con il testo
	 *
	 * @param divId  : div conetente le voci dei links da ridurre
	 * @param length : lunghezza massima delle voci
	 */
	function truncateMenuText(divId, length) {
		var len = 35;  // default length
		if (length) len = length;
		var div = document.getElementById(divId);
		var li = div.getElementsByTagName("a");
		
		for (var i = 0; i < li.length; i++) {
			if (li[i]) {					
			  var trunc = li[i].innerHTML;
			  
			  if (li[i].title == '' && trunc.length > len) {
			  	li[i].title = li[i].innerHTML;
			    trunc = trunc.substring(0, len);
			    trunc = trunc.replace(/\w+$/, '');
			    // trunc += '<a href="#" ' +
			    //  'onclick="this.parentNode.innerHTML=' +
			    //  'unescape(\''+escape(li[i].innerHTML)+'\');return false;">' +
			    //  '...<\/a>';
			    trunc += '...';
			    li[i].innerHTML = trunc;
			  }			  
			}
		}	
	}
	
	
	/** DYNAMIC BREADCRUMBS */
	
	/**
	 * questa funzione consente di inserire il livello di una breadcrumb in modo dinamico
	 * 
	 * @param breadCrumbId : id del div che contiene la breadcrumb
	 * @param level				 : livello da inserire
	 * @param label				 : etichetta del livello
	 * @param jsaction		 : azione javascript
	 * @param bullet			 : separatore dei livelli
	 * 
	 * NOTA: jsacrion -> location.href='http://....' imposta un link
	 */
	function breadCrumbAddLevel(breadCrumbId, level, label, jsaction, bullet) {	
		breadCrumbRemoveFromLevel(breadCrumbId, level);			
		if (document.getElementById(breadCrumbId)) {					
			var newLevel = document.createElement('span');
			newLevel.setAttribute('id', breadCrumbId + '#' + level);					
			newLevel.onclick = new Function("function level(){ breadCrumbRemoveFromLevel('" + breadCrumbId + "', '" + level + "', 'true'); " + jsaction + "; return false; } level();");
			var newLevelLink = document.createElement('a');					
			newLevelLink.setAttribute('href', '#');				
			newLevelLink.setAttribute("onclick", "function level(){ breadCrumbRemoveFromLevel('" + breadCrumbId + "', '" + level + "', 'true'); " + jsaction + "; return false; } level();");						
			newLevelLink.innerHTML = label;
			if (bullet) newLevel.innerHTML = bullet;
			else newLevel.innerHTML = ' > ';
			newLevel.appendChild(newLevelLink);
			document.getElementById(breadCrumbId).appendChild(newLevel);
		}
	}
	
	/**
	 * rimuove il livello di una breadcrumb
	 * 
	 * @param breadCrumbId : id del div che contiene la breadcrumb
	 * @param level				 : livello da inserire 
	 * @param currentToo	 : non elimina il nodo corrente se è settata e a true
	 */
	function breadCrumbRemoveFromLevel(breadCrumbId, level, currentToo) {

		if (document.getElementById(breadCrumbId)) {
			var breadCrumb = document.getElementById(breadCrumbId);
			var breadCrumbElements = breadCrumb.getElementsByTagName("span");
			
			level = currentToo ? level + 1 : level;
			var breadCrumbElementLevel = 0;
			removableLevels = new Array();
			for (var i = 0; i < breadCrumbElements.length; i++) {										
				if ((breadCrumbElements[i].id).match('#')) {
					breadCrumbElementLevel = (breadCrumbElements[i].id).substr((breadCrumbElements[i].id).lastIndexOf('#') + 1);				
					if (breadCrumbElementLevel > 0 && breadCrumbElementLevel >= level) {
						removableLevels.push(breadCrumbElements[i].id);																									
					}
				}
			}
			for ( ; removableLevels != 0; ) {		
				var removableLevel = document.getElementById(removableLevels.pop());
				breadCrumb.removeChild(removableLevel);
			}
		}
	}			
	
