var MarkerLoader = Class.create();

MarkerLoader.prototype = 
{
	map:null,
	aid:null,
	mapContainer:null,
	pano:null,
	panoContainer:null,
	progressBar:null,
	currentMarker:null,
	ongoingPoisAjaxCalls:null,
	ongoingRegionAjaxCalls:null,
	addingMarkers:null,
	addingPoiMarkers:null,
	regions:[],
	pois:[],
	lodgesDefaultNights:null,
	lodgesTodayFormatted:null,
	lodgesTomorrowFormatted:null,
	highlightedPoi:null,
	poisPage:null,
	poisMarkersThread:null,
	regionsMarkersThread:null,
	poisMarkers:[],
	shownPois:[],
	markers:[],
	method:null,
	markersDelay:null,
	session:null,
	zoomLevels:[],
	zindexLevels:[],
	zoomInLevels:[],
	zoomOutLevels:[],
	markerIcons:[],
	highlightIcons:[],
	baseIcon:null,
	markerManager:null,
	poisCountContainers:[],
	ajaxCallsLimit:null,
	nextPoiAjaxCall:null,
	nextPoiAjaxPars:null,
	nextRegionAjaxCall:null,
	nextRegionAjaxPars:null,
	totalPoisInArea:null,
	maxPoisShown:null,
	countryID:null,
	
	initialize: function(MapContainer,MapCenter,MapZoom,PanoContainer,UrlRegions,UrlPois,PoisCountContainers,PoiViewUrl,CountryID)
	{
		/*** Parametros recibidos ***/
		this.mapContainer = MapContainer;
		this.panoContainer = PanoContainer;
		this.url_regions = UrlRegions;
		this.url_pois = UrlPois;
		this.poisCountContainers = PoisCountContainers;
		this.poi_link_url = PoiViewUrl;
		this.countryID = CountryID;

		/*** Getting affiliate ID if it exists ***/
		if(document.location.search.match(/aid=[0-9]+/))
			this.aid = "?" + document.location.search.match(/aid=[0-9]+/);
		else
			this.aid = "";

		
		/*** Variables fijas ***/
		this.currentMarker = 0;
		this.totalMarkers = 0;
		this.addingMarkers = false;
		this.addingPoiMarkers = false;
		this.markers = [];
		this.method = "get";
		this.markersDelay = 10;
		this.ongoingPoisAjaxCalls = 0;
		this.ongoingRegionAjaxCalls = 0;
		this.poisPage = 0;
		this.lodgesDefaultNights = 1;
		this.ajaxCallsLimit = 2;
		//Asignando el limite de rincones segun el navegador
		if( BrowserFind.browser == 'Explorer' && BrowserFind.version < 7 )	//IE6, 20 markers
		{	this.maxPoisShown = 20;	}
		else if ( BrowserFind.browser == 'Explorer' && BrowserFind.version < 8)	//IE7, 30 markers
		{	this.maxPoisShown = 30;	}
		else	//FireFox, Chrome, Safari, etc; 50 markers
		{	this.maxPoisShown = 50;	}
		
		//Zoom Levels
		this.zoomLevels['Country'] = 0;
		this.zoomLevels['Zone'] = 6;
		this.zoomLevels['City'] = 10;
		this.zoomLevels['Poi'] = 14;
		this.zoomInLevels['Country'] = this.zoomLevels['Zone'];
		this.zoomInLevels['Zone'] = this.zoomLevels['City'];
		this.zoomInLevels['City'] = this.zoomLevels['Poi'];
		this.zoomOutLevels['World'] = 2;
		this.zoomOutLevels['Country'] = this.zoomLevels['Zone'];
		this.zoomOutLevels['Zone'] = this.zoomLevels['City'];
		this.zoomOutLevels['City'] = this.zoomLevels['Poi'];
		
		//Z-Index values
		this.zindexLevels['Country'] = 1;
		this.zindexLevels['Zone']  = 100;
		this.zindexLevels['City'] = 1000;
		
		//Icons
		this.baseIcon = new GIcon();
		this.baseIcon.iconSize=new GSize(22,22);
		this.baseIcon.iconAnchor=new GPoint(11,22);
		this.baseIcon.infoWindowAnchor=new GPoint(11,2);
		this.highlightIcons['Country'] = "http://3.images.mnstatic.com/maps/icons/countryh.png";
		this.highlightIcons['Zone'] = "http://1.images.mnstatic.com/maps/icons/zoneh.png";
		this.highlightIcons['City'] = "http://4.images.mnstatic.com/maps/icons/cityh.png";
		this.highlightIcons['highlight'] = "http://5.images.mnstatic.com/iconos/map-here.png";
		this.highlightIcons['tosee'] = "http://1.images.mnstatic.com/iconos/map-point.png";
		this.highlightIcons['sleep'] = "http://5.images.mnstatic.com/iconos/map-hotel.png";
		this.highlightIcons['eat'] = "http://4.images.mnstatic.com/iconos/map-restaurant.png";
		this.markerIcons['Country'] = new GIcon(this.baseIcon,"http://1.images.mnstatic.com/maps/icons/country.png");
		this.markerIcons['Zone'] = new GIcon(this.baseIcon,"http://3.images.mnstatic.com/maps/icons/zone.png");
		this.markerIcons['City'] = new GIcon(this.baseIcon,"http://2.images.mnstatic.com/maps/icons/city.png");
		this.markerIcons['highlight'] = new GIcon(this.baseIcon,"http://5.images.mnstatic.com/iconos/map-here.png");
		this.markerIcons['tosee'] = new GIcon(this.baseIcon,"http://1.images.mnstatic.com/iconos/map-point.png");
		this.markerIcons['sleep'] = new GIcon(this.baseIcon,"http://5.images.mnstatic.com/iconos/map-hotel.png");
		this.markerIcons['eat'] = new GIcon(this.baseIcon,"http://4.images.mnstatic.com/iconos/map-restaurant.png");
		
		/*** Creando Mapa y Panorama ***/
		this.map = new GMap2(this.mapContainer,{googleBarOptions:{showOnLoad:true,suppressInitialResultSelection:true,onGenerateMarkerHtmlCallback:this.googleBarResultInfoWindow,onSearchCompleteCallback:this.googleBarSearchCompleted,onMarkersSetCallback:this.googleBarMarkersSet}});
		
		this.map.setCenter(MapCenter,MapZoom);
		this.map.addControl(new GMapTypeControl());
		this.map.addControl(new GLargeMapControl(),new GControlPosition(G_ANCHOR_TOP_RIGHT,new GSize(5,60)));
		GEvent.addListener(this.map,'zoomend',this.map.closeInfoWindow);
		//this.map.enableGoogleBar();
		
		if(FlashDetect && FlashDetect.installed)
		{
			this.pano = new GStreetviewPanorama(this.panoContainer);
			function handleNoPano(errorCode)
			{
				//Error Code 600 => NO_NEARBY_PANO
				if (errorCode == 600)	
				{
					this.showMap();
					alert(dictionary_pois_map_streetview_no_nearby_pano);
				}
				else
				{	alert(dictionary_pois_map_streetview_unexpected_error+errorCode);	}
			} 
			GEvent.addListener(this.pano, "error", handleNoPano.bind(this));	
			
			this.streetViewAvailable = true;
		}
		else
		{	this.streetViewAvailable = false;	}
		
		/*** Variables creadas ***/
		this.session = new Date() - Math.random()
		var today = new Date();
		var tomorrow = new Date(1*today + this.lodgesDefaultNights*24*60*60*1000);
		this.lodgesTodayFormatted = this._leftpad_zero(today.getDate(),2)+'/'+this._leftpad_zero(today.getMonth()+1,2)+'/'+today.getFullYear();
		this.lodgesTomorrowFormatted = this._leftpad_zero(tomorrow.getDate(),2)+'/'+this._leftpad_zero(tomorrow.getMonth()+1,2)+'/'+tomorrow.getFullYear();
		this.markerManager = new MarkerManager(this.map);
		this.progressBar = new ProgressbarControl(this.map);
	}
	
	//Returns the HTML to show in the result's window. In our case, we don't want to show anything
	,googleBarResultInfoWindow:function(marker,html,searchResult)
	{
		//return  document.createElement('div').update(searchResult.title);
		return null;
	}
	
	,googleBarSearchCompleted:function(localSearch)
	{
		return localSearch;
	}
	
	,googleBarMarkersSet:function(results)
	{
		results.each(function(result){
			//Moviendo su iconito
			//result.marker.setImage("http://maps.google.com/mapfiles/kml/pal3/icon62.png");
		});
	}
	
	,getPoisCountContainers:function()
	{	return this.poisCountContainers;	}
	,setPoisCountContainers:function(PoisCountContainers)
	{	this.poisCountContainers = PoisCountContainers;	}
	
	,showMap:function()
	{
		this.panoContainer.up().hide();
		this.mapContainer.up().show();
		this.panoContainer.hide();
		this.mapContainer.show();
		window.location = "#"+this.mapContainer.id;
	}
	
	,showPano:function()
	{
		if(this.streetViewAvailable)
		{
			$(this.mapContainer).hide();
			$(this.panoContainer).show();
			$(this.mapContainer).up().hide();
			$(this.panoContainer).up().show();
			window.location = "#"+this.panoContainer.id;
		}
		else
		{
			alert(dictionary_pois_map_streetview_no_nearby_pano);
		}
	}
	
	,centerPano:function(Center)
	{
		if(this.streetViewAvailable)
		{
			this.pano.setLocationAndPOV(Center);
			this.showPano();
		}
		else
		{
			alert(dictionary_pois_map_streetview_no_nearby_pano);
		}
	}
	
	,getMap:function()
	{	return this.map;	}
	
	,getPano:function()
	{	return this.pano;	}
	
	,_log:function(text)
	{
		/*if($('logger'))
		{
			$('logger').insert(text+"<br/>");
		}*/
		//console.log(text);
	}
	
	,loadRegion:function(Region)
	{
		var mapBounds = this.map.getBounds();
		var parameters =
		{
			object:Region,
			session:this.session,
			min_lat:mapBounds.getSouthWest().lat(),
			max_lat:mapBounds.getNorthEast().lat(),
			min_long:mapBounds.getSouthWest().lng(),
			max_long:mapBounds.getNorthEast().lng()
		};
	
		if(!this.addingMarkers)
		{
			this.progressBar.loadstring_ = dictionary_pois_map_loadstring_text;
			this.progressBar.start(0);
		}
		
		if(this.ongoingRegionAjaxCalls < this.ajaxCallsLimit)
		{
			this.loadRegionRequest(parameters,Region);
		}
		else
		{
			//this._log("Ajax calls limit reached. Queueing call.","this.loadRegionRequest",[parameters,Region]);
			this.nextRegionAjaxCall = this.loadRegionRequest;
			this.nextRegionAjaxPars = [parameters,Region];
		}
	}
	
	,loadRegionRequest:function(args,Region)
	{
		this.ongoingRegionAjaxCalls++;
		new Ajax.Request
		(
			this.url_regions,
			{
				method:this.method,
				parameters:args,
				onSuccess:this.loadRegionOnSuccess.bind(this,Region)
			}
		);
	}
	
	,loadRegionOnSuccess:function(Region,transport)
	{
		this.ongoingRegionAjaxCalls--;
		
		transport.responseJSON = eval(transport.responseText);
		if(transport.responseJSON.length > 0)
		{
			if(this.addingMarkers)
			{
				this.regions = this.regions.concat(transport.responseJSON);
				this.progressBar.start(this.currentMarker+this.regions.length);
				this.progressBar.updateLoader(this.currentMarker+1);
			}
			else
			{
				this.regions = transport.responseJSON;
				this.currentMarker = 0;
				this.progressBar.start(this.regions.length);
				
				this._addRegionMarker(Region);
			}
		}
		else if(!this.addingMarkers)
		{
			this.progressBar.remove();
		}
		
		this._processAjaxQueue();
	}
	
	,_processAjaxQueue:function()
	{
		if(this.ongoingRegionAjaxCalls < this.ajaxCallsLimit && typeof this.nextRegionAjaxCall == "function")
		{
			//this._log("Ajax calls available. Making next call.",this.nextRegionAjaxCall,this.nextRegionAjaxPars);
			this.nextRegionAjaxCall.apply(this,this.nextRegionAjaxPars);
			this.nextRegionAjaxCall = null;
			this.nextRegionAjaxPars = null;
		}
		if(this.ongoingPoisAjaxCalls < this.ajaxCallsLimit && typeof this.nextPoiAjaxCall == "function")
		{
			//this._log("Ajax calls available. Making next call.",this.nextPoiAjaxCall,this.nextPoiAjaxPars);
			this.nextPoiAjaxCall.apply(this,this.nextPoiAjaxPars);
			this.nextPoiAjaxCall = null;
			this.nextPoiAjaxPars = null;
		}
	}
	
	,loadNextPois:function(params)
	{
		//Si todavia hay rincones por mostrar
		if(this.maxPoisShown * this.poisPage < this.totalPoisInArea)
			this.loadPois(this.poisPage+1,params);
		else
			alert(dictionary_pois_map_pagination_no_more_pois);
	}
	
	,loadPrevPois:function(params)
	{
		//Si no estamos en la primera pagina
		if(this.poisPage > 1)
			this.loadPois(this.poisPage-1,params);
		else
			alert(dictionary_pois_map_pagination_first_page);
	}
	
	,loadPois:function(Page,params)
	{
		this.poisPage = Page;
		if(!this.addingMarkers)
		{
			this.progressBar.loadstring_ = dictionary_pois_map_loadstring_text;
			this.progressBar.start(0);
		}
		
		var mapBounds = this.map.getBounds();
		var baseParams = $H({
			page:Page,
			ignore:this.highlightedPoi,
			min_lat:mapBounds.getSouthWest().lat(),
			max_lat:mapBounds.getNorthEast().lat(),
			min_long:mapBounds.getSouthWest().lng(),
			max_long:mapBounds.getNorthEast().lng()
		});
		if(typeof params != "undefined" && typeof params.merge == "function")
		{	baseParams = params.merge(baseParams);	}
		
		//Asignando el limite de rincones segun el navegador
		baseParams.set("limit",this.maxPoisShown);
		//Asignando el país, si esta definido
		if(this.countryID)	baseParams.set("country_id",this.countryID);
		
		if(this.ongoingPoisAjaxCalls < this.ajaxCallsLimit)
		{
			this.loadPoisRequest(baseParams);
		}
		else
		{
			//this._log("Ajax calls limit reached. Queueing call.","this.loadPoisRequest",baseParams);
			this.nextPoiAjaxCall = this.loadPoisRequest;
			this.nextPoiAjaxPars = [baseParams];
		}
	}
	
	,loadPoisRequest:function(args)
	{
		this.ongoingPoisAjaxCalls++;
		new Ajax.Request
		(
			this.url_pois,
			{
				method:this.method,
				parameters:args,
				onSuccess:this.loadPoisOnSuccess.bind(this)
			}
		);
	}
	
	,loadPoisOnSuccess:function(transport)
	{
		this.ongoingPoisAjaxCalls--;
		eval("transport.responseJSON = "+transport.responseText);
		
		if(transport.responseJSON.Pois.length > 0)
		{
			/***
			Si ya esta añadiendo poiMarkers:
				a) Eliminamos todos los pois que teniamos
				b) Matamos la thread (this.poisMarkersThread)
				c) Añadimos los que recibimos
			Si no esta añadiendo, no pasa nada y llamamos al metodo tal cual
			***/
			if(this.addingPoiMarkers)
			{
				clearTimeout(this.poisMarkersThread);
				var poisToAdd = transport.responseJSON.Pois;
				var poisToRemove = this.shownPois;
				var newPois = transport.responseJSON.Pois;
			}
			else
			{
				this.addingPoiMarkers = true;
				var oldPois = this.shownPois;
				var oldPoisIDs = oldPois.collect(function(poi){return poi.Poi.id;});
				//this._log("Teniamos: ",oldPoisIDs);
				var newPois = transport.responseJSON.Pois;
				var newPoisIDs = newPois.collect(function(poi){return poi.Poi.id;});
				//this._log("Recibimos: ",newPoisIDs);
				
				var poisToRemove = oldPois.findAll(function(poi){
					return !newPoisIDs.include(poi.Poi.id);
				});
				var poisToAdd = newPois.findAll(function(poi){
					return !oldPoisIDs.include(poi.Poi.id);
				});
				//this._log(poisToRemove.length + " rincones a quitar");
				//this._log(poisToAdd.length + " rincones a añadir");
			}
				
			this.pois = poisToAdd;
			this.shownPois = newPois;
			this.currentMarker = 0;
			this.progressBar.start(poisToAdd.length);
			this._removePoiMarker(poisToRemove,0);
			this._addPoiMarker();
		}
		else
		{
			if(!this.addingMarkers)
			{
				this.progressBar.remove();
			}
			/**** Vieja manera de hacerlo
			progressBar.remove();
			isMoving = false;
			******/
		}
		
		this.poisCountContainers['see'].update(transport.responseJSON.Categories['see']);
		this.poisCountContainers['eat'].update(transport.responseJSON.Categories['eat']);
		this.poisCountContainers['sleep'].update(transport.responseJSON.Categories['sleep']);
		this.totalPoisInArea = 
			1*transport.responseJSON.Categories['see'] +
			1*transport.responseJSON.Categories['eat'] +
			1*transport.responseJSON.Categories['sleep'];
		
		/* QUICK DIRTY WAY TO DO IT, MUST CLEAN LATER! */
		//Probablemente la manera decente de hacerlo sea con un callback
		
		//Actualizando el control con el total de rincones en el area
		$('total_pois_in_area').update(this.totalPoisInArea);
		
		//Actualizando los enlaces de prev
		if(transport.responseJSON.Pagination.page > 1)
			var prev_pois_count = this.maxPoisShown;
		else
			var prev_pois_count = 0;
		$('prev_pois_count').update(prev_pois_count);
		
		//Actualizando los enlaces de next
		var next_pois_count = this.totalPoisInArea - transport.responseJSON.Pagination.page*this.maxPoisShown;
		if(next_pois_count > this.maxPoisShown)
			var next_pois_count = this.maxPoisShown;
		else if(next_pois_count < 0)
			var next_pois_count = 0;
		$('next_pois_count').update(next_pois_count);
		
		this._processAjaxQueue();
	}
	
	,_zoomInMarker:function(region,marker)
	{
		this.map.setCenter(marker.getLatLng(),this.zoomInLevels[region]);
	}
	
	,_zoomOut:function(latlng,zoom)
	{
		this.map.setCenter(latlng,zoom);
	}
	
	,addRegionZoomControl:function()
	{
		if(!this.regionZoomControl)
		{
			this.regionZoomControl = new gRegionZoomControl();
			this.regionZoomControl.setZoomOutLevels(this.zoomOutLevels);
			map.addControl(this.regionZoomControl);
		}
	}
	
	,_getRegionInfoWindow:function(Marker,Region)
	{
		var HTML = '<div style="text-align: left;">';
		HTML += '	<b style="font:bold 16px/1.8em \'Trebuchet Ms\';color:#333">'+Marker[Region].name+'</b>';
		if(Marker.url != null)				HTML += '	<br/><a href="'+Marker.url+this.aid+'">'+dictionary_pois_map_visit_city+'</a><br/>';
		if(Marker.sleep_count != null)	HTML += '	<p style="line-height:1.8em"><img src="'+this.markerIcons['sleep'].image+'"/> '+'<a target="_blank" href="'+Marker.sleep_url+this.aid+'">'+Marker.sleep_count+' '+dictionary_pois_map_infowindow_sleep+'</a></p>';
		if(Marker.see_count != null)		HTML += '	<p style="line-height:1.8em"><img src="'+this.markerIcons['tosee'].image+'"/> '+'<a target="_blank" href="'+Marker.see_url+this.aid  +'">'+Marker.see_count  +' '+dictionary_pois_map_infowindow_see+'</a></p>';
		if(Marker.eat_count != null)		HTML += '	<p style="line-height:1.8em"><img src="'+this.markerIcons['eat'].image  +'"/> '+'<a target="_blank" href="'+Marker.eat_url+this.aid  +'">'+Marker.eat_count  +' '+dictionary_pois_map_infowindow_eat+'</a></p>';
		HTML += '</div>';
		return HTML;
	}
	
	,_showRegionInfoWindow:function(HTML,Marker)
	{
		setTimeout(Marker.openInfoWindowHtml.bind(Marker,HTML),5);
	}
	
	,_setCountryID:function(ID)
	{
		this.countryID = ID;
	}
	
	,_addRegionMarker:function(Region)
	{
		this.addingMarkers = true;
		var marker = this.regions.pop();
		if(!marker[Region])
		{
			if(marker['City'])	Region = 'City';
			else if(marker['Zone'])	Region = 'Zone';
			else if(marker['Country'])	Region = 'Country';
		}
		
		var latlng = new GLatLng(marker.Geocode.latitude,marker.Geocode.longitude); 
		var markerName = marker[Region].name + " ("+marker[Region].pois_count+")";
		//var markerName = marker[Region].name;
		marker[Region].zindex = this.zindexLevels[Region];
		var gMarker = new GMarker(latlng,{title:markerName,icon:this.markerIcons[Region],zIndexProcess:function(){
			return marker[Region].zindex * marker[Region].pois_count;
		}});
		
		GEvent.addListener(gMarker,'mouseover',gMarker.setImage.bind(gMarker,this.highlightIcons[Region]));
		GEvent.addListener(gMarker,'mouseout',gMarker.setImage.bind(gMarker,this.markerIcons[Region].image));
		
		GEvent.addListener(gMarker,'click',this._zoomInMarker.bind(this,Region,gMarker));
		if(this.regionZoomControl)
		{	GEvent.addListener(gMarker,'click',this.regionZoomControl.updateRegion.bind(this.regionZoomControl,Region,marker[Region].name,latlng));	}
		if(Region == "City")
		{	GEvent.addListener(gMarker,'click',this._showRegionInfoWindow.bind(this,this._getRegionInfoWindow(marker,Region),gMarker));	}
		if(Region == "Country")
		{	GEvent.addListener(gMarker,'click',this._setCountryID.bind(this,marker[Region].id));	}
		else
		{	GEvent.addListener(gMarker,'click',this._setCountryID.bind(this,marker[Region].country_id));	}
		
		if(Region != 'City')	this.addMarker(gMarker,this.zoomLevels[Region],this.zoomInLevels[Region]-1);
		else						this.addMarker(gMarker,this.zoomLevels[Region],this.zoomInLevels[Region]);
			
		this.progressBar.updateLoader(1);
		this.currentMarker++;
		if(this.regions.length > 0)
		{	this.regionsMarkersThread = setTimeout(this._addRegionMarker.bind(this,Region),this.markersDelay);	}
		else
		{
			this.addingMarkers = false;
			if(this.ongoingRegionAjaxCalls + this.ongoingPoisAjaxCalls == 0)
			{	this.progressBar.remove();	}
		}
		
		this.markers[this.currentMarker] = gMarker;
	}
	
	,addMarker:function()
	{
		return this.markerManager.addMarker.apply(this.markerManager,arguments);
	}
	
	,_leftpad_zero:function(str,padToLength)
	{
		var result	= '';
		for ( var i = 0; i < (padToLength - String(str).length); i++ )
			result	+= '0';
		return	result + str;
	}
	
	,formatURL:function(baseURL)
	{
		var formattedURL = baseURL;
		formattedURL = formattedURL.toLowerCase().gsub('ñ','n').gsub('ç','c').gsub(" ","_");
		formattedURL = formattedURL.gsub('á','a').gsub('é','e').gsub('í','i').gsub('ó','o').gsub('ú','u');
		formattedURL = formattedURL.gsub('à','a').gsub('è','e').gsub('ì','i').gsub('ò','o').gsub('ù','u');
		formattedURL = formattedURL.gsub('ä','a').gsub('ë','e').gsub('ï','i').gsub('ö','o').gsub('ü','u');
		formattedURL = formattedURL.gsub('â','a').gsub('ê','e').gsub('î','i').gsub('ô','o').gsub('û','u');
		return formattedURL;
	}
	
	,_getPoiInfoWindow:function(poi)
	{
		var html = '';
		
		html += '<div style="background-color: rgb(255, 255, 255); text-align:left; ">';	//width: 300px; height: 180px;
		
		if(poi.Subcategory.group != 'highlight')
		{	html += 	'<a target="_blank" style="color: rgb(0, 99, 204); font-size: 16px; font-weight: bold;" href="'+this.poi_link_url+poi.Poi.id+this.aid+'">'+poi.Poi.name+'</a>';	}
		else
		{
			html += '<img src="'+this.markerIcons[poi.Subcategory.group].image+'" style="padding: 5px 5px; float: left;""/>';
			html +=	'<p style="font-family: Arial,Helvetica,sans-serif; font-size: 13px; color: rgb(51, 51, 51); text-transform: uppercase; font-weight: bold;">'+dictionary_pois_map_infowindow_yah+'</p>';
		}
		
		if(poi.Poi.address != null)
		{	html += '<p>'+poi.Poi.address+'</p>';	}
		
		if(poi.City != null && poi.Zone != null && poi.Country != null)
		{	html += '<p><a target="_blank" href="/'+dictionary_homes_url_experiences+'/'+this.formatURL(poi.Country.name+"/"+poi.Zone.name+"/"+poi.City.name)+this.aid+'">'+poi.City.name+'</a></p>';	}
		
		if(poi.PoiPoi != null && poi.PoiPoi.distance != null)
		{
			var walking_time = Math.ceil(poi.PoiPoi.distance/100);
			html += 	'<p style="font-family: Arial,Helvetica,sans-serif; font-size: 11px; color: rgb(119, 119, 119);">';
			html += 		'<img style="margin: 3px 5px 0pt 0pt;" src="http://3.images.mnstatic.com/iconos/map-walk2.gif"/>';
			html += 			dictionary_pois_map_walking_time_start+' '+walking_time+' ';	//A #
			if(walking_time == 1)	html += dictionary_pois_map_walking_time_singular;		//minuto a pie
			else							html += dictionary_pois_map_walking_time_plural;		//minutos a pie
			html += 	'</p>';
		}
		
		if(poi.Subcategory.group != 'highlight')
		{
			html += 	'<p>';
			if(poi.Poi.comments > 0)
			{
				html += 	'<a target="_blank" href="'+this.poi_link_url+poi.Poi.id+this.aid+'">'+poi.Poi.comments+' ';
				if(poi.Poi.comments == 1)	html += dictionary_pois_map_comments_singular;
				else								html += dictionary_pois_map_comments_plural;
				html += 	'</a> ';
			}
			
			if(poi.Poi.pics > 0)
			{
				html += 	'<a target="_blank" href="/'+dictionary_url_poi_photo_gallery+'/'+poi.Poi.id+this.aid+'">'+poi.Poi.pics+' ';
				if(poi.Poi.pics == 1)	html += dictionary_pois_map_pictures_singular;
				else							html += dictionary_pois_map_pictures_plural;
				html += 	'</a> ';
			}
			
			if(poi.Poi.vids > 0)
			{
				html += 	'<a target="_blank" href="/'+dictionary_url_poi_video_gallery+'/'+poi.Poi.id+this.aid+'">'+poi.Poi.vids+' ';
				if(poi.Poi.vids == 1)	html += dictionary_pois_map_videos_singular;
				else							html += dictionary_pois_map_videos_plural;
				html += 	'</a> ';
			}
			html +=	'</p>';
		} else {	
			if (dictionary_homes_url_experiences=="viajes")
				//html += '<p><a target="_blank" href="http://clk.tradedoubler.com/click?p=121376&a=1521837&g=18061278">Cómo llegar</a><img src="http://impes.tradedoubler.com/imp?type(inv)g(18061278)a(1521837)" /></p>';
				html +='';
		}
		
		/*
		if(poi.Poi.hotel_id != false)
		{
			html += '<form id="formSearchEnginesMini" action="/lodges/results" method="post" target="_blank">';
			html += '<input type="hidden" value="21/01/2009" name="data[Lodge][date_in]"/>';
			
			//Tendre que hacer que cree cada Datepicker en el onClick
			
            html += 'Del <input type="text" id="LodgeDateIn" readonly="readonly" value="' + this.lodgesTodayFormatted;
			html += '" name="data[Lodge][date_in]" timeloader="false" style="border: 0px solid ; width: 75px; height: 20px; font-family: \'Trebuchet MS\'; font-size: 13px; color: rgb(51, 51, 51); background-color: transparent; cursor: pointer;"/>';
			html += '<img id="imageLodgeDateIn" align="absmiddle" style="cursor: pointer;" src="http://5.images.mnstatic.com/iconos/calendario2.gif"/>';
			
            html += '<br/>al <input type="text" id="LodgeDateOut" readonly="readonly" value="' + this.lodgesTomorrowFormatted;
			html += '" name="data[Lodge][date_out]" timeloader="false" style="border: 0px solid ; width: 75px; height: 20px; font-family: \'Trebuchet MS\'; font-size: 13px; color: rgb(51, 51, 51); background-color: transparent; cursor: pointer;"/>';
			html += '<img id="imageLodgeDateOut" align="absmiddle" style="cursor: pointer;" src="http://5.images.mnstatic.com/iconos/calendario2.gif"/>';
			
			html += '<input type="hidden" value="2" name="data[Lodge][adults]"/>';
			html += '<input type="hidden" value="0" name="data[Lodge][children]"/>';
			html += '<input type="hidden" value="1" name="data[Lodge][rooms]"/>';
			
			html += '<input type="hidden" value="'+poi.Poi.hotel_id+'" name="data[Lodge][hotel_id]"/>';
			html += '<input type="hidden" value="'+poi.Poi.hotel_location+'" name="data[Lodge][city]"/>';
			html += '<br/>';
			html += '<input type="submit" value="Revisar disponibilidad"/>';
			html += '</form>';
		}
		else
		{	html += "<br/>";	}
		*/
		
		if(this.streetViewAvailable)
		{	html += '<a href="#streetview" id="infowindow_streetview_link" lat="'+poi.Geocode.latitude+'" long="'+poi.Geocode.longitude+'">'+dictionary_pois_map_streetview_link+'</a>';}
		
		html += '</div>';
		return html;
	}
	
	,_dateUpdater:function()
	{
		var dateMatches = $('LodgeDateIn').value.split("/");
		var dateDay = dateMatches[0];
		var dateMon = dateMatches[1];
		var dateYear = dateMatches[2];
		var dateString = dateMon + "/" + dateDay + "/" + dateYear;
		
		var targetTime = new Date(Date.parse(dateString) + this.lodgesDefaultNights*24*60*60*1000);
		var stringTime = this._leftpad_zero(targetTime.getDate(),2)+'/'+this._leftpad_zero(targetTime.getMonth()+1,2)+'/'+targetTime.getFullYear();
		$('LodgeDateOut').value = stringTime;
	}
	
	,_bindStreetViewLink:function()
	{
		//this._log("_bindStreetViewLink");
		var element_link = $('infowindow_streetview_link');
		//this._log(element_link);
		Event.observe
		(
			element_link,
			'click',
			this.centerPano.bind(this,new GLatLng(element_link.readAttribute("lat"),element_link.readAttribute("long")))
		);
	}
	
	,_createDatePickers:function()
	{
		//this._log("_createDatePickers");
		var dpck_in   = new DatePicker({
		relative	: "LodgeDateIn",
		language	: "Spanish",
		topOffset	: 18,
		leftOffset	: 0,
		timeLoader  : false,
		zindex  	: 10000,
		relativePosition	: true,
		cellClickCallback 	: this._dateUpdater.bind(this)
		});
	
		var dpck_out   = new DatePicker({
		relative	: "LodgeDateOut",
		language	: "Spanish",
		topOffset	: 18,
		leftOffset	: 0,
		timeLoader  : false,
		zindex  	: 10000,
		relativePosition	: true
		});
	}
	
	,_poiToMarker:function(poi)
	{
		var latlng = new GLatLng(poi.Geocode.latitude,poi.Geocode.longitude); 
		var markerName = poi.Poi.name + " (" + poi.Poi.experiences_count + ")";
		var marker;
		if(poi.Subcategory.group != 'highlight') {
		marker = new GMarker(latlng,{title:markerName,icon:this.markerIcons[poi.Subcategory.group],zIndexProcess:function(){
			return poi.Poi.experiences_count * 1000000;
		}});}
		else {
		marker = new GMarker(latlng,{title:markerName,icon:this.markerIcons[poi.Subcategory.group],zIndexProcess:function(){
			return poi.Poi.experiences_count * 1000000 * 10;
		}});}
		
		//Si es un hotel, al abrir la infowindow creamos los datepickers
		//if(poi.Poi.hotel_id != false)
		//{	GEvent.addListener(marker,'infowindowopen',this._createDatePickers.bind(this));	}
		if(this.streetViewAvailable)
		{	GEvent.addListener(marker,'infowindowopen',this._bindStreetViewLink.bind(this));	}
		
		marker.bindInfoWindowHtml(this._getPoiInfoWindow(poi));
		return marker;
	}
	
	,_removePoiMarker:function(pois_array,current_index)
	{
		if(current_index < pois_array.length)
		{
			this.addingPoiMarkers = true;
			
			var poiMarker = this.poisMarkers[pois_array[current_index].Poi.id];
			if(poiMarker != null)
			{
				this.markerManager.removeMarker(poiMarker);
				this.poisMarkers[pois_array[current_index].Poi.id] = null;
			}
			//this._log("Quitando el rincon "+ pois_array[current_index].Poi.id + ":" + poi.Poi.name);
			//this.progressBar.updateLoader(1);
			//setTimeout(this._removePoiMarker.bind(this,pois_array,current_index+1),this.markersDelay);
			this._removePoiMarker(pois_array,current_index+1);
		}
	}
	
	,addHighlightedPoi:function(poi)
	{
		//We check if street view is available for this marker, if it's not, we disable street view
		if(this.streetViewAvailable)
		{	new GStreetviewClient().getNearestPanoramaLatLng(new GLatLng(poi.Geocode.latitude,poi.Geocode.longitude),this.streetViewCheckCallback.bind(this,poi));	}
		else
		{	this.addHighlightedPoiDelayed(poi);	}
	}
	
	,streetViewCheckCallback:function(poi,result)
	{
		this.streetViewAvailable = result != null;
		this.addHighlightedPoiDelayed(poi);
	}
	
	,addHighlightedPoiDelayed:function(poi)
	{
		this.highlightedPoi = poi.Poi.id;
		poi.Subcategory = Object;
		poi.Subcategory.group = 'highlight';
		var poiMarker = this._poiToMarker(poi);
		this.poisMarkers[poi.Poi.id] = poiMarker;
		this.addMarker(poiMarker,this.zoomLevels['Poi']);
		
		this.focusOnPoi(poi.Poi.id);
	}
	
	,focusOnPoi:function(poi_id)
	{
		//A lo mejor añadir un panTo ?
		GEvent.trigger(this.poisMarkers[poi_id],'click');
	}
	
	,_addPoiMarker:function()
	{
		if(this.currentMarker < this.pois.length)
		{
			//No actualizar mientras hayan llamadas AJAX pendientes?
			if(this.ongoingPoisAjaxCalls == 0)
			{
				this.addingPoiMarkers = true;
				var poi = this.pois[this.currentMarker];
				//this._log("Añadiendo "+poi.Poi.id+", faltan "+(this.pois.length-this.currentMarker-1));
				var poiMarker = this._poiToMarker(poi);
				GEvent.addListener(poiMarker,'mouseover',poiMarker.setImage.bind(poiMarker,this.highlightIcons[poi.Subcategory.group]));
				GEvent.addListener(poiMarker,'mouseout',poiMarker.setImage.bind(poiMarker,this.markerIcons[poi.Subcategory.group].image));
				this.poisMarkers[poi.Poi.id] = poiMarker;
				
				this.addMarker(poiMarker,this.zoomLevels['Poi']);
				this.progressBar.updateLoader(1);
				this.currentMarker++;
				//this._log("Añadiendo el rincon "+ poi.Poi.id + ":" + poi.Poi.name);
			}
			else
			{
				//this._log("Ajax calls pending. Waiting.");
			}
			this.poisMarkersThread = setTimeout(this._addPoiMarker.bind(this),this.markersDelay);
		}
		else
		{
			this.progressBar.remove();
			this.addingPoiMarkers = false;
		}
	}
}