function Filter()
{
	this.exec = function(element)
	{
		return true;
	}
}

function AttributeFilter(attr, val)
{
	var attribute = attr;
	var pattern = val;
	
	this.exec = function(element)
	{
		if(pattern.test(element.getAttribute(attribute))) return true;
		else return false;
	}
}

function AttributeEqualsFilter(attr, val)
{
	var value = val;
	var attribute = attr;
	
	this.exec = function(element)
	{
		if(element.getAttribute(attribute) == value) return true;
		else return false;
	}
}

function AttributeStartWithFilter(attr, val)
{
	var value = val;
	var attribute = attr;
	
	this.exec = function(element)
	{
		var pattern = new RegExp("^" + value, "g");
		if(pattern.test( element.getAttribute(attribute) )) return true;
		else return false;
	}
}

function AttributeEndWithFilter(attr, val)
{
	var value = val;
	var attribute = attr;
	
	this.exec = function(element)
	{
		var pattern = new RegExp(value + "$", "gi");
		if(pattern.test(element.getAttribute(attribute))) return true;
		else return false;
	}
}

function Dom()
{

	this.getLinks = function(filter)
	{
		if(!filter) filter = new Filter();
		
		var childArray = new Array();
		
		for(q = 0; q < document.links.length; q++ )
			if (filter.exec(document.links[q])) childArray.push(document.links[q])
		
		return childArray;
	}
	
	this.getChildElements = function(childType, element, parseSubtree, filter, level) //nota: level è di uso interno alla ricorsione e non è da passare quando si richiama il metodo
	{
		var childArray = new Array();
		var el = element;
		if (!level) level = 0;
		if(!filter) filter = new Filter();
		if(!element) return childArray;
		
		do
		{
			if( (parseSubtree || level == 0 ) && el.hasChildNodes())
			{
				var tmpArray = document.dom.getChildElements(childType, el.firstChild, true, filter, level + 1);
				childArray = childArray.concat(tmpArray);
			}
			
			if(el.tagName && filter.exec(el))
			{
				if(el.tagName.toLowerCase() == childType.toLowerCase()) childArray.push(el);
			}
		}
		while(el = el.nextSibling);
		
		return childArray;
	}
	
	this.setClass = function(element, className, filter)
	{
		if(!element) return;
		if( !(element.slice || element.nodeType) ) return;
		
		if(!filter) filter = new Filter();
		
		var unparsedElements;
		
		if( element.slice ) //se è un array di elementi
		{
			var el
			unparsedElements = new Array();
						
			for(q = 0; q < element.length; q++)
			{
				el = element[q];
				
				if( el.nodeType && filter.exec(el) ) el.className += " " + className; //
				else unparsedElements.push(el);
			}
			return unparsedElements;
		}	
		else //se è un elemento singolo
		{	
			if( element.nodeType && filter.exec(el) ) element.className += " " + className;
			return null;
		}
	}
	
	this.appendCSS = function(cssFile)
	{
		
		if (document.createStyleSheet && !document.browser.op)
		{
			document.createStyleSheet(cssFile)
		}
		else
		{
			var css = '\n@import url("' + cssFile + '"); \n';
			var importCSS = document.createTextNode(css);
			var myStyle = document.createElement("style");
			
			myStyle.setAttribute("type", "text/css");
			myStyle.appendChild(importCSS);
			pageStyle = document.getElementsByTagName("style")[0];
			pageStyle.parentNode.insertBefore(myStyle, pageStyle.nextSibling)
		}
	}
}

function BrowserDetector()
{
	var agent = navigator.userAgent.toLowerCase();
		
	//definizione delle variabili di detection del browser
	this.ie4  = (document.all && !window.opera ? true : false);
	this.ie5  = (document.all && !document.fireEvent && !window.opera ? true : false);
	this.mac5 = (document.all && document.getElementById && !document.mimeType && !window.opera);
	this.ie55 = (document.all && document.fireEvent && !document.createComment ? true : false);
	this.ie6  = (document.all && document.fireEvent && document.createComment ? true : false);
	this.ie   = this.ie4 || this.ie5 || this.ie55 || this.ie6;
	
	this.op  = (agent.indexOf("opera") != -1);
	this.op2 = (agent.indexOf("opera 2") != -1 || agent.indexOf("opera/2") != -1);
    this.op3 = (agent.indexOf("opera 3") != -1 || agent.indexOf("opera/3") != -1);
    this.op4 = (agent.indexOf("opera 4") != -1 || agent.indexOf("opera/4") != -1);
	this.op6 = (agent.indexOf("opera 6") != -1 || agent.indexOf("opera/6") != -1); 
	this.op5 = (agent.indexOf("opera 5") != -1 || agent.indexOf("opera/5") != -1);
	this.op7 = (agent.indexOf("opera 7") != -1 || agent.indexOf("opera/7") != -1);
    this.op8 = (agent.indexOf("opera 8") != -1 || agent.indexOf("opera/8") != -1);
    this.op9 = (agent.indexOf("opera 9") != -1 || agent.indexOf("opera/9") != -1);
	this.op5up = (this.op && !this.op2 && !this.op3 && !this.op4);
    this.op6up = (this.op && !this.op2 && !this.op3 && !this.op4 && !this.op5); 
    this.op7up = (this.op && !this.op2 && !this.op3 && !this.op4 && !this.op5 && !this.op6); 
    this.op8up = (this.op && !this.op2 && !this.op3 && !this.op4 && !this.op5 && !this.op6 && !this.op7); 
	this.op9up = (this.op && !this.op2 && !this.op3 && !this.op4 && !this.op5 && !this.op6 && !this.op7 &&!this.op8);
	
	this.ns4  = (document.layers ? true : false);
	this.ns6  = (!document.all && !window.opera && document.getElementById ? true : false);
	this.ns   = this.ns6 || this.ns4;

}

function Locus() //ver 3.0 DOM by marco
{
	var oldWord = new Array();
	var newWord = new Array();
	
	var params = new Array();
	var links = new Array();
	
	var levels = 0;
	var isIndex = 0;
	
	params["homePageName"] = "home";
	params["dirIndexName"] = "";
	params["separator"] = " / ";
	params["idName"] = "bar";
	params["baseElement"] = "span";
	
	this.set = function(elementId)
	{
		var container = document.createElement( params["baseElement"] );
		var realpath;
		var path;
		
		container.setAttribute("id", params["idName"]);
		
		//elimina il nome della pagina
		path = document.location.pathname.replace(/\/[^\/]\.[a-z]{3}(\?[^\?]+)?/i, "");
		realPath = path;
		
		//elimina gli underscore
		path = path.replace(/_/g, " ");
		
		//sostituzioni del dizionario
		for(q = 0; q < oldWord.length; q++)
			path = path.replace(oldWord[q], newWord[q]);
			
		//conta i livelli presenti nel path (-2 perchè nell'url ci sono anche gli / iniziale e finale che intervengono nello split della stringa)
		levels = path.split("/").length - 2;
		
		//crea i link e li inserisce nel container
		for(q = levels; q >= 1 ; q--)
		//for(q = 1; q <= levels ; q++)
		{
			createLink( container, params["idName"] + (levels - q), getLevelName(path, q), getLevelPath(realPath, q) + params["dirIndexName"], document.createTextNode( params["separator"]) );
		}
		
		//crea il link alla homepage
		createLink( container, params["idName"] + "Home", params["homePageName"], "/" + params["dirIndexName"], document.createTextNode( params["separator"]) );
		
		//rimuove l'elemento spaziatore al fondo della barra
		container.removeChild(container.lastChild)
		
		//elimina il contenuto base dell'elemento contenitore della barra
		document.getElementById(elementId).removeChild( document.getElementById(elementId).firstChild )
		
		//inserisce la barra nell'elemento selezionato
		document.getElementById(elementId).appendChild(container);
	}
	
	this.setParam = function(param, value)
	{
		params[param] = value;
	}
	
	this.dictionary = function(ini, fin)
	{
		if (!ini || !fin) return;
		
		oldWord.push(ini);
		newWord.push(fin);
	}
	
	function createLink (container, idName, innerHTML, href, separator)
	{
		var el = document.createElement("a");
		el.setAttribute("id", idName);
		
		el.innerHTML = innerHTML;
		el.setAttribute( "href", href );
		
		container.insertBefore(separator, container.firstChild);
		container.insertBefore(el, container.firstChild);
	}
	
	function getLevelName(lPath, level)
	{
		lPath = lPath.replace(/^\//, "").replace(/\/$/, "");
		names = lPath.split("/");
		return names[level -1];
	}
	
	function getLevelPath(rPath, level)
	{
		rPath = rPath.replace(/^\//, "").replace(/\/$/, "");
		
		var pathArray = rPath.split("/");
		var result = "/";
		
		for(q = 0; q < level; q++) result += pathArray[q] + "/";
		return result;
	}
}

function LevelChanger()
{
	var layers = new Array();
	var actualVisible = null;
	
	var hideClass;
	var showClass;
	var hiddenClass;
	
	var hideAll = false;
	
	this.setLevels = function()
	{
		for(q=0; q < this.setLevels.arguments.length; q++)
		{
			var name = this.setLevels.arguments[q]
			
			layers[name] = document.getElementById(name);
			
			layers[name].visible = (layers[name].className != hiddenClass ? true : false);
			layers[name].show = show;
			layers[name].hide = hide;
			layers[name].hideClass = hideClass;
			layers[name].showClass = showClass;
			layers[name].originalWidth = layers[name].offsetWidth;
			
			if (hideAll) layers[name].hide();
			if (layers[name].visible) actualVisible = name;
		}
	}
	
	this.hideAll = function ( h )
	{
		hideAll = h
	}
	
	this.setHiddenClass = function(name)
	{
		hiddenClass = name;
	}
	
	this.setHideClass = function(name)
	{
		hideClass = name;
	}
	
	this.setShowClass = function(name)
	{
		showClass = name;
	}
	
	this.showLevel = function( name )
	{
		if (layers[name].visible) return;
		
		if (actualVisible) layers[actualVisible].hide();
		layers[name].show();
		
		actualVisible = name;
	}
	
	this.hideLevel = function( name )
	{
		if (!layers[name].visible) return;
		
		layers[name].hide();
		actualVisible = null;
	}
	
	function show()
	{
		if(!this.visible)
		{
			this.className = this.showClass;
			this.visible = true;
		}
	}
	
	function hide()
	{
		if(this.visible)
		{
			this.className = this.hideClass;
			this.visible = false;
		}
	}
}

function LinkManager()
{
	var myLink
	var enabled;
	
	this.linkId = function( id )
	{
		var tag = /a/i;
		
		enabled = false;
		myLink = document.getElementById(id);
		
		if (tag.test(myLink.tagName)) enabled = true;
		else alert("L'elemento '" + id + "' non è un link");
	}
	
	this.href = function ( url )
	{
		if (enabled) myLink.setAttribute("href", url);
	}
	
	this.click = function ( val )
	{
		if (enabled) myLink.setAttribute("onClick", val);
	}
	
	this.mouseUp = function ( val )
	{
		if (enabled) myLink.setAttribute("onMouseUp", val);
	}
	
	this.title = function ( title )
	{
		if (enabled) myLink.setAttribute("title", title);
	}
	
	this.target = function ( target )
	{
		if (enabled) myLink.setAttribute("target", target);
	}
}

function cookie(name,expires,path,domain,secure)
	{
	//proprietà dell'oggetto
	this.varValue = ""; 	//valore del cookie intero
	this.varName = name; 	//nome del valore memorizzato
	this.expString = ((expires == null) ? "" : ("; expires=" + expires.toGMTString()));	//durata del cookie
	this.pathString = ((path == null) ? "" : ("; path=" + path));			//percorso per il cookie
	this.domainString = ((domain == null) ? "" : ("; domain=" + domain));		//dominio del cookie
	this.secureString = ((secure == true) ? "; secure" : "");				//cookie sicuro?
	this.deleted = ((document.cookie.indexOf(name) != -1) ? false : true)       //controlla se il coockie è presente	
	
	//metodi dell'oggetto
	this.getVal = function()//funzione di recupero del valore memorizzato; 
	{
		if (this.deleted) return null
		
		offset = this.varName.length+1;
		this.varValue = new String(document.cookie+";");
		
		inizio = this.varValue.indexOf(this.varName);
	
		if (inizio!=-1) 
			{
			fine = this.varValue.indexOf(";",inizio)
			result = this.varValue.substring((inizio+offset),fine);
			return unescape(result);
			}
		else return null
	}
	
	this.setVal = function() // funzione di impostazione del valore del cookie
	{
		this.deleted = false
		this.varValue = value;
		document.cookie = this.varName+"="+escape(value)+this.expString+this.pathString+this.domainString+this.secureString;
	}
	
	this.delCookie = function() //funzione di cancellazione: imposta la data di scadenza del cookie 3gg addietro, così il browser lo cancella
	{
		this.deleted=true;
		expDate= new Date();
		expDate.setTime(expDate.getTime()-3*24*60*60*1000);
		expDate.toGMTString();
		document.cookie=this.varName+"=null"+"; expires="+expDate.toGMTString()
	}

	this.isset = function() //ritorna true se il cookie è presente
	{
		return !this.deleted;
	}
	
	this.getName = function() //ritorna il nome del cookie (che è il primo argomento del costruttore)
	{
		return this.varName;
	}
}

function expDate(mesi,giorni,ore,minuti)
{
	//proprietà dell'oggetto
	this.mesi = mesi;
	this.giorni = giorni;
	this.ore = ore;
	this.minuti = minuti;
	
	//metodi dell'oggetto
	this.get= function()
	{
		var mesi = this.mesi*30*24*60*60*1000;
		var giorni = this.giorni*24*60*60*1000;
		var ore = this.ore*60*60*1000;
		var minuti = this.minuti*60*1000;
		var result = new Date();
		result.setTime( result.getTime() + mesi + giorni + ore + minuti );
		return result;
	}	
}

function DHTMenu()	//gestisce un menu dinamico a cascata fatto con ul / li
{
	var showClass = "show";			//classe che visualizza il menu nascosto
	var linkClass = "true";			//classe da applicare al link che è stato aperto
	var pathList = new Array();		//contiene l'elenco dei path abilitati ad utilizzare il menu dhtml
	var cssPath = new Array();		//contiene i path ai css da aggiungere
				
	function menu()		//questa funzione viene applicata all'evento onclick del link sensibile
	{
		this.open = !this.open;
		
		if(this.open == true)
		{
			this.parentNode.memoClass = this.parentNode.className;
			this.memoClass = this.className
			this.parentNode.className += " " + showClass;
			this.className += " " + linkClass;
		}
		else
		{
			this.parentNode.className = this.parentNode.memoClass;
			this.className = this.memoClass;
		}
	}
	
	/*
		abilita le funzionalità del menù dinamico, importando i css per la gestione,
		se l'url della pagina è stato inserito come enablePath
	*/
	this.init = function()
	{
		var path = location.pathname;
		var sectionEnabled = -1;
		var cnt = 0;
		
		// controllo se l'url attuale è abilitato al menù dinamico. 
		// appena ho un match tra url e percorso abilitato esco dal ciclo
		while (cnt < pathList.length && sectionEnabled == -1)
		{
			var tmpEx = new RegExp(pathList[cnt].path,"i");
			if ( tmpEx.test(path) ) sectionEnabled = cnt;
			cnt++;
		}
		
		// se l'url è abilitato sectionEnabled contiene l'indice del pathList da utlizzare per il menù. 
		// dal pathList estraggo le label dei css da utilizzare nella sezione
		if (sectionEnabled > -1)
		{
			var labels = pathList[sectionEnabled].label.split(",");
			for(q=0; q < labels.length; q++)
			{
				document.write('<link href="' + cssPath[labels[q]] + '" rel="stylesheet" type="text/css" />');
			}
		}
	}
	
	/*
		si utilizza per creare un elenco di css da utilizzare per il menù dinamico.
		label è un'etichetta usata come nome breve del css.
		deve essere chiamato prima di enablePath()
	*/
	this.setCssPath = function(css, label) 
	{
		cssPath[label] = css;
	}
	
	/*
		configura path specifici per eseguire il menù dinamico.
		L'asterisco * è il carattere jolly es. /sezione/* oppure /*
		label è il nome del css da utilizzare per il path definito. 
		label può contenere un elenco di nomi di css separati da virgola,
		ovvero ad ogni path è possibile associare uno o più css.
		deve essere chiamato prima di init()
	*/
	this.enablePath = function(path, label) 
	{
		var pathInfo = new Object();
		
		path = path.replace("\*", ".*");
		
		pathInfo.path = "^" + path + "$";
		pathInfo.label = label;
		
		pathList[pathList.length] =  pathInfo;
	}
	
	this.setShowClass = function(name)		//imposta la classe di visualizzazione dell'elemento nascosto se diversa dal default
	{
		showClass = name
	}
	
	this.setLinkClass = function(name)		//imposta la classe del link cliccato se diversa dal default
	{
		linkClass = name;	
	}
	
	/*
		abilita i link alla visualizzazione dell'elemento nascosto. 
		id è l'elemento contenitore della lista di link.
		title il titolo da impostare ad ogni link contenente un sottomenu
	*/
	this.enable = function (id, title)
	{
		var sensibleLinkFilter = new AttributeEqualsFilter("href", "javascript:menu()");	//filtra gli elementi con l'attributo specificato
		var sensibleLinks = document.dom.getChildElements ("a", document.getElementById(id), true, sensibleLinkFilter);	//estrae gli elementi 'a' dal contenitore usando il filltro 
		for (q=0; q < sensibleLinks.length; q++)	//modifica gli elementi 'a' per renderli attivi 
		{
			sensibleLinks[q].href = "javascript:foo()";
			sensibleLinks[q].onclick = menu;
			sensibleLinks[q].open = false;
			if (title != null) sensibleLinks[q].title = title;
		}
	}
}

function tabManager()
{
	var tabs = new Array()
	var cssClass = null;
	
	this.addTab = function(tabId, urlPath, localClass)
	{
		var tabInfo = new Object();
		
		tabInfo.id = tabId;
		tabInfo.url = new RegExp( "^" + urlPath.replace("\*", ".*") + "$" );
		tabInfo.cssClass = ( localClass == null ? cssClass : localClass );
		
		tabs.push(tabInfo);
	}
	
	this.dafaultClass = function(classe)
	{
		cssClass = classe;
	}
	
	this.execute = function()
	{
		var index = 0;
		var exit = false;
		var path = document.location.pathname;
		
		while (index < tabs.length && !exit)	
		{
			if( tabs[index].url.test(path) )
			{
				document.getElementById( tabs[index].id ).className += " " + tabs[index].cssClass;
				exit = true;
			}
			
			++index;
		}
	}
}

