/* Copyright 2007-2009 SCube NewMedia. */
/** ============ API ============= */

/** ============ VARIABILI ============= */
// oggetti presenti nel template
var percorso;

// struttura dati da mandare in stampa
var PrintParameters = {};
// lista delel opzioni disponibili su mappa 
var ListOption = null;

// Specifica una sequenza di azione da eseguire sui dati
var ACTION_DATA = {
	"A":{"Q":"","L":"LAYERS.ATTRATTORE_POI","C":1},
	"B":{"Q":"","L":"LAYERS.POI","C":1}
};

// Ogni posizione dell'array rappresenta un livello di zoom su mappa a cui è assegnata una azioen sui dati
var DATA_ZOOM = [
  	ACTION_DATA.A, 		// livello di zoom 0
  	ACTION_DATA.A, 		// livello di zoom 1
  	ACTION_DATA.A, 		// livello di zoom 2
 	ACTION_DATA.A, 		// livello di zoom 3
 	ACTION_DATA.A, 		// livello di zoom 4
 	ACTION_DATA.A, 		// livello di zoom 5
 	ACTION_DATA.A, 		// livello di zoom 6
 	ACTION_DATA.A, 		// livello di zoom 7
 	ACTION_DATA.A, 		// livello di zoom 8
 	ACTION_DATA.B 		// livello di zoom 9  (e tutti a seguire)
];

// stato dati attivo su mappa
var ActionDataActive = null;
// gestore mappa google
var GoogleMap = null;
// gestione evento 'zoomend'
var ListenerZoomend = null;
// zoom corrente su mappa
var CurrentZoom = 0;
// true per bloaccare il caricamento dei dati su mappa, false in caso contrario
var LockLoadData = true;
// true se siao in modalità 3D, false in caso contrario
var EarthMode = false;

/** ============ EVENTI ============= */
//gestione evento "onload"
if (window.addEventListener) {
	window.addEventListener("load", loadTemplate, false);
} else if (window.attachEvent) {
	window.attachEvent("onload", loadTemplate);
};

/**
 * Gestione evento "load".
 */
function loadTemplate() {
	// creazione mappa e gestione parti comuni
	initialize();
	
	// Creates a collapsible overview map in the corner of the screen.
	Gmap.addOverviewMapControl();
	// Creates a control with buttons to switch between map types.
	Gmap.addHierarchicalMapTypeControl();
	// Creates a drop-down map type control for switching between supported map types.
	//Gmap.addMenuMapTypeControl(); 
	// enables double click to zoom in and out (disabled by default).
	Gmap.enableDoubleClickZoom();
	// Installs keyboard event handler for the map passed as argument.
	Gmap.enableKeyboardHandler();
	// Creates a control with buttons to pan in four directions, and zoom in and zoom out, and a zoom slider.
	Gmap.addLargeMapControl();
	// Enables wheel zoom
	Gmap.enableScrollWheelZoom();
	// Enables continuous smooth zooming for select browsers (disabled by default).
	Gmap.enableContinuousZoom();

	// definizione controllo per la velina di attesa
	function LoadingControl(){}
	LoadingControl.prototype = new GControl();
	LoadingControl.prototype.initialize = function(map) {
		var loading = document.getElementById("loading");
		var parentNode = loading.parentNode;
		parentNode.removeChild(loading);
		map.getContainer().appendChild(loading);
		return loading;
	}
	LoadingControl.prototype.getDefaultPosition = function() {return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(8, 30));}
	// velina di attesa
	Gmap.addControl(new LoadingControl());
	
	// caricamento layer porgetto per definizione stili grafici 
	Gmap.getListLayerAsync(function(){});

	// caricamento contenuti confini regionali
	Gmap.showLayerAsync(/*layer*/LAYERS.BOUNDARY, /*query*/null, /*focus*/false, /*frontend*/null, function (idLayer, listObject) {
		if (listObject.length == 0) {
			// alert("Spiacenti.\nLa ricerca non ha prodotto risultati.")
		} else {
			// gestione lock del contenuto
			Gmap.lockLayer(idLayer);
		}	
	});
	
	// grafica
	percorso = document.getElementById("percorso");

	// gestione caricamento secondo parametri
	var layerByURL = ParamByURL["l"];

	// gestione caricamento informazioni a seconda dello zoom utente.
	initDataByEvent();

	// gestione categorie
	ListOption = document.getElementById("l").getElementsByTagName("input");
	for (var i = 0; i < ListOption.length; ++ i) {
		var input = ListOption[i];
		var checked = (layerByURL == input.id)
		input.checked = checked;
		input.onclick = function(){loadData(this)};
		// caricamento dati
		if (checked) {loadData(input, ParamByURL["id"])}
	}

	// settaggio posizione mappa
	Gmap.setCenter(LATITUDINE, LONGITUDINE, ZOOM);
}
/** ============ FUNZIONI ============= */
/**
 * Cancella tutti i contenuti caricati su mappa.
 */
function resetall() {
	// settaggio stato azione mappa
	ActionDataActive = null;
	
	// eliminiamo le possibnili informazioni salvate per la stampa
	clearPrint();

	
	// eliminiamo tutti i contentui caricati su mappa
	if (percorso) {percorso.style.display = "none";}
	if (ZOOM < CurrentZoom || LockLoadData == true) {Gmap.clearAll()};
	
	if (EarthMode == true) {
		 // settaggio posizione mappa
		Gmap.setCenter(LATITUDINE, LONGITUDINE);
		// gestione caricamento dati
		loadDataByZoomLevel((DATA_ZOOM.length - 1));

	} else {
		// settaggio stato
		LockLoadData = false;

		// settaggio posizione mappa
		Gmap.setCenter(LATITUDINE, LONGITUDINE, ZOOM);
	}
}
/**
 * Calcolo del percorso.
 * @param saddr indirizzo di partenza.
 * @param daddr indirizzo di arrivo.
 * @param dlatlng indirizzo di arrivo nel sistema cartografico WSG-84.
 * @param type tipologia di percorso, nel dettaglio: w=G_TRAVEL_MODE_WALKING (percorso "a pidie"), c=true (autostrade di preferenza) o c=false (alternatica alel autostrade).
 */
 function calcolaPercorso(saddr, daddr, dlatlng, type) {
	try {

		// verifichiamo che l'informazione sia valida
		if (saddr.replace(/[^A-Za-z0-9]/g,"").length == 0) {
			// gestione errore
			alert("Indirizzo di partenza non specificato");
			return false;
		}
		
		var indirizzo = daddr;

		// gestione coordinate
		if (dlatlng != null) {indirizzo = dlatlng;}
		// verifichiamo che l'informazione sia valida
		if (indirizzo.replace(/[^A-Za-z0-9]/g,"").length == 0) {
			// gestione errore
			alert("Indirizzo di arrivo non specificato");
			return false;
		}

		// opzioni di ricerca
		var option = {"getSteps":"false","locale":"IT"};
		if (type == "w") {
			option.travelMode = G_TRAVEL_MODE_WALKING;
		} else if (type == "c") {
			option.avoidHighways = "false";
		}
		
		// eliminiamo il possibile percorso (se presente) su mappa
		Gmap.removeDirection();

		// calcolo percorso
		Gmap.getDirections([saddr, indirizzo], "percorso", option, function(statusCode) {
			// gestione errore
			if (statusCode != SGEO_SUCCESS) {
				// costruzione messaggio di errore
				var message = ERROR_PATH;
				message = message.replace("ERROR_PATH_FROM", saddr);
				message = message.replace("ERROR_PATH_TO", daddr);
				
				// gestione errore
				alert(message);
	
			} else {
				// eliminiamo tutti i contentui caricati su mappa
				if (percorso) {percorso.style.display = "";}

				// salvataggio informazioni di stampa
				savePrintDirection(saddr, indirizzo, type)
				
				// settaggio stato
				LockLoadData = true;
				
				// eliminiamo i contenuti caricati
				Gmap.clear();

				// gestione categorie
				for (var i = 0; i < ListOption.length; ++ i) {ListOption[i].checked = false;}
				// settaggio stato azione mappa
				ActionDataActive = null;
			}
		});
	} catch(e) {
		toException(e);
	}
}
/** ============ BALLOON ============= */
/**
 * Calcola un percorso partendo dal balloon.
 * @param dlat latitudine del POI.
 * @param dlng longitudine del POI.
 */
function balloonPercorso(dlat, dlng) {
 	// recuperiamo i valori untente
	var balloonpercorso = document.forms["balloonpercorso"];
 	var saddr = balloonpercorso.saddr.value;
 	var daddr = document.getElementById("daddr").innerHTML;
 	var mode = balloonpercorso.mode.value;

	// esecuzione calcolo percorso
	calcolaPercorso(saddr, daddr, (dlat+","+dlng), mode);
}
/**
 * Massimizza la finestra attiva su mappa.
 */
function maximizeInfoWindow() {
	// gestione massimizzazione la finestra attiva su mappa.
	Gmap.maximizeInfoWindow();	
}
/**
 * Naviga su l'oggetto richiesto.
 * @param idPOI identificatore punto da raggiungere.
 * @param idLevel livello di appartenenza [opzionale].
 * @param bZoom true nel caso in cui si vule effetture lo zoom della mappa, false in caso contrario (false by default) [opzionale].
 * @param bSetCenter true per centrare la mappa sul POI, false in caso contrario (false by default) [opzionale].
 */
function goToPOI(idPOI, idLevel, bZoom, bSetCenter) {
	// focus su oggetto richiesto
	Gmap.setObjectFocus(idPOI, idLevel, ((bZoom == true)? 16:null), (bSetCenter == true)?true:false);
}

/** ============ DATI ============= */
/**
 * Gestione caricamento dati.
 * @param objectHTML oggetto HTML di cui si desidera gestire i contenuti.
 * @param idByURL id POI ricevuto come parametro.
 */	
function loadData(objectHTML, idByURL) {
	// eliminiamo le possibnili informazioni salvate per la stampa
	clearPrint();

	// eliminiamo il possibile percorso (se presente) su mappa
	Gmap.removeDirection();
	// eliminiamo tutti i contentui caricati su mappa
	if (percorso) {percorso.style.display = "none";}

	// recuperiamo l'identificatore del layer
	var idLayer = objectHTML.id;
	if (objectHTML.checked) {
		// attrattori culturali
		if (idLayer == LAYERS.ATTRATTORE_POI) {
			// settaggio stato
			var myZoom = ZOOM;
			if (EarthMode) {myZoom = (DATA_ZOOM.length - 1);}
			else {LockLoadData = false;}

			// settaggio posizione mappa
			Gmap.setCenter(LATITUDINE, LONGITUDINE, ZOOM);
			
			// gestione caricamento dati
			loadDataByZoomLevel(myZoom);
			
		} else {
			// caricamento contenuti layer secondo parametri
			Gmap.showLayerAsync(/*layer*/idLayer, /*query*/null, /*focus*/false, /*frontend*/null, function (idLayer, listObject) {
				if (listObject.length == 0) {
					alert("Spiacenti.\nLa ricerca non ha prodotto risultati.")
				} else {
					// settaggio focus su mappa
					if (idByURL) {Gmap.setObjectFocus(/*oggetto*/idByURL, /*layer*/idLayer, /*levelZoom*/15, /*bSetCenter*/false, /*bOpenWindow*/true, /*frontend*/null);}
					else {Gmap.setDataLoadedFocus();}
				}	
			});
		}
	
	} else {
		// attrattori culturali
		if (idLayer == LAYERS.ATTRATTORE_POI) {
			// GEvent.removeListener(ListenerZoomend);
			// settaggio stato
			LockLoadData = true;

			// eliminiamo i contenuti caricati
			Gmap.clearLayer(LAYERS.POI);
			Gmap.clearLayer(LAYERS.ATTRATTORE_POI);

			// settaggio stato azione mappa
			ActionDataActive = null;
		} else {
			// eliminiamo i contenuti caricati
			Gmap.clearLayer(idLayer);
		}
	}
}

/**
 * Gestione caricamento informazioni a seconda dello zoom utente.
 */	
function initDataByEvent() {
	// settaggio variabili
	GoogleMap = Gmap.getGoogleMap();
	CurrentZoom = GoogleMap.getZoom();

	// gestione evento 'zoomend'
	ListenerZoomend = GEvent.addListener(GoogleMap, 'zoomend', function(oldLevel, newLevel) {	
		// verifichiamo lo stato
		if (LockLoadData == true) {return;}

		// settaggio stato
		CurrentZoom = newLevel;
		// gestione temporizzazione
		window.setTimeout(function() {
			if (GoogleMap.getZoom() == CurrentZoom) {
				// gestione caricamento dati
				loadDataByZoomLevel(newLevel);
			}
		}, 800);
	});
	
	// gestione evento 'maptypechanged'
	GEvent.addListener(GoogleMap, 'maptypechanged', function() {
		if (GoogleMap.getCurrentMapType() == G_SATELLITE_3D_MAP) {
			// settaggio stato
			LockLoadData = true;
			EarthMode = true;
			
			if (Gmap.containsLayer(LAYERS.ATTRATTORE_POI)) {
				// eliminiamo i contenuti caricati
				Gmap.clearLayer(LAYERS.POI);
				Gmap.clearLayer(LAYERS.ATTRATTORE_POI);
				// gestione caricamento dati
				loadDataByZoomLevel((DATA_ZOOM.length - 1));
			}
			
		} else {
			// settaggio stato
			LockLoadData = false;
			EarthMode = false;
		}
	});
}
/**
 * Gestione caricamento informazioni a seconda del valore di zoom.
 * @param newLevel livello di zoom su mappa
 */	
function loadDataByZoomLevel(newLevel) {
	// recuperiamo l'azione legata al livello di zoom corrente
	var levelZoomAction = DATA_ZOOM[newLevel];
	if (!levelZoomAction) {levelZoomAction = DATA_ZOOM[DATA_ZOOM.length - 1]}

	// verifichiamo che sia specificata una azione e che sia differente da quella già caricata su mappa
	if (levelZoomAction && levelZoomAction != ActionDataActive) {
		// settaggio stato
		ActionDataActive = levelZoomAction;
		// eliminiamo le informazioni caricate su mappa
		if (ActionDataActive.C == 1) {
			// eliminiamo i contenuti caricati
			Gmap.clearLayer(LAYERS.POI);
			Gmap.clearLayer(LAYERS.ATTRATTORE_POI);
		}

		// costruzione query
		var query = ActionDataActive.Q;
		if (query == null || query == "undefined") {query = NO_QUERY};

		// recupero informazione layer
		var myLayer = eval(ActionDataActive.L);
		// verifichiamo che l'informazione sia valida
		if (myLayer != null && myLayer != "undefined") {
			// caricamento contenuti layer secondo parametri
			Gmap.showLayerAsync(/*layer*/myLayer, /*query*/query, /*focus*/false, /*frontend*/null, function (idLayer, listObject) {
				if (listObject.length == 0) {
					alert("Spiacenti.\nLa ricerca non ha prodotto risultati.")
				}
			});
		}
	}
}
/** ============ STAMPA ============= */
/**
 * Stampa i contenuti presenti sulla mappa.
 */
function stampa() {
 	try {

		// richiamo la pagina di stampa
		var paramURL = "";
		if (PrintParameters[PRINT_MODE] == PRINT_DIRECTION) {
			for (var key in PrintParameters) {
				paramURL += "&" + key + "=" + encodeURIComponent(PrintParameters[key]);
			}
		} else {
			paramURL = PRINT_MODE + "=" + PRINT_DATA;
			var categoryURL = "";
			var count = 0;
			for (var i = 0; i < ListOption.length; ++ i) {
				var category = ListOption[i];
				if (category.checked) {
					if (count > 0) {categoryURL += ",";}
					var idLayer = category.id;
					if (idLayer == LAYERS.ATTRATTORE_POI) {idLayer = LAYERS.POI;}
					categoryURL += "\"" + idLayer + "\"";
					count++;
				}
			}
			if (count > 0) {paramURL += "&" + PRINT_DATA_LAYER + "=[" + categoryURL + "]";}
			else {paramURL = PRINT_MODE + "=" + PRINT_GRAPHIC;}
		}

		
		window.open("stampa.html?" + paramURL, 'stampa', "height=600,width=800,menubar=yes,toolbar=yes,location=no,scrollbars=yes");
 		
 	} catch(e) {
		toException(e);
 	}
}

/**
 * Elimina le informazioni salvate per la stampa.
 */
function clearPrint() {
	PrintParameters = {};
}
/**
 * Salva le informazioni per la stampa del percorso.
 * @param saddr @see#calcolaPercorso
 * @param daddr @see#calcolaPercorso
 * @param type @see#calcolaPercorso
 */
function savePrintDirection(saddr, daddr, type) {
	// elimina le informazioni salvate per la stampa 
	clearPrint();
	
	// salvataggio stato stampa
	PrintParameters[PRINT_MODE] = PRINT_DIRECTION;
	PrintParameters[PRINT_DIRECTION_START_ADDRESS] = saddr;
	PrintParameters[PRINT_DIRECTION_END_ADDRESS] = daddr;
	PrintParameters[PRINT_DIRECTION_TYPE] = type;
}
/**
 * Salva le informazioni per la stampa dei dati.
 * @param parameters parametri da salvare.
 */
function savePrintData(parameters) {
	// elimina le informazioni salvate per la stampa 
	clearPrint();

	// salvataggio stato stampa
	PrintParameters[PRINT_MODE] = PRINT_DATA;
	for (var key in parameters) {
		PrintParameters[eval(key)] = parameters[key];
	}
}
