// inizializza la mappa e tutti i vari oggetti che le servono
	function initialize(centerLat,centerLng,zoomLevel,zoomLevelMinus) {
		// punto iniziale in base a cui centrare la mappa
		lat              = parseFloat(centerLat);
		lng              = parseFloat(centerLng);
		initialZoomLevel = parseInt(zoomLevel, 10);

		if (zoomLevelMinus!=null && zoomLevelMinus!="-1") {
			minZoomLevel     = parseInt(minZoomLevel,10)-parseInt(zoomLevelMinus,10);
			initialZoomLevel = minZoomLevel;
		}
		
		if (google.maps.BrowserIsCompatible()) {
			initAsciiCodeMap();
			map = new google.maps.Map2(document.getElementById("map"));
			map.addControl(new google.maps.LargeMapControl());
			map.addControl(new google.maps.MapTypeControl());
			map.enableScrollWheelZoom(); 
			
			// carica il bordo del vento sulla mappa
			venetoLayerBorder = new google.maps.GeoXml(venetoLayerBorderUrl);
			
			// genera il punto che funge da centro della mappa
			var pt = new google.maps.LatLng(lat, lng);
			
			// cattura l'evento zoom e verifica che non vada oltre i limiti imposti
			google.maps.Event.addListener(map, "zoomend", function () {
											currentLevelZoom = map.getZoom();
											if (currentLevelZoom<minZoomLevel) {
												map.setZoom(minZoomLevel);
											} else if (currentLevelZoom>maxZoomInLevel) {
												map.setZoom(maxZoomInLevel);
											}
											if (map.getZoom()>minZoomLevel) {
												map.removeOverlay(venetoLayerBorder);
											} else if (map.getZoom()==minZoomLevel) {
									      		map.addOverlay(venetoLayerBorder);
											}
										});
			google.maps.Event.addListener(map, "mousemove", function (latlng) {
																findMousePosition(latlng);
															});
			
			map.setCenter(pt, initialZoomLevel);
			if (initialZoomLevel<=minZoomLevel) {
				map.addOverlay(venetoLayerBorder);
			}
			
			// inizializzo gli array in base ai quali verranno generati i marker
			initializeArrayMarker();
			for (var x=0; x<checkButton.length; x++) {
				performAction(checkButton[x]);
			}
			initLatLngBoundaries();

		    // The allowed region which the whole map must be within
		    allowedBounds = new google.maps.LatLngBounds(new google.maps.LatLng(latSW,lngSW), new google.maps.LatLng(latNE,lngNE));

			google.maps.Event.addListener(map, "move", function() {checkBounds();});
			google.maps.Event.addListener(map, "moveend", function() {
															// prima nascondo i vari div se ce ne sono di visualizzati
															hideLabels();
															checkLabels();
														});
		} else {
			alert("Il Browser non è compatibile con le librerie di GoogleMaps.");
		}
	}
	
	function findMousePosition(latlng) {
		var punto = map.fromLatLngToDivPixel(latlng);
		mouse_pos[0] = punto.x;
		mouse_pos[1] = punto.y;
	}

/*********** Metodi per visualizzare o meno i marker sulla mappa **************/
// obj è il riferimento al checkebox sul quale si è cliccato con il mouse
// se obj.checked=true  --> allora visualizzo i marker legati al valore della chekbox
// se obj.checked=false --> elimino dalla mappa i marker legati al valore della chekbox
// -- obj.value = 1 --> cantieri   --> visualizzerà i marker relativi alle ordinanze per i lavori in corso
// -- obj.value = 2 --> divieti    --> visualizzerà i marker relativi alle ordinanze per i limiti di velocità
// -- obj.value = 3 --> comunicati --> visualizzerà i marker relativi ai comunicati neve
// -- obj.value = 4 --> mevdar     --> visualizzerà i marker relativi ai mevdar
// -- obj.value = 5 --> smitcam    --> visualizzerà i marker relativi alle smitcam
// -- obj.value = 6 --> tronchi    --> link alla mappa statica che visualizza le strade in gestione
	function performAction(obj) {
		setProgressBar("show");
		
		var valore = obj.value;
		
		// aggiungo i marker selezionati
		if (obj.checked) {
			if (eval(valore) == 1) {
				setTimeout("showMarkers(ordinanze_lavori_markers)",3000);
			} else if (eval(valore) == 2) {
				setTimeout("showMarkers(ordinanze_limiti_markers)",3000);
			} else if (eval(valore) == 3) {
				setTimeout("showMarkers(comunicati_neve_markers)",3000);
			} else if (eval(valore) == 4) {
				setTimeout("showMarkers(mevdar_markers)",3000);
			} else if (eval(valore) == 5) {
				setTimeout("showMarkers(smitcam_markers)",3000);
			}/** else if (eval(valore) == 6) {
				//setTimeout("showPolylineMap()",3000);
			}**/
		} else {
			// tolgo dalla mappa i markers selezionati
			if (eval(valore) == 1) {
				setTimeout("hideMarkers(ordinanze_lavori_markers)",3000);
			} else if (eval(valore) == 2) {
				setTimeout("hideMarkers(ordinanze_limiti_markers)",3000);
			} else if (eval(valore) == 3) {
				setTimeout("hideMarkers(comunicati_neve_markers)",3000);
			} else if (eval(valore) == 4) {
				setTimeout("hideMarkers(mevdar_markers)",3000);
			} else if (eval(valore) == 5) {
				setTimeout("hideMarkers(smitcam_markers)",3000);
			} /**else if (eval(valore) == 6) {
				//setTimeout("hidePolylineMap()",3000);
			}**/
		}
		setTimeout("setProgressBar('hide')",3000);
	}

// metodo che mostra o nasconde la barra di caricamento
	function setProgressBar(option){
		if (option == "show") {
			document.getElementById("messageLoad").style.display = "block";
		}
		if (option == "hide") {
			document.getElementById("messageLoad").style.display = "none";
		}
	}


// metodo che crea un marker
	function createMarker(markerObject, tipo) {
		// definisce il punto di coordinate per l'icona da visualizzare
		var pt                = new google.maps.LatLng(markerObject.info.lat, markerObject.info.lng);
		// definisce l'icona da visualizzare
		var icon              = new google.maps.Icon();
		icon.image            = markerObject.info.icon;
		icon.iconSize         = new google.maps.Size(24, 24);
		icon.iconAnchor       = new google.maps.Point(12, 12);
		icon.infoWindowAnchor = new google.maps.Point(10, 10);
		// crea il marker passandogli i parametri
		var marker            = new google.maps.Marker(pt, icon);
		map.addOverlay(marker);
		// assegna il testo da visualizzare sul tooltip al passaggio del mouse sull'icona
		google.maps.Event.addListener(marker, "click", function() {
										var _html = "<center><div style=\"";
										if (tipo=="smitcam") {
											_html += "width:350px;";
										} else {
											_html += "width:250px;";
										}
										_html += "text-align:justify;\">"
											  + markerObject.info.getDescriptionWithParX()
											  + "</div></center>";
										marker.openInfoWindowHtml(_html);
									});
		marker.hide();
		return marker;
	}
	
// aggiunge marker alla mappa
	function showMarkers(arrayMarker) {
		for (var i=0; i<arrayMarker.length; i++) {
			if (arrayMarker[i].isHidden()) {
				arrayMarker[i].show();
			}
		}
	}
	
// eimina i marker dalla mappa
	function hideMarkers(arrayMarker) {
		for (var i=0; i<arrayMarker.length; i++) {
			arrayMarker[i].hide();
		}
	}
	

// metodo che aggiunge un div con link alla descrizione associata al marker	
	function addLinkToDescription(container) {
		var url    = "'./viabilita.do'";
		var params = "'act=POP_UP_ORD&idTronco=" + container.info.id +
					 "&tipoOrdinanza=" + container.info.state + "'";
		var specs  = "'left=200px,top=50px,height=400px,width=550px,resizable=yes,scrollbars=yes'";
		
		var linkText = "<div style='width:200px;'>" +
							"<a href=\"javascript:popUp(" + url + ",'Ordinanza'," + params + "," + specs + ");\">" +
							"dettagli</a>" +
						"</div>";
		container.info.setDescription(linkText,"<br/>",false);
		return container;
	}
	
// metodo che apre una nuova finestra per il popUP
	function popUp(url, name, params, specs) {
		if (params!=null){
			url = url + "?" + params;
		}
		window.open(url,name,specs);
	}
	
// inizializza i limiti della mappa entro la quale l'utente si pu� muovere
	function initLatLngBoundaries() {
		// si ricava i punti estremi della mappa
		for (var x=0; x<boundsMap.length; x++) {
			var point = boundsMap[x];
			if (parseFloat(latNE)<parseFloat(point.lat())) {
				latNE = point.lat();
			}
			if (parseFloat(lngNE)<parseFloat(point.lng())) {
				lngNE = point.lng();
			}
			if (parseFloat(latSW)>parseFloat(point.lat())) {
				latSW = point.lat();
			}
			if (parseFloat(lngSW)>parseFloat(point.lng())) {
				lngSW = point.lng();
			}
		}
	}
	

// If the map position is out of range, move it back
	function checkBounds() {
	      // Perform the check and return if OK
	      if (allowedBounds.contains(map.getCenter())) {
	        return;
	      }
	      // It`s not OK, so find the nearest allowed point and move there
	      var C = map.getCenter();
	      var X = C.lng();
	      var Y = C.lat();
	
	      var AmaxX = allowedBounds.getNorthEast().lng();
	      var AmaxY = allowedBounds.getNorthEast().lat();
	      var AminX = allowedBounds.getSouthWest().lng();
	      var AminY = allowedBounds.getSouthWest().lat();
	
	      if (X < AminX) {X = AminX;}
	      if (X > AmaxX) {X = AmaxX;}
	      if (Y < AminY) {Y = AminY;}
	      if (Y > AmaxY) {Y = AmaxY;}
	      map.setCenter(new google.maps.LatLng(Y,X));
	}

// creo l'elemento div che contiene l'etichetta
	function createDivElement(div_el, text, font, color, bgcolor, opacity, size, width, phone, link, brdcolor, fixed) {
		var div = document.createElement("div");
		var title  = "";
		var bckclr = "";
		var brdclr = "";
		var padding = "";
		if (link!=null && link!="" && link!=" ") {
			text = "<a href=\""+ link + "\"" +
				   " target=\"_blank\" style=\"text-decoration:none;color:#" + color.substr(2) +
				   ";\"><b>" + text + "</b></a>";
		}
		if (phone!=null && phone!="" && phone!=" ") {
			title = " title=\"telefono:" + phone + "\"";
		}
		if (bgcolor!=null && bgcolor!="" && bgcolor!=" ") {
			bckclr = "background-color:#" + bgcolor.substr(2) + ";";
		}
		if (brdcolor!=null && brdcolor!="" && brdcolor!=" ") {
			brdclr = "border-style:solid;border-width:1px;border-color:#" + brdcolor.substr(2) + ";";
		}
		if (!fixed) {
			padding = "padding:3px";
		}
		div.innerHTML = "<div id=\"" + div_el + "\"" + 
								title + " style=\"" + bckclr + brdclr +
								"filter:alpha(opacity=" + (opacity*100) + ");" +
								"opacity:" + opacity + ";" +
								"color:#" + color.substr(2) + ";" +
								"font-family:" + font + ";" +
								"font-size:" + size + "pt;" +
								"font-weight:bold;" +
								"width:" + width + "px;" +
								"z-index:30;float:none;left:0;top:0;display:none;position:absolute;" +
								padding +
								"\">" +
								text +
						"</div>";
		map.getPane(G_MAP_FLOAT_SHADOW_PANE).appendChild(div);
	}

// visualizza l'etichetta più vicina al centro della mappa per ogni tipologia di etichetta 
	function checkLabels() {
		var currentLevelZoom = map.getZoom();
		var visibleBounds    = map.getBounds();
		// visualizzo le etichette fisse presenti nella parte della mappa visibile
		var ks = divElementAnasFix.keySet();
		for (var x=0; x<ks.length; x++) {
			var pt = divElementAnasFix.get(ks[x]);
			if (visibleBounds.contains(pt.point) && currentLevelZoom>=pt.zoom) {
				var div        = document.getElementById(ks[x]);
				var _punto      = map.fromLatLngToDivPixel(pt.point);
				var _ways = new Array();
				_ways = pt.way.split(";");
				var _x = _punto.x;
				var _y = _punto.y;
				if (_ways[0]=="right") {
					_x = parseInt(_x) - parseInt(div_tag.style.width)-parseInt(pt.offsetX); 
				} else if (_ways[0]=="left") {
					_x = parseInt(_x) + parseInt(pt.offsetX); 
				}
				if (_ways[1]=="bottom") {
					_y = parseInt(_y) - parseInt(pt.offsetY); 
				} else if (_ways[1]=="top") {
					_y = parseInt(_y) + parseInt(pt.offsetY); 
				}
				div.style.left = _x + "px";
				div.style.top  = _y + "px";
				if (div.style.display=="none") {
					div.style.display="block";
				}
			}
		}
		
		// verifico che i punti delle label siano presenti e le visualizzo
		var keys = divElementReg.keySet();
		for (var i=0; i<keys.length; i++) {
			// recupero le informazioni e le coordinate per ogni label
			var label_div = keys[i];
			var punti = divElementReg.get(label_div);
			// verifico che almeno un punto delle coordinate sia contenuto nel 'visibleBounds'
			var present = false;
			var centro = map.getCenter();
			var point  = visibleBounds.getNorthEast();
			var indice_ok = 0;
			for (var index=0; index<punti.length; index++) {
				var sup = punti[index].point;
				if (visibleBounds.contains(sup) && currentLevelZoom>=punti[index].zoom) {
					var diffLat1 = sup.lat()-centro.lat();
					var diffLng1 = sup.lng()-centro.lng();
					var diffLat2 = point.lat()-centro.lat();
					var diffLng2 = point.lng()-centro.lng();
					if (diffLat1<0) {
						diffLat1=diffLat1*(-1);
					}
					if (diffLng1<0) {
						diffLng1=diffLng1*(-1);
					}
					if (diffLat2<0) {
						diffLat2=diffLat2*(-1);
					}
					if (diffLng2<0) {
						diffLng2=diffLng2*(-1);
					}
					if (diffLat1<diffLat2 || diffLng1<diffLng2) {
						point = sup;
						indice_ok = index;
						present = true;
					}
				}
			}
			if (present==true) {
				var punto = map.fromLatLngToDivPixel(punti[indice_ok].point);
				var div_tag = document.getElementById(label_div);
				var _ways = new Array();
				_ways = punti[indice_ok].way.split(";");
				var _x = punto.x;
				var _y = punto.y;
				if (_ways[0]=="right") {
					_x = parseInt(_x) - parseInt(div_tag.style.width)-parseInt(punti[indice_ok].offsetX); 
				} else if (_ways[0]=="left") {
					_x = parseInt(_x) + parseInt(punti[indice_ok].offsetX); 
				}
				if (_ways[1]=="bottom") {
					_y = parseInt(_y) - parseInt(punti[indice_ok].offsetY); 
				} else if (_ways[1]=="top") {
					_y = parseInt(_y) + parseInt(punti[indice_ok].offsetY); 
				}
				div_tag.style.left    = _x + "px";
				div_tag.style.top     = _y + "px";
				div_tag.style.display = "block";
			}
		}
	}

// nasconde tutte le etichette
	function hideLabels() {
		var keys = divElementReg.keySet();
		for (var x=0; x<keys.length; x++) {
			var div = document.getElementById(keys[x]);
			if (div.style.display=="block") {
				div.style.display="none";
			}
		}
		keys = divElementAnasFix.keySet();
		for (var x=0; x<keys.length; x++) {
			var div = document.getElementById(keys[x]);
			if (div.style.display=="block") {
				div.style.display="none";
			}
		}
	}

// visualizza l'etichetta più vicina al centro della mappa per ogni tipologia di etichetta 
	function showLabelAnas(obj) {
		var currentLevelZoom = map.getZoom();
		var visibleBounds    = map.getBounds();
		// verifico che i punti della label siano presenti e le visualizzo
		// recupero le informazioni e le coordinate della label predefinita
		// verifico che almeno un punto delle coordinate sia contenuto nel 'visibleBounds'	
		var lbl   =  anasPolylines.get(obj);
		var punti =  divElementAnas.get(lbl);
		//anasPolylines
		var present   = false;
		for (var index=0; index<punti.length; index++) {
			if (visibleBounds.contains(punti[index].point) && currentLevelZoom>=punti[index].zoom) {
				present = true;
			}
		}
		if (present) {
			var div_tag = document.getElementById(lbl);
			div_tag.style.left    = mouse_pos[0] + "px";
			div_tag.style.top     = mouse_pos[1] + "px";
			div_tag.style.display = "block";
		}
	}

// nasconde tutte le etichette
	function hideLabelAnas(obj) {
		var div = document.getElementById(anasPolylines.get(obj));
		if (div.style.display=="block") {
			div.style.display="none";
		}
	}

// metodo che va a creare le polylines per le etichette ANAS
	function createPolylines4Label() {
		// recupero l'insieme delle etichette
		var keys = divElementAnas.keySet();
		// per ogni etichetta creo la polyline
		var lbl              = 0;
		var arrayCoordinates = new Array();
		var polylinesVertex;
		for (var x=0; x<keys.length; x++) {
			lbl              = keys[x];
			arrayCoordinates = divElementAnas.get(lbl);
			polylinesVertex  = new Array();
			// vado a scorrere l'array di punti delle label e per recuperare le coordinate da inserire nella polyline
			for (var i=0; i<arrayCoordinates.length; i++) {
				polylinesVertex.push(arrayCoordinates[i].point);
			}
			// creo la polyline
			var polyline = new google.maps.Polyline(polylinesVertex, lineColor, lineWeight, lineOpacity);
			anasPolylines.put(polyline,lbl);
			// quando il mouse passa sopra la polyline viene visualizzata l'etichetta
			google.maps.Event.addListener(polyline, "mouseover", function() {
																	showLabelAnas(this);
																});
			// quando il mouse esce dalla polyline viene nascosta l'etichetta
			google.maps.Event.addListener(polyline, "mouseout", function() {
																	hideLabelAnas(this);
																});
			map.addOverlay(polyline);
			
		}

	}
	


/*	
	// visualizza i tronchi sulla mappa
	function showPolylineMap() {
		// la prima volta inizializzo l'array di polylines
		if (polylines==null) {
			polylines = new Array();
			for(var i=0; i<polylinesVertex.length; i++) {
				var poly = new google.maps.Polyline(polylinesVertex[i], lineColor, lineWeight, lineOpacity);
				polylines.push(poly);
				map.addOverlay(poly);
				poly.hide();
			}
		}
		// visualizzo le polylines sulla mappa
		for(var x=0; x<polylines.length; x++) {
			if (polylines[x].isHidden()) {
				polylines[x].show();
			}
		}
	}
	
	// nasconde i tronchi sulla mappa
	function hidePolylineMap() {
		if (polylines!=null && polylines.length>0) {
			for(var i=0; i<polylines.length; i++) {
				polylines[i].hide();
			}
		}
	}
*/

function initAsciiCodeMap() {
	asciiCodeMap = new Map();
	asciiCodeMap.put("&quot;","\"");
	asciiCodeMap.put("&amp;","&");
	asciiCodeMap.put("&copy;","�");
	asciiCodeMap.put("&ordf;","�");
	asciiCodeMap.put("&laquo;","�");
	asciiCodeMap.put("&raquo;","�");
	asciiCodeMap.put("&reg;","�");
	asciiCodeMap.put("&deg;","�");
	asciiCodeMap.put("&prime;","'");
	asciiCodeMap.put("&acute;","�");
	asciiCodeMap.put("&Agrave;","�");
	asciiCodeMap.put("&Aacute;","�");
	asciiCodeMap.put("&agrave;","�");
	asciiCodeMap.put("&aacute;","�");
	asciiCodeMap.put("&Egrave;","�");
	asciiCodeMap.put("&Eacute;","�");
	asciiCodeMap.put("&egrave;","�");
	asciiCodeMap.put("&eacute;","�");
	asciiCodeMap.put("&Igrave;","�");
	asciiCodeMap.put("&Iacute;","�");
	asciiCodeMap.put("&igrave;","�");
	asciiCodeMap.put("&iacute;","�");
	asciiCodeMap.put("&Ograve;","�");
	asciiCodeMap.put("&Oacute;","�");
	asciiCodeMap.put("&ograve;","�");
	asciiCodeMap.put("&oacute;","�");
	asciiCodeMap.put("&Ugrave;","�");
	asciiCodeMap.put("&Uacute;","�");
	asciiCodeMap.put("&ugrave;","�");
	asciiCodeMap.put("&uacute;","�");
	asciiCodeMap.put("<br/>","\n");
	asciiCodeMap.put("&nbsp;","\t");
	asciiCodeMap.put("&amp;","&");
}