
//el objeto GMap2 que estamos utilizando como mapa
var map;

//el formulario que interactua con el mapa
var filterForm;

//establecemos un address y un radius que se usaran por defecto si no hay address o radius
//o si estos no dan como resultado una coordenada
var defaultAddress = "Costa del Sol, Malaga";
var defaultRadius = 60;

//variable global que almacena el json con los markers que devuelve el servidor
var markers;

//variable global que almacena el json con la "cuenta" de markers que ha devuelto el servidor
var countMarkers;

//variable que contiene la fecha de la consulta, esto es para que cuando se introduzca una fecha que ya ha pasado asigne la actual
var fechaConsulta;

//variable que almacenara un timeout para que no se ejecuten muchas peticiones ajax en un corto periodo tiempo
var updateMarkersTimeOut;

//variable global que contendra una instancia de un geocoder de google para hacer geolocalizacion inversa.
var geocoder;

//variable que almacena el precio maximo que se quiere tener.
var maxPrice;

//variable que indica si se esta llamando desde facebook. Esto se hace con el parametro fb=1
var esFacebook;


//variable que utilizo para que los elementos de cada grupo esten a un z-level distinto.
//por defecto google pone los overlays mas al sur para que esten a un z-level superior (encima)
//yo quiero que los grupos vayan estando por capas, de manera que el primero que se anade
//este mas abajo y los grupos siguientes encima.
//para ello, vario este z_index_correction multiplicandolo x 10 con cada grupo que se anade
var z_index_correction = 1;


//funcion para hacer un log debug
log = function(msg){
    debug = false;//cambiar a false para anular mensajes de debugging
    if(debug){
        if(typeof console == "undefined"){
            window.alert(msg);
        } else {
            console.log(msg);
        }
    }
}


/**
* Establece y devuelve la infowindow y el contenido segun el json de un marker
*/
function getInfoWindow(markerJson){
	var marker = {};

	//voy a montar html a mano:

	marker.infoWindowHtml = '<div id="infowindow">';

	if(markerJson.url){
	   marker.infoWindowHtml += '<h2 id="infowindow-header"><a href="' + markerJson.url + '">' + markerJson.name + '</a></h2>';
	} else {
	   marker.infoWindowHtml += '<h5 id="infowindow-header">' + markerJson.name + '</h5>';
	}

	if(markerJson.description)
    	marker.infoWindowHtml += '<p id="infowindow-desc">' + markerJson.description + '</p>';

    if($("#show-prices").is(":checked")){
    	var tmp;
        if(!markerJson._otherData.vendemos){
    	    tmp = localizedStrings.noSelling;
    	}

    	else if(markerJson._otherData.bestPrice && markerJson._otherData.bestPrice.precioporpersona){
			if(markerJson._otherData.bestPrice.buggy=='Y') tmp = localizedStrings.sellingWithPriceWithBuggy;
    	    else tmp = localizedStrings.sellingWithPrice;
    	    tmp = tmp.replace(/%%desde%%/, markerJson._otherData.bestPrice.desde);
    	    tmp = tmp.replace(/%%pax%%/, markerJson._otherData.bestPrice.pax);
    	    tmp = tmp.replace(/%%precio%%/, markerJson._otherData.bestPrice.precioporpersona);
    	    tmp = tmp.replace(/%%nombre_producto%%/, markerJson._otherData.bestPrice.nombre_producto);
        }

        else{
            tmp = localizedStrings.sellingWithoutPrice;
        }

        marker.infoWindowHtml += '<p id="infowindow-selling">' + tmp + '</p>';
   }


    marker.infoWindowHtml += '<p id="infowindow-links">';

    if(markerJson.url)
	  if(esFacebook) marker.infoWindowHtml += '<a href="' + markerJson.url + '" target=\'_blank\'>' + localizedStrings.moreDetails + '</a>';
	  else marker.infoWindowHtml += '<a href="' + markerJson.url + '">' + localizedStrings.moreDetails + '</a>';

    if(markerJson._otherData.vendemos){
		markerJson._otherData.url_vendemos='/scripts/res/?package=1000&id_campo='+markerJson.id_entity;
		if(markerJson._otherData.bestPrice) markerJson._otherData.url_vendemos+='&date='+encodeURIComponent(fechaConsulta);
		if(esFacebook) marker.infoWindowHtml += ' | <a href="' + markerJson._otherData.url_vendemos + '" target=\'_blank\'>' + localizedStrings.reserve + '</a>';
	    else marker.infoWindowHtml += ' | <a href="' + markerJson._otherData.url_vendemos + '">' + localizedStrings.reserve + '</a>';
	}

	marker.infoWindowHtml += '</p>';


	marker.infoWindowHtml += '</div>';

	return marker.infoWindowHtml;
}


/**
* Funcion que dibuja un circle en el mapa, dado una lat y lng que hace de centro
* y un radio dado en kms.
**/
function drawCircle(lat, lng, radius)
{
   lat = parseFloat(lat);
   lng = parseFloat(lng);
   radius = parseFloat(radius);


   var d2r = Math.PI / 180; // degrees to radians
   var r2d = 180 / Math.PI; //radians to degrees
   var earthsradius = 6371.0 //radio de la tierra en kms.
   var points = 35; //puntos que vamos a utilizar para dibujar el circulo


   // find the raidus in lat/lon
   var rlat = (radius / earthsradius) * r2d;
   var rlng = rlat / Math.cos(lat * d2r);

   var extp = new Array();
   for (var i=0; i < points+1; i++) // one extra here makes sure we connect the
   {
      var theta = Math.PI * (i / (points/2));
      ex = lng + (rlng * Math.cos(theta)); // center a + radius x * cos(theta)
      ey = lat + (rlat * Math.sin(theta)); // center b + radius y * sin(theta)
      extp.push(new GPoint(ex, ey));
   }

  //map.addOverlay(new GPolyline(extp, "#000000", 5, 0.5));
  circle = new GPolygon(extp,"#000000",2, 0.3,"#FFFFFF", 0.3);
  //map.addOverlay(circle);//NO LO VAMOS A DIBUJAR

  return (circle);

}



/**
* Anade un marker al mapa y establece sus eventos, etc.
* grupoZIndex es el grupo al que pertenece el marker, que voy a utilizar
* para calcular un z-index personalizado que me permita que los campos
* esten siempre por encima de los hoteles.
*/
function addMarker(markerJson) {

	var customIcon = new GIcon(G_DEFAULT_ICON);
    //customIcon.image = (markerJson.icon) ? markerJson.icon : "/admin/templates/js/marker-green.png";
    //customIcon.image = (markerJson.icon.image) ? markerJson.icon.image : "/admin/templates/js/marker-green.png";

     if(markerJson.icon){
		var rutaIcono="\/scripts\/maps\/markers\/golfinspain-4\/"; // anado la ruta de modo estatico.
		if(markerJson.cluster == true){
			markerJson.icon.image='numbered_cluster.php?img=golf_cluster.png';
			markerJson.icon.image+='&text='+markerJson._otherData.clusteredMarkers.length;
			markerJson.icon.image+='&color=CDD9B3';
			//if(markerJson._otherData.bestPrice && markerJson._otherData.bestPrice.preciogis) markerJson.icon.image+='&text'+markerJson._otherData.bestPrice.preciogis;
        	customIcon.image = rutaIcono+markerJson.icon.image;
        	//customIcon.shadow = rutaIcono+'golf_selling.png';
		}else if(markerJson._otherData.vendemos){
			markerJson.icon.image='numbered_marker.php?';
			if(markerJson._otherData.bestPrice && markerJson._otherData.bestPrice.buggy == 'Y') markerJson.icon.image+='img=golf_selling_buggy.png';
			else if(maxPrice && markerJson._otherData.bestPrice && Math.round(markerJson._otherData.bestPrice.precioporpersona)>maxPrice){
				markerJson.icon.image+='img=golf_selling_no_max_price.png';
			}
			else markerJson.icon.image+='img=golf_selling.png';
			if(markerJson._otherData.bestPrice && markerJson._otherData.bestPrice.precioporpersona) markerJson.icon.image+='&text='+Math.round(markerJson._otherData.bestPrice.precioporpersona);
			else if(markerJson._otherData.bestPrice === null) {
				 markerJson.icon.image+='&text=?';
			}
			markerJson.icon.image+='&color=ffffff';
			
        	customIcon.image = rutaIcono+markerJson.icon.image;
        	customIcon.shadow = rutaIcono+'selling_shadow.png';
		}
		else{
			customIcon.image = rutaIcono+'golf_no_selling.png';
			customIcon.shadow = rutaIcono+'no_selling_shadow.png';
		}
        customIcon.iconSize = new GSize(markerJson.icon.iconSize.width, markerJson.icon.iconSize.height);
        if(markerJson.icon.shadowSize) customIcon.shadowSize = new GSize(markerJson.icon.shadowSize.width, markerJson.icon.shadowSize.height);
        customIcon.iconAnchor = new GPoint(markerJson.icon.iconAnchor.x, markerJson.icon.iconAnchor.y);
        customIcon.infoWindowAnchor = new GPoint(markerJson.icon.infoWindowAnchor.x, markerJson.icon.infoWindowAnchor.y);
        customIcon.imageMap = markerJson.icon.imageMap;
    }


	var title = (markerJson.cluster == true)
	             ? localizedStrings.clusterLabel.replace(/%%numcampos%%/, markerJson._otherData.clusteredMarkers.length)
	             : markerJson.name;
	var markerOptions = {draggable:false,
	                     icon:customIcon
	                     //title:title
	                     /*descomentar esto para que funcione la correccion del zIndex,
	                     zIndexProcess:function(){
	                         z_index = Math.abs(GOverlay.getZIndex(markerJson.lat) * z_index_correction);
	                         return z_index;
	                     }*/};

	var marker = new GMarker(new GLatLng(markerJson.lat, markerJson.lng), markerOptions);
	var tooltip = new Tooltip(marker, title, 2);
	marker.tooltip = tooltip;
	//map.currentMarker = marker;//hacemos que el currentMarker sea el actual

	if(markerJson.cluster == true){
		GEvent.addListener(marker, 'click',
			   function() {

					var clusterBounds = new GLatLngBounds(new GLatLng(markerJson.swlat, markerJson.swlng), new GLatLng(markerJson.nelat, markerJson.nelng));

					log("centering in " + clusterBounds.getCenter() + " a un zoom de " + map.getBoundsZoomLevel(clusterBounds) + " click en cluster");
					map.setCenter(clusterBounds.getCenter(), map.getBoundsZoomLevel(clusterBounds));


			   }
		);


	} else {

		GEvent.addListener(marker, 'click',
			   function() {
					marker.infoWindowHtml = getInfoWindow(markerJson);
					marker.openInfoWindowHtml(marker.infoWindowHtml, {maxWidth:300});
					map.currentMarker = marker;

					//guardamos los bounds del mapa en una variable,
					//para comprobar posteriormente, cuando se cierre la ventana, que
					//si ha habido un desplazamiento del mapa para mostrar la infowindow
					//y si lo ha habido, hacer una update de los markers
					map.boundsWhenMarkerClicked = map.getBounds();
			   }
		);


		GEvent.addListener(marker, 'infowindowopen', function(){
		    marker.noTooltip = true;
		    marker.tooltip.hide();
		});


		//Al cerrar la ventana, comprobamos los bounds actuales del mapa
		//con los que guardamos al hacer click sobre el marker
		//y si no son los mismos, ha habido desplazamiento, entonces
		//hacempso un update de los markers ya que las nuevos bounds del mapa
		//pueden incluir nuevos markers y clusters
		GEvent.addListener(marker, 'infowindowclose',
            function(){
                marker.noTooltip = false;

                if(!map.boundsWhenMarkerClicked.equals(map.getBounds())){
                    updateMarkersWithDelay();
                }

                map.boundsWhenMarkerClicked = null;
            }
		);
	}


	//tanto para los cluster como para los markers, mostraremos el tooltip
	//mostrar tooltip
	GEvent.addListener(marker,'mouseover',function(){
	    if(!marker.noTooltip){
	       marker.tooltip.show();
	       setTimeout(function() {marker.tooltip.hide()}, 2000);
	    }

	});


	GEvent.addListener(marker,'mouseout',function(){
	    marker.tooltip.hide();
	});




	map.addOverlay(marker);
	map.addOverlay(tooltip);
	marker.data = markerJson;

	return marker;
}


/**
* Actualiza el mapa anadiendo los markers que ha devuelto el servidor despues de un update
*/
function refreshMap(){

    log("refreshMap()");
    log("hay " + countMarkers.total + " markers.");

    map.clearOverlays();//limpiamos los markers que hubiera

    //dibujamos un circulo que represente el circulo en el que estamos centrados
    //siempre que tengamos los datos necesarios para dibujarlo
    /*log("refLat: " + filterForm.refLat.value);
    log("refLng: " + filterForm.refLng.value);
    log("radius: " + filterForm.radius.value);
    log("address: " + filterForm.address.value);
    if(filterForm.refLat.value && filterForm.refLng.value && filterForm.radius.value && filterForm.address.value){
        log("se debe haber dibujado un circulo");
        var circle = drawCircle(filterForm.refLat.value, filterForm.refLng.value, filterForm.radius.value);
    } else {
        log("no se dibuja circulo");
    }*/



    //para calcular los limites necesarios para el mapa,
    //de manera que quepan todos en el area seleccionada.
    var latlngbounds = new GLatLngBounds( );

    if(markers != undefined && countMarkers.total > 0){
       for (j in markers){
			var grupo = markers[j];
			for(m in grupo){
				var currentMarker = grupo[m];
				var latLngTmp = new GLatLng(currentMarker.lat, currentMarker.lng);
				latlngbounds.extend( latLngTmp);
                addMarker(currentMarker); //paso j para utilizarlo en el calculo de un z-index por grupo personalizado
			}

			//modifico el z-index, para que el siguiente grupo este por encima en el z-index
			z_index_correction = z_index_correction * 10;
		}

		log("se han pintado los markers");

    }

    //Siempre que llego aqui, el mapa se ha inicializado - o cambiado su posicion
    //asi que guardo el zoom y el center actual para futuras referencias
    filterForm.z.value = map.getZoom();
    filterForm.center.value = map.getCenter().toUrlValue();
    filterForm.province_bak.value = filterForm.province.value;
    log("z y center actualizados");
	
	UpdateLink();


    //actualizamos la informacion de los resultados, para mostrar el numero total de markers
    var countGolf = (countMarkers.byGroup[2]) ? countMarkers.byGroup[2] : 0;
	var countHotels = (countMarkers.byGroup[1]) ? countMarkers.byGroup[1] : 0;
	$("#golf-from-date").val(fechaConsulta);
    $("#markers-count").html(countGolf)
    .effect("pulsate", {times:1}, 700);

    //escondemos el bloque de "updating-indicator".
    $("#updating-map-indicator").hide();

	//usando jbind plugin de jquer, pintamos un template con los campos y los hoteles devueltos por json
    $('#show-lists').empty();

    if(countMarkers.byGroup[2] > 0){
        //vamos a utilizar para montar el template tanto los markers como los clustered markers
        var todosMarkers = [];
        for(prop in markers[2]){
           var marker = markers[2][prop];
           if(marker.cluster == true){
                for(prop2 in marker._otherData.clusteredMarkers){
                    var clusterMarker = marker._otherData.clusteredMarkers[prop2];

                    var tmp = {
                       name:clusterMarker.name,
                       url:clusterMarker.url,
                       ciudad:clusterMarker._otherData.ciudad,
                       provincia:clusterMarker._otherData.provincia
                    };

                    if(clusterMarker._otherData.vendemos){
                        if(esFacebook) tmp.vendemos =  '<a href="' + clusterMarker._otherData.url_vendemos + '" target=\'_blank\'>';
						else tmp.vendemos =  '<a href="' + clusterMarker._otherData.url_vendemos + '">';
                        tmp.vendemos += '<img src="/iconweb/gfs_mini_Y.gif" border="0">';
                        tmp.vendemos += '</a>';

                        if($("#show-prices").is(":checked")){
                            if(clusterMarker._otherData.bestPrice && parseFloat(clusterMarker._otherData.bestPrice.precioporpersona) > 0){
                                if(esFacebook) tmp.precioporpersona = '<a href="' + clusterMarker._otherData.url_vendemos + '" target=\'_blank\'>';
								else tmp.precioporpersona = '<a href="' + clusterMarker._otherData.url_vendemos + '">';
                                tmp.precioporpersona += clusterMarker._otherData.bestPrice.precioporpersona + '&euro;';
                                tmp.precioporpersona += '</a>';
                                if($("#show-prices").is(":checked")
                                   && parseFloat(clusterMarker._otherData.bestPrice.precioporpersona) > parseFloat($("#maxprice").val())
                                ){
                                    tmp.rowclass = "pricehigher";
                                }
                            } else {
                                tmp.precioporpersona = '<a href="' + clusterMarker._otherData.url_vendemos + '">';
                                tmp.precioporpersona += '?';
                                tmp.precioporpersona += '</a>';
                            }
                        } else {
                            tmp.precioporpersona = '';
                        }

                    } else {
                        tmp.vendemos = '';
                        tmp.precioporpersona = '';
                    }

                    if(!tmp.rowclass)
                        tmp.rowclass = "normal";
                    todosMarkers.push(tmp);
                }
            } else {

                var tmp = {
                   name:marker.name,
                   url:marker.url,
                   ciudad:marker._otherData.ciudad,
                   provincia:marker._otherData.provincia
                };

                if(marker._otherData.vendemos){
                    tmp.vendemos =  '<a href="' + marker._otherData.url_vendemos + '">';
                    tmp.vendemos += '<img src="/iconweb/gfs_mini_Y.gif" border="0">';
                    tmp.vendemos += '</a>';

                    if($("#show-prices").is(":checked")){
                        if(marker._otherData.bestPrice && parseFloat(marker._otherData.bestPrice.precioporpersona) > 0){
                            tmp.precioporpersona = '<a href="' + marker._otherData.url_vendemos + '">';
                            tmp.precioporpersona += marker._otherData.bestPrice.precioporpersona + '&euro;';
                            tmp.precioporpersona += '</a>';
                            if($("#show-prices").is(":checked")
                               && parseFloat(marker._otherData.bestPrice.precioporpersona) > parseFloat($("#maxprice").val())
                            ){
                                tmp.rowclass = "pricehigher";
                             }
                        } else {
                            tmp.precioporpersona = '<a href="' + marker._otherData.url_vendemos + '">';
                            tmp.precioporpersona += '?';
                            tmp.precioporpersona += '</a>';
                        }
                    } else {
                        tmp.precioporpersona = '';
                    }

                } else {
                    tmp.vendemos = '';
                    tmp.precioporpersona = '';
                }

                 if(!tmp.rowclass)
                    tmp.rowclass = "normal";
                todosMarkers.push(tmp);
            }
        }


        //ordenamos todos markers segun el campo que hayamos decidido
       todosMarkers.sort(function(a,b){
            var orderBy = "name";
            var al = a[orderBy];
            var bl = b[orderBy];

            if(al == bl)
                return 0;
            else
                return (al > bl) ? 1 : -1;
        });


        log(todosMarkers);

        var template = $('#template-campos-table').html();
        var nodeCampos = $(template).bindTo(todosMarkers,{root:'root'});
        $(nodeCampos).appendTo('#show-lists');
    }

    if(countMarkers.byGroup[1] > 0){
        var template = $('#template-hotels').html();
        var nodeHotels = $(template).bindTo(markers,{root:'root'});
        $(nodeHotels).appendTo('#show-lists');
    }


}

/**
* Funcion que lanza el updateMarkers por AJAX con un pequeno delay
* por si se producen nuevas peticiones en ese intervalo de tiempo
* que solo la ultima tenga lugar
**/
function updateMarkersWithDelay(){
    //neutralizamos el anterior timeout si lo hubiera
    if(updateMarkersTimeOut)
        clearTimeout(updateMarkersTimeOut);

    //y establecemos el nuevo
    updateMarkersTimeOut = setTimeout("updateMarkers();", 500);
}


/**
* Funcion que envia una peticion al servidor para que le devuelva markers
* segun los bounds y zoom del mapa, asi como los datos del formulario relacionado
* al devolver respuesta el servidor, se hace un refreshMap
**/
function updateMarkers(){

    //siempre que haya un updateMarkers, nos aseguramos que el panel de resultados
    //como lista se cierra:
    /*if($("#show-lists").is(":show")){
        $("#show-lists").slideUp("slow", function(){
           $("#slideUpDown").html("open");
        });
        $("#slideUpDown").animate({top:"0px"},"slow");
    }*/



    var params = {};//parametros que vamos a enviar en el $_GET de la peticion AJAX

    //anadmos a params todos los datos del form
    //cogemos los datos del filterForm para aplicarselos al mapa
    for (h=0;h<filterForm.elements.length;h++){
		if(filterForm.elements[h].value && filterForm.elements[h].name){//solo los inputs.
			var formElement = filterForm.elements[h];
			if(formElement.type == 'checkbox' || formElement.type == 'radio'){
				if(formElement.checked)
					params[formElement.name]= (formElement.name + '=' + escape(formElement.value));
			} else {
				params[formElement.name] = (formElement.name + '=' + escape(formElement.value));
			}
		}

	}

	 //quitamos los params innecesarios:
    delete params.address;
    delete params.province;
    delete params.refLat;
    delete params.refLng;
    delete params.radius;


    //----
    //Vamos a convertirlo en un mapa que se comporte siempre igual:
    //nos centramos en un area (geolocalizada) o bien en un center previamente definido
    //siempre vamos a pasar los parametros sw, ne y no los refLat, refLng ni radius;
    // Resolver los siguientes casos:
    // 1.- cuando entramos la primera vez en el mapa, necesitamos inicializarlo, centrandonos en un area, dado un radio.
    // por ello, si no tenemos address y/o radius, tenemos que asignar uno por defecto
    // con ese address y radius calculamos el circle, y por ende el center del mapa (con sus bounds, y por tanto sw y ne)
    // 2.- cuando volvemos a un mapa que tiene un center y un z guardaddos previamente, nos centramos en esa zona:
    // y ya tendremos los bounds (sw y ne)

    //El mapa al llegar aqui estara inicializado
    //asi que lanzamos la consulta, calculando los sw, ne necesarios para el boundary

	var zoom = map.getZoom();
    var bounds = map.getBounds();
	var sw = bounds.getSouthWest();
	var ne = bounds.getNorthEast();

	params.sw = "sw=" + sw.toUrlValue();
	params.ne = "ne=" + ne.toUrlValue();
	params.z = "z=" + zoom;


    var getVars = '';
	for(prop in params){
	    if(params[prop])
	       getVars += params[prop] + "&";
	}

    getVars = '?' + getVars;
	

	var url = '/scripts/maps/index.php' + getVars;


	log("pedimos los markers a : " + url);
	//mostramos el "updating-indicator
    $("#updating-map-indicator").show();

	//obtenemos los markers por ajax - json
	GDownloadUrl(url, function(response, httpStatus){
		if(httpStatus == 200){
			json = eval("("+response+")");
			markers = json.markers;
			countMarkers = json.countMarkers;
			fechaConsulta = json.fechaConsulta;
			maxPrice = json.maxPrice;
			if(document.URL.indexOf('fb=1')>-1){
				esFacebook = true;
			}
		}

		//ahora que tenemos markers, hacemos un refreshMap() para redibujar los markers
		//devueltos por el server
		refreshMap();

		if(!map.zoomendListener){
    		map.zoomendListener = GEvent.addListener(map, 'zoomend', function(zoomLevelOld, zoomLevelNew){
    		    updateMarkersWithDelay();
        	});
		}

        if(!map.dragendListener){
        	map.dragendListener = GEvent.addListener(map, 'dragend', function(){
        	    updateMarkersWithDelay();
        	});
        }

        //ya podemos inicializar el checkbox que estara disabled al empezar
		$("#show-prices").removeAttr("disabled");
		if($("#show-prices").is(":checked")){
		    //eah!. parche pal explorer que no admite table-cell como valor de display
		    var displayValue = ($.browser.msie == true) ? "inline-block" : "table-cell";
		    $(".price-related").css("display", displayValue);
		    $("#legend-icons-price-related").css("display", "inline");
//		    $(".price-related").show();
		}
	});

}


function UpdateLink()
{
	 // funcion igual que UpdateMarkers salvo que esta solo se utiliza para actualizar el enlace
	 // Se hace aparte, ya que no se ejecutan al mismo tiempo. Si lo hiciera no se actualizaria bien.



    var params = {};//parametros que vamos a enviar en el $_GET de la peticion AJAX

    //anadmos a params todos los datos del form
    //cogemos los datos del filterForm para aplicarselos al mapa
    for (h=0;h<filterForm.elements.length;h++){
		if(filterForm.elements[h].value && filterForm.elements[h].name){//solo los inputs.
			var formElement = filterForm.elements[h];
			if(formElement.type == 'checkbox' || formElement.type == 'radio'){
				if(formElement.checked)
					params[formElement.name]= (formElement.name + '=' + escape(formElement.value));
			} else {
				params[formElement.name] = (formElement.name + '=' + escape(formElement.value));
			}
		}

	}

	 //quitamos los params innecesarios:
    delete params.address;
    //delete params.province;
    delete params.refLat;
    delete params.refLng;
    delete params.radius;
	delete params.province_bak;


    //----
    //Vamos a convertirlo en un mapa que se comporte siempre igual:
    //nos centramos en un area (geolocalizada) o bien en un center previamente definido
    //siempre vamos a pasar los parametros sw, ne y no los refLat, refLng ni radius;
    // Resolver los siguientes casos:
    // 1.- cuando entramos la primera vez en el mapa, necesitamos inicializarlo, centrandonos en un area, dado un radio.
    // por ello, si no tenemos address y/o radius, tenemos que asignar uno por defecto
    // con ese address y radius calculamos el circle, y por ende el center del mapa (con sus bounds, y por tanto sw y ne)
    // 2.- cuando volvemos a un mapa que tiene un center y un z guardaddos previamente, nos centramos en esa zona:
    // y ya tendremos los bounds (sw y ne)

    //El mapa al llegar aqui estara inicializado
    //asi que lanzamos la consulta, calculando los sw, ne necesarios para el boundary

	var zoom = map.getZoom();
    var bounds = map.getBounds();
	var sw = bounds.getSouthWest();
	var ne = bounds.getNorthEast();

	params.sw = "sw=" + sw.toUrlValue();
	params.ne = "ne=" + ne.toUrlValue();
	params.z = "z=" + zoom;


    var getVars = '';
	for(prop in params){
	    if(params[prop])
	       getVars += params[prop] + "&";
	}

    getVars = '?' + getVars;
	
	if(document.ampliar) getVars = getVars + 'ampliar=1';
	
	/*
	if(document.URL.indexOf('fb=1')>-1) alert("Es facebook");
	else alert("No es facebook");
	*/
	
	//var enlace=document.getElementById('enlace');
	
	$('#enlace').attr('href', getVars);
}



/**
* Funcion que inicializa el mapa
* containerId: Id del bloque que contendra el mapa
* formFiltersId: Id del formulario que interactua con el mapa
* por defecto, si no se pasan a false estos parametros, habra un AJAX update de los markers en ambos eventos
**/
function initMap(containerId, formFiltersId)
{
	if (GBrowserIsCompatible()) {

	        map = new GMap2(document.getElementById(containerId));

			if(formFiltersId){
				filterForm = document.getElementById(formFiltersId);
				filterForm.onsubmit = function(){
				    return false;
				}

				//utilizo selectores de jQuery para aplicar el change
				//a todos los elementos del form, ya que onchange aplicado a un form
				//no funciona en IE. Se ha de aplicar a sus hijos

				//al inicializar el mapa, nos aseguramos de establecer el valor
                //de province al que teniamos antes de irnos en province_bak, si lo hubiera
                if(filterForm.province_bak.value)
                    $("#province").val(filterForm.province_bak.value);

				// Autocomplete 2
               //http://docs.jquery.com/Plugins/Autocomplete
               $("#province").autocomplete(
                    '/scripts/maps/index.php?a=searchGolfByMapAutocomplete',
                    {
                        formatItem: function(item){
                            return item[0];
                        },
                        minChars:3,
                        selectFirst:false
                    }
               );
               $('#province').result(function(event, item, formatted) {
					var address;
                    var radius;
                    if(item){
                        //hay matching con un elemento de la lista

                        //Si el item tiene lat y lng la aplicamos
                        var lat = item[5];
                        var lng = item[6];
                        if(lat && lng){
                            address = lat + "," + lng;
                        } else {
                           var addressParts = [];
                            for(i=2;i<=3;i++){
                                if(item[i])
                                    addressParts.push(item[i]);
                            }
                            address = (addressParts.length > 0) ? addressParts.join(", ") : formatted;
							// JOSE: Se ha anadido spain a las busquedas que no tienen lat y lng
							// y coincida con algun valor del autocompletar.
							// para en caso de haber otra region llamada igual en otra parte del
							// mundo, salga la que es spain.
                        }
                        radius = item[4];
                    } else {
                        //NO hay matching
                        address =  $(this).val();
                        radius = defaultRadius;
                    }
                    //comprobamos si tenemos que lanzar el evento de change
                    if(address != $("#address").val()){
						$("#address").val(address);
                        $("#radius").val(radius);
                        $("#address").trigger("change");
                        $("#province").blur();
                    }



                });
               
			   // al pulsar enter, quita el foco y envia
				$('#province').bind('keypress', function(e) {
									if(e.keyCode==13) 
                        $("#province").blur();																	 
									});
				
				//cuando salgo del campo fuerzo un search
				$('#province').blur(function(){
							// cambio en el comportamiento de blur
							// que hacia que al cliquear estando
							// seleccionado un elemento del autocompletar
							// buscara lo que habia en la barra y no
							// el elemento.
							
							// Hay una clase en ac_result (elemento de autocompletar)
							// y si esta contiene la clase ac_over (hay elemento seleccionado)
							// no deberia buscar, en caso contrario si.
							 if($(".ac_results").html()==null)
							 {
								 var ac_result_valor=-1;
							 }
							 else var ac_result_valor=parseInt($(".ac_results").html().indexOf('ac_over'));
							 if(ac_result_valor<0) $(this).search();
							 });
				
				
				

				$("#radius, #address").bind("change", function(){
                   log("change que implica centrar en address");
                   geocoder.centerInAddress();
				});
				

				$("#golf-from-date, #golf-to-date, #pax, #maxprice, #pref-buggy").bind("change", function(){
                    log("change que NO implica centrar");
				   updateMarkers();
				});



				//en IE un checkbox, o un radio, hasta que no pierde el focus
				//no cambia, por lo que mejor utilizamos el evento click
				//para que el cambio sea inmediato.
				$("#golf-courses, #hotels").bind("click", function(){
				    updateMarkers();
				});
				


				//show-prices
                $("#show-prices").bind("click", function(e){
                    if($(this).is(':checked')){
                       //eah!. parche pal explorer que no admite table-cell como valor de display
            		    var displayValue = ($.browser.msie == true) ? "inline-block" : "table-cell";
            		    $(".price-related").css("display", displayValue);
            		    $("#legend-icons-price-related").css("display", "inline");
//		                $(".price-related").show();
                        $(this).blur();
                        updateMarkers();
                    } else {
                       $(".price-related").css("display", "none");
                       $("#legend-icons-price-related").css("display", "none");
//                        $(".price-related").hide();
                        $(this).blur();
                        updateMarkers();
                    }
                });


			   }

			


			map.disableDoubleClickZoom();
			map.enableScrollWheelZoom();//habilitar zoom in - out con la rueda del raton
			map.addMapType(G_PHYSICAL_MAP);
			map.addControl(new GMenuMapTypeControl());
			map.addControl(new GLargeMapControl());
            map.setMapType(G_PHYSICAL_MAP);



			//instanciamos un geocoder para geolocalizacion inversa
			geocoder = new GClientGeocoder();

			//esta funcion obtendra un latLng, para un address y dado un radio.
			//una vez obtenida las coordenadas, centrara el mapa en esa zona
			//y lanzara el updateMarkers para obtener los markers de esa zona
			geocoder.centerInAddress = function () {
			    //address pueden ser un par de coordenadas en cuyo caso no hacemos geocoding
			    var coords = (!map.isLoaded() && filterForm.center.value)
			         ? filterForm.center.value.split(",")
			         : filterForm.address.value.split(",");
			    var lat;
			    var lng;
			    if(coords.length === 2){
                    lat = parseFloat(coords[0]);
                    lng = parseFloat(coords[1]);
			    }
			    if(lat && lng){
					var point = new GLatLng(lat, lng);

			        //eliminamos temporalmente los listeners de zoom y drag
				    //ya que al centrar el mapa se podrian disparar
				    //y volver a lanzar el evento de update.
				    //posteriormente los anadiremos de nuevo
				    if(map.dragendListener){
    			        GEvent.removeListener(map.dragendListener);
    			        map.dragendListener = null;
    			    }

    			    if(map.zoomendListener){
    			        GEvent.removeListener(map.zoomendListener);
    			        map.zoomendListener = null;
    			    }


				   //obtenemos el circle correspondiente y centramos el mapa en ese
				   //area.
				   var circle = drawCircle(point.lat(), point.lng(), filterForm.radius.value);
                   var zoom = (!map.isLoaded() && filterForm.z.value)
                        ? parseFloat(filterForm.z.value)
                        : map.getBoundsZoomLevel(circle.getBounds());
                   var center = circle.getBounds().getCenter();
                   map.setCenter(center, zoom);
                   updateMarkers();
                   return point;

			    }
			    this.getLatLng(
				  filterForm.address.value+',spain',
				  function(point) {
					//si no se devuelven coordenadas, entonces invocamos recursivamente
					//a la funcion, con los datos por defecto, que deben devolver coordenadas
				    if (!point) {
					   if(map.isLoaded() != true){
				           filterForm.address.value = defaultAddress;
					       filterForm.province.value = defaultAddress;
					       geocoder.centerInAddress();
				        }
					} else {

					    //eliminamos temporalmente los listeners de zoom y drag
					    //ya que al centrar el mapa se podrian disparar
					    //y volver a lanzar el evento de update.
					    //posteriormente los anadiremos de nuevo
					    if(map.dragendListener){
        			        GEvent.removeListener(map.dragendListener);
        			        map.dragendListener = null;
        			    }

        			    if(map.zoomendListener){
        			        GEvent.removeListener(map.zoomendListener);
        			        map.zoomendListener = null;
        			    }


					   //obtenemos el circle correspondiente y centramos el mapa en ese
					   //area.
					   var circle = drawCircle(point.lat(), point.lng(), filterForm.radius.value);
                       var zoom = map.getBoundsZoomLevel(circle.getBounds());
                       var center = circle.getBounds().getCenter();
                       map.setCenter(center, zoom);


                       //cambiamos las defaultAddress a esta ultima direccion que dio
                       //coordenadas, para volver a ella siempre que se invoque una nueva
                       //direccion que no sirva
//                       defaultAddress = filterForm.address.value;

	                   updateMarkers();
                       return point;
					}
				  }
				);
			  }

			  //me aseguro que las vars address y valius tienen un valor inicialmente
			  if(!filterForm.address.value){
					filterForm.address.value = defaultAddress;
			      	filterForm.province.value = defaultAddress;
			  }
			  if(!filterForm.radius.value){
			      filterForm.radius.value = defaultRadius;
			  }


			  //arrancamos geolocalizando la direccion en la que vamos a centrarnos
			  //e inicializando el mapa ahí
			  geocoder.centerInAddress();
	}
}


//nos aseguramos de que se hace un GUnload para optimizar los recursos del navegador
window.onunload = GUnload;
