<!-- API For integration of Google Maps in NH Web. -->
<!-- Version 0.0.3 -->

/***********************
**	FUNCIONES BÁSICAS **
************************/

// Función principal, carga el mapa y si no puede, muestra un static map.
function loadMap (idDivMap, latitude, longitude, zoom, markers, documentIdDivMap) {
	if (GBrowserIsCompatible()) {
		var objDivMap = get(idDivMap,documentIdDivMap); 
		googleMap = new GMap2(objDivMap);
		addMapControls(zoom);	
        setGeoCoordenates (latitude, longitude, zoom);
        addMarkers(markers);
	} else {
		var div = document.getElementById(idDivMap);
		div.innerHTML = '<img src="'+getURLStaticMap(latitude,longitude,zoom,div.clientWidth+'x'+div.clientHeight, null)+'"/>';
	}
}

// Función útil para las categorias especiales, recibe un rectangulo y determina el punto medio y el zoom
function loadMapWithBounds (idDivMap, markers, bounds) {
	if (GBrowserIsCompatible()) {
		var rectangle = bounds.rectangle;
		googleMap = new GMap2(document.getElementById(idDivMap));
		var centre = new GLatLng(rectangle.getCenter());
		var zoom = googleMap.getBoundsZoomLevel(rectangle);
		zoom = (zoom!=17)?zoom:zoom-1;			// Para no poner el máximo zoom (no parece necesario tanto detalle)
		addMapControls(zoom);
		setGeoCoordenates (rectangle.getCenter().lat(), rectangle.getCenter().lng(), zoom);
		addMarkers(markers);
	} else {
		var div = document.getElementById(idDivMap);
		var rectangle = bounds.rectangle;
		var latitude = rectangle.getCenter().lat();
		var longitude = rectangle.getCenter().lng();
		var zoom = 8; // pasando markers no es necesario el zoom
		div.innerHTML = '<img src="'+getURLStaticMap(latitude,longitude,zoom,div.clientWidth+'x'+div.clientHeight, null)+'"/>';
	}
}

	
function rePaintWithCities(idDivMap, countryCode, latitude, longitude, zoom, documentIdDivMap) {
	if (!markersByCountry) return;
	var markers = markersByCountry[countryCode];
	loadMap(idDivMap,latitude,longitude,zoom, markers, documentIdDivMap); 	
}

// Comprueba que el valor sea un booleano correcto
function correctBooleanData(mapBooleanControl) {
	if (mapBooleanControl!=null && mapBooleanControl==true) return true;
	return false;
}

// Comprueba que la propiedad exista
function correctObjectData(mapObjectControl) {
	if (mapObjectControl!=null) return true;
	return false;
}

// Añade todas las propiedades del objeto NHGoogleMap al mapa
function addMapControls (zoom) {
	mapObject = new NHGoogleMap(zoom);
	if (correctBooleanData(mapObject.mapTypeActive)) googleMap.addControl(new GMapTypeControl());
	if (correctBooleanData(mapObject.scaleActive)) googleMap.addControl(new GScaleControl());
	if (correctBooleanData(mapObject.mapOverviewActive)) googleMap.addControl(new GOverviewMapControl());
	if (correctBooleanData(mapObject.googleSearch)) googleMap.enableGoogleBar();
	if (correctObjectData (mapObject.mapControl)) googleMap.addControl(mapObject.mapControl);
	if (correctObjectData (mapObject.mapType)) googleMap.setMapType(mapObject.mapType);
	if (correctBooleanData(mapObject.scrollWheelZoom)) googleMap.enableScrollWheelZoom();
	if (correctBooleanData(mapObject.progressZoom)) googleMap.enableContinuousZoom();
}

// Centra el mapa en un punto
function setGeoCoordenates (latitude, longitude, zoom) {
	var point = new GLatLng(latitude, longitude);
	googleMap.setCenter(point, zoom);
}

function moveTo (latitude, longitude) {
	var point = new GLatLng(latitude, longitude);
	googleMap.panTo(point);
}

// Cambia el zoom del mapa
function changeZoom (newZoom) {
	googleMap.setZoom (newZoom);
}

// Transforma un objeto NHPoint a un string tratable por google
function transformPointToString(Point){
	return Point.country + ", " + Point.city + ", " + Point.freeText;
}         		



/*********************************
**	FUNCIONES PARA AÑADIR PINs  **
**********************************/

// Añade todos los objetos NHMarkers de un array
function addMarkers (arrayMarkers) {
	googleMap.clearOverlays();
	if (arrayMarkers!=null) {
		for (var i=0; i<arrayMarkers.length; i++){
			createMarker(arrayMarkers[i]);
		}
	}
}

// Crear un marker
function createMarker (marker) {
	var iconMarker = createIcon(marker.iconPath, marker.iconShadowPath);
	var markerOptions = { icon:iconMarker };
	var newMarker = new GMarker(new GLatLng (marker.latitude, marker.longitude), markerOptions);
	if (marker.data != ''){
		GEvent.addListener(newMarker, 'click', function() { newMarker.openInfoWindowHtml(generatePopUpInfoHotel(marker.data)); });
	} else if (marker.text != ''){
		GEvent.addListener(newMarker, 'click', function() { newMarker.openInfoWindowHtml(marker.text); });
	} // no tooltip in other case
	var zoom = googleMap.getZoom();
	GEvent.addListener(newMarker, 'infowindowclose', function() {moveTo(marker.latitude, marker.longitude);});
	googleMap.addOverlay(newMarker)
}

// Crea un icono para el marker
function createIcon (imagePath, imageShadow){
	var iconMarker = new GIcon ();
	if (imagePath != null && imagePath != ''){
		iconMarker.image = imagePath;
		iconMarker.shadow = imageShadow;
		iconMarker.iconSize = new GSize(30, 30);		// Tamaños por bbdd
		iconMarker.shadowSize = new GSize(22, 20);		// Tamaños por bbdd
		iconMarker.iconAnchor = new GPoint(6, 20);		// Tamaños por bbdd
		iconMarker.infoWindowAnchor = new GPoint(5, 1);	// Tamaños por bbdd
	} else{
		iconMarker.image = "http://#{urlTranslator.getSemanticUrlByCode('/baseDomain',locale.language)}#{requestManager.contextPath}/img/map/pinDefault.gif";
		iconMarker.shadow = '';
		iconMarker.iconSize = new GSize(15, 25);		// Tamaños por bbdd
		iconMarker.shadowSize = new GSize(22, 20);		// Tamaños por bbdd
		iconMarker.iconAnchor = new GPoint(6, 20);		// Tamaños por bbdd
		iconMarker.infoWindowAnchor = new GPoint(5, 1);	// Tamaños por bbdd
	}
	return iconMarker;
}

function generatePopUpInfoHotel(hotelData){
	var text = getGenericText();
	text = text.replace(/#\{hotelName\}/g,hotelData.name);
	text = text.replace(/#\{hotelAddress\}/g,hotelData.address);
	text = text.replace(/#\{hotelCategory\}/g,hotelData.category);
	text = text.replace(/#\{hotelPhone\}/g,hotelData.phone);
	text = text.replace(/#\{hotelPrice\}/g,hotelData.price);
	text = text.replace(/#\{hotelPriceInfo\}/g,hotelData.priceInfo);
	text = text.replace(/#\{hotelDescription\}/g,hotelData.description);
	text = text.replace(/#\{hotelImage\}/g,hotelData.image);
	text = text.replace(/#\{hotelUrl\}/g,hotelData.url);
	text = text.replace(/#\{hotelUrlReservation\}/g,hotelData.urlReservation);
	text = text.replace(/#\{roomFrom\}/g,hotelData.roomFrom);
	text = text.replace(/#\{reservation\}/g,hotelData.reservation);
	return text;
}

// This function paint the popUp
function getGenericText(){
	var text = '<div style="width:348px; padding:0; position:relative; font-size:1em; font-family:Verdana, Arial, Helvetica, sans-serif; color:#7a7a7a;">';
	text += '<div style="width:152px;float:left;margin: 0pt; padding: 0pt 10px 3px 0px; font-family: Arial,Helvetica,sans-serif; font-size: 20px; color: rgb(86, 126, 181); font-weight: bold; line-height: 1em; display: block;">#{hotelName}</div><div style="width:60px;float:left"><img style="margin-bottom:0px; border:none; vertical-align: top" src="#{hotelCategory}" width="110px" height="17px"/></div>';
	text += '<div style="clear:both; height:1px; font-size:1px; border-bottom:2px solid #b1c4e4; padding:5px 0 0 0; margin:0 0 15px 0px"></div>';
	text += '<span><a href="#{hotelUrl}"><img width="93px" height="93px" style="padding-right:18px; float:left; margin-bottom:0px; border:none" src="#{hotelImage}" alt="#{hotelName}" /></a></span>';
	text += '<div style="float:left">';
   	text += '<p style="margin:0; padding:0 0 5px 0; width:235px; color:#424245">#{hotelAddress} #{hotelPhone}</p>';
   	text += '<p style="margin:0; padding:0 0 5px 0; width:235px; color:#7a7a7a">#{roomFrom} <strong style="font-size:16px; color:#880c12; ">#{hotelPrice}</strong><br /> <span style="font-size:0.9em">#{hotelPriceInfo}</span></p>';
   	text += '<input type="button" style="margin:5px 0 0 0; padding:0px 33px 2px 6px; overflow:visible; background:#880c12 url(../../../stylesheet/gfx/btn-flecha.gif) right top no-repeat; border:none; color:#ffffff; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:1.3em; cursor:pointer" value="#{reservation}" onclick="#{hotelUrlReservation}"/>';
	text += '</div>';
	text += '<div style="display:block; clear:both; height:0px; margin-top:-2px; font-size:1px"></div>';
	text += '</div>';
	return text;
}
         		
         		
/****************************************
**	FUNCIONES PARA REALIZAR BÚSQUEDAS  **
*****************************************/     

// Inicializa el geocoder
function initGeocoder(){
	geocoder = new GClientGeocoder();
}
 
// Es el inicio de una búsqueda en la que se esperan resultados múltiples.
// Siempre se buscará por este método y en caso de tener que devolver sólo 
// 1 resultado, se cogerá el de más puntuación (el primero listado).
function searchLocations (addressPoint, queryString, allResults, styleResults, idDivResults){
	var stringAddress = transformPointToString(addressPoint);
	optionsLocation = new NHOptionsLocation(queryString, allResults, styleResults, idDivResults);
	showLocations(stringAddress);
}     

// Obtiene las localizaciones gracias al método getLocations
function showLocations (address) {
	initGeocoder();
	if (geocoder) {
		geocoder.getLocations(address, getLocations);
	}
}

// Es la función que decide si la respuesta se ha recibido bien e interactua con los resultados
function getLocations(response){
	if (response.Status.code != G_GEO_SUCCESS){
		var finalString = optionsLocation.url + '&lat=&lng=';
		document.location.href = finalString;
	} else if (response.Placemark != null && response.Placemark[0]!=null) {
		if (optionsLocation.showAll){
			var div = document.getElementById(optionsLocation.idDiv);
			for (var i=0; i<=response.Placemark.length; i++) {
				var location = new NHLocation(response.Placemark[i]);
				div.innerHtml = parse(style, location);
			}
		} else{
			var finalString = optionsLocation.url + '&lat=' + response.Placemark[0].Point.coordinates[1] + '&lng=' + response.Placemark[0].Point.coordinates[0];
			document.location.href = finalString;
		}
	} else{
		var finalString = optionsLocation.url + '&lat=&lng=';
		document.location.href = finalString;
	}
}

// Parsea el string recibido para mostrar los resultados de manera correcta.
// Sólamente es útil en el caso de que haya resultados múltiples que mostrar
// directamente por pantalla.
function parse(style, location){
	var txt = style.replace('${street}', location.street);
	var newUrl = optionsLocation.url + '&lat=' + location.latitude + '&lng=' + location.longitude;
	var txt = style.replace('${url}', newUrl);
	//...
	return txt;
}


/**************************************
**	FUNCIONES PARA CONFIGURAR RUTAS. **
***************************************/

// Dado una dirección de origen, y longitud y latitud de destino, devuelve la ruta.
function searchRouteWithPoint (addressSrc, latitudeDst, longitudeDst, language){
	var src = transformPointToString(addressSrc);
	var destination = latitudeDst + ',' + longitudeDst;
	configureRoute (addressSrc, destination, language);
}

// Busca una ruta entre un origen y un destino
function searchRoute (addressSrc, addressDst, language){
	var src = transformPointToString(addressSrc);
	var dst = transformPointToString(addressDst);
	configureRoute(src,dst,language);
}

// Es la función que realmente realiza la búsqueda.
function configureRoute(addressSrc, addressDst, language, idDivRoute) {
	var idRoute = document.getElementById(ROUTE_DIV);
	gdir = new GDirections(googleMap, idRoute);
	gdir.clear();
	idRoute.innerHTML = '';
	GEvent.addListener(gdir, "error", handleErrors);
	gdir.load("from: " + addressSrc + " to: " + addressDst, { "locale": language });
}



/*****************************************
**	FUNCIONES PARA INCLUIR STATIC MAPS  **
******************************************/

// Obtiene la URL que mostrará la imagen del mapa
function getURLStaticMap (latitude, longitude, zoom, size, markers){
	var URLStaticGoogleMap = 'http://maps.google.com/staticmap'   // parámetro
	URLStaticGoogleMap += '?center='+latitude+','+longitude;
	URLStaticGoogleMap += '&zoom='+zoom;
	URLStaticGoogleMap += '&size='+size;
	if (markers!=null){
		URLStaticGoogleMap += '&markers=' + simplifyMarkers(markers);	
	}
	URLStaticGoogleMap += '&key='+googleKey;
	return URLStaticGoogleMap;
}

// Trata el array de markers para luego crearlos
function simplifyMarkers(markers) {
	var stringMarkers = '';
	for (var i=0; i<markers.length; i++){
		stringMarkers += createStaticMarker(marker[i]);
		if (i!=markers.length-1){
			stringMarkers += '|';
		}
	}
	return stringMarkers
}	

// Crear un marker en el mapa estático
function createStaticMarker (marker) {
	return marker.latitude +','+marker.longitude+','+marker.description;
}



/***************************************
**	FUNCIONES DE TRATAMIENTO DE ERROR ** 
****************************************/

// Función que dado un error devuelve un alert indicando el problema en pantalla
function handleErrors(){
	showError(NO_RESULTS_TEXT);
	//var codeError = gdir.getStatus().code;
	//if (codeError == G_GEO_UNKNOWN_ADDRESS)
	//	alert("Address not found\nError code: " + codeError);
	//else if (codeError == G_GEO_UNAVAILABLE_ADDRESS)
	//	alert("The geocode for the given address or the route for the given directions query cannot be returned due to legal or contractual reasons.\n Error code: " + codeError);
	//else if (codeError == G_GEO_SERVER_ERROR)
	//	alert("The exact reason for the failure is not known.\n Error code: " + codeError);
	//else if (codeError == G_GEO_MISSING_QUERY)
	//	alert("No info requested.\n Error code: " + codeError);
	//else if (codeError == G_GEO_BAD_KEY)
	//	alert("Bad key. \n Error code: " + codeError);
	//else if (codeError == G_GEO_BAD_REQUEST)
	//	alert("A directions request could not be successfully parsed.\n Error code: " + codeError);
	//else if (codeError == G_GEO_UNKNOWN_DIRECTIONS)
	//	alert("There is no route available between the two points.\n Error code: " + codeError);
	//else if (codeError == G_GEO_TOO_MANY_QUERIES)
	//	alert("Too many request in too short period of time.\n Error code: " + codeError);
	//else 
	//	alert("An unknown error occurred.");
}

function showError(message) {
	var error = '<br/><table style="width:100%; border: 1px solid silver; margin: 10px 0px; background: rgb(238, 238, 238) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; border-collapse: collapse; color: rgb(0, 0, 0);">' ;
	error += '<tbody><tr><td style="padding: 4px 15px 0pt 5px; text-align:center; vertical-align: middle; width:100%"><br/><strong>' 
	error += message;
	error += '</strong><br/><br/></td></tr></tbody></table>'; 
	get(ROUTE_DIV).innerHTML = error;
}