
// the map in the search panel
var GoogleMapResults = {

  map: null,
  manager: null,
  currentWindow: null,
  waitTimeout: null,
  loaded: false,
  markers: {},

  load: function() 
  {
    //Prevent error message
    if (typeof (google.maps.Icon) == "undefined") return;
  
    var canvas = document.getElementById("googleMapResultsCanvas");
    if (!GoogleMapUtils.isImplemented(canvas))
      return;
      
    var map = GoogleMapResults.map = new google.maps.Map2(canvas);
    var coordsEl = document.getElementById('googleMapResultsCoords');
    
    // enable various features on the map
    map.enableDoubleClickZoom();
    map.enableContinuousZoom();
    map.enableScrollWheelZoom();
    
    // add controls		
		map.addControl(new google.maps.LargeMapControl());
		map.addControl(new google.maps.OverviewMapControl());
		map.addControl(new google.maps.MapTypeControl());
    
    // set default view
    var rect = GoogleMapUtils.getMapDefaultView(coordsEl, false);
    map.setCenter(rect.getCenter());
    var defaultZoom = GoogleMapUtils.getDefaultZoom(map, rect);
    
    //Don't zoom too much
    if (defaultZoom > 12) defaultZoom = 12;

    map.setZoom(defaultZoom);
    map.savePosition();
  
    // load markers
    GoogleMapUtils.loadMarkers(GoogleMapResults, coordsEl, true);
    GoogleMapUtils.setMinMaxZoom(4, 17);
    
    // fix copyright element overflow
    GoogleMapResults.fixCopyright();

    if (search) search.fillSearchedFor(false);
    
    // listen to events
    var handleMapClick = google.maps.Event.addListener(map, "click", GoogleMapResults.handleMapClick);
    var handleZoom = google.maps.Event.addListener(map, "zoomend", GoogleMapResults.handleZoom);
    var handleMove = google.maps.Event.addListener(map, "moveend", GoogleMapResults.handleMove);
    var handleDragStart = google.maps.Event.addListener(map, "dragstart", GoogleMapResults.handleDragStart);
    var handleDragEnd = google.maps.Event.addListener(map, "dragend", GoogleMapResults.handleDragEnd);

    this.loaded = true;
  },
  
  updateMapLinks: function(bounds, zoom)
  {
    var mapParams = document.getElementById('map_params');
    var listLinkEl = document.getElementById('results-tab-list').getElementsByTagName('a')[0];

    mapParams.value = mapParams.value.replace(/google-map-bounds=(.*?)(?:&|$)/, 'google-map-bounds=' + bounds + '&');
    mapParams.value = mapParams.value.replace(/google-map-zoom=(.*?)(?:&|$)/, 'google-map-zoom=' + zoom + '&');
    mapParams.value = mapParams.value.replace(/&$/, '');

    listLinkEl.href = listLinkEl.href.replace(/google-map-bounds=(.*?)(?:&|$)/, 'google-map-bounds=' + bounds + '&');
    listLinkEl.href = listLinkEl.href.replace(/google-map-zoom=(.*?)(?:&|$)/, 'google-map-zoom=' + zoom + '&');
    listLinkEl.href = listLinkEl.href.replace(/&$/, '');
  },
  
  fixCopyright: function()
  {
    var canvas = document.getElementById("googleMapResultsCanvas");
    canvas.childNodes[1].style.overflow = 'hidden';
    canvas.childNodes[1].style.width = '400px';
  },
  
  handleMapClick: function(marker)
  {
    if (GoogleMapResults.currentWindow && !marker)
    {
      GoogleMapResults.currentWindow.hide();
      GoogleMapResults.currentWindow = null;
    }
  },
  
  handleMarkerClick: function()
  {
    if (GoogleMapResults.currentWindow)
    {
      GoogleMapResults.currentWindow.hide();
      GoogleMapResults.currentWindow = null;
    }
    
    var pos = GoogleMapResults.getPixelPositionFromCoords(this);
    var window = GoogleMapResults.currentWindow = new GoogleMapResultsInfoWindow(pos, 'googleMapResultsInfoWindow');
    window.show(this.VSpoint);
  },
  
  handleClusterClick: function()
  {
    if (GoogleMapResults.currentWindow)
    {
      GoogleMapResults.currentWindow.hide();
      GoogleMapResults.currentWindow = null;
    }
    
    var pos = GoogleMapResults.getPixelPositionFromCoords(this);
    pos.x -= 2;
    pos.y -= 18;
    
    var window = GoogleMapResults.currentWindow = new GoogleMiniMapInfoWindow(pos, 'googleMiniMapInfoWindow');
    window.show(this.VSpoint);
  },
  
  handleLargeClusterClick: function()
  {
    if (GoogleMapResults.currentWindow)
    {
      GoogleMapResults.currentWindow.hide();
      GoogleMapResults.currentWindow = null;
    }
    
    var cluster = this.VSpoint;
    var newZoom = GoogleMapResults.map.getZoom() + 1;
    var hasLat = cluster.getAttribute('minLat') != null;
    
    //Bounding box defined?
    if (hasLat)
    {
			var oldZoom = newZoom;
			var sw = new google.maps.LatLng(cluster.getAttribute('minLat'), cluster.getAttribute('minLng'));
			var ne = new google.maps.LatLng(cluster.getAttribute('maxLat'), cluster.getAttribute('maxLng'));
			var rect = new google.maps.LatLngBounds(sw, ne);
			
			newZoom = GoogleMapResults.map.getBoundsZoomLevel(rect);
	    
	    //Goto zoomfactor 12 at once
			if (newZoom > oldZoom && newZoom <= 12)
			{
				//Keep quick zoom
			}
			
			//Furthermore allow steps of 2
			else if (newZoom >= oldZoom + 2)
			{
				newZoom = oldZoom + 2;
			}
			
			//Otherwise do OLD behaviour
			else
			{
				newZoom = oldZoom;
			}
    }
    
    // get bounds for the position around the clicked cluster
    var center = new google.maps.LatLng(cluster.getAttribute('lat'), cluster.getAttribute('lng'));
    GoogleMapResults.map.setCenter(center, newZoom);
		GoogleMapResults.handleViewChange();
  },
  
  handleZoom: function(map) {
    GoogleMapResults.handleViewChange();
  },
  
  handleMove: function(map) {
    GoogleMapResults.handleViewChange();
  },
  
  handleDragStart: function(map)
  {
    if (GoogleMapResults.currentWindow && !GoogleMapResults.currentWindow.isHidden())
    {
      GoogleMapResults.currentWindow.hide();
    }    
  },
  
  handleDragEnd: function(map) {
    GoogleMapResults.handleViewChange();
  },
  
  getPixelPositionFromCoords: function(marker)
  {
    var point = GoogleMapResults.map.fromLatLngToDivPixel(marker.getLatLng());
    var origin = GoogleMapResults.map.fromLatLngToDivPixel(
      GoogleMapResults.map.fromContainerPixelToLatLng(new GPoint(0,0)));
    
    var x = point.x - origin.x;
    var y = point.y - origin.y;
    
    return {x: x, y: y};
  },
  
  showPins: function(type)
  {
    var markers = this.markers[type];
    if (markers)
    {
      for (var i = 0; i < markers.length; i++)
      {
        markers[i].show();
      }
    }
    if (this.currentWindow)
    {
      this.currentWindow.hide();
    }
  },
  
  hidePins: function(type)
  {
    var markers = this.markers[type];
    if (markers)
    {
      for (var i = 0; i < markers.length; i++)
      {
        markers[i].hide();
      }
    }
    if (this.currentWindow)
    {
      this.currentWindow.hide();
    }
  },

  handleViewChange: function()
  {
    // timeout already running?
    if (GoogleMapResults.waitingMap) {
      // clear!
      clearTimeout(GoogleMapResults.waitingMap);
      GoogleMapResults.waitingMap = null;
    }

		GoogleMapResults.map.clearOverlays();
	  GoogleMapResults.waitingMap = setTimeout(function() { GoogleMapResults.handleViewChangeTimed(); }, 50);
  },
  
  handleViewChangeTimed: function()
  {
    if (GoogleMapResults.currentWindow)
    {
      GoogleMapResults.currentWindow.hide();
      GoogleMapResults.currentWindow = null;
    }

    //var boundsEl = document.getElementById('googleMapSearchBounds');
    //var zoomEl = document.getElementById('googleMapSearchZoom');
    //var bounds = GoogleMapResults.getCurrentPosition();
    //boundsEl.value = [bounds.SW.lat, bounds.SW.lng, bounds.NE.lat, bounds.NE.lng].join(",");
    //zoomEl.value = GoogleMapResults.map.getZoom();

    //GoogleMapResults.updateMapLinks(boundsEl.value, zoomEl.value);

    var bounds = GoogleMapResults.getCurrentPosition();
    var boundsStr = [bounds.SW.lat, bounds.SW.lng, bounds.NE.lat, bounds.NE.lng].join(",");
    var zoom = GoogleMapResults.map.getZoom();

    GoogleMapResults.updateMapLinks(boundsStr, zoom);

    // fires search to get new totals for map
    dataCollector.getTotalsMap();
  },
  
  getCurrentPosition: function()
  {
    var bounds = GoogleMapResults.map.getBounds();
    var SWLatLng = bounds.getSouthWest();
    var NELatLng = bounds.getNorthEast();
    
    var SW = { lat: SWLatLng.lat(), lng: SWLatLng.lng() };
    var NE = { lat: NELatLng.lat(), lng: NELatLng.lng() };
    
    return { SW: SW, NE: NE };
  }
};

function GoogleMapResultsInfoWindow(pos, infoWindowId) {
  this.init(pos, infoWindowId);
}
GoogleMapResultsInfoWindow.prototype = new GoogleMapInfoWindow(null, null);

GoogleMapResultsInfoWindow.prototype.show = function(cluster)
{
  this.toHtml(cluster);
  GoogleMapInfoWindow.prototype.show.apply(this, arguments);
};

GoogleMapResultsInfoWindow.prototype.getAccFromCluster = function(cluster) {
  return {
    id:               cluster.getElementsByTagName('accommodation')[0].getAttribute("id"),
    code:             cluster.getElementsByTagName('accommodation')[0].getAttribute("code"),
    url: cluster.getElementsByTagName('url')[0].text || cluster.getElementsByTagName('url')[0].innerHTML || cluster.getElementsByTagName('url')[0].textContent,
    title: cluster.getElementsByTagName('name')[0].text || cluster.getElementsByTagName('name')[0].innerHTML || cluster.getElementsByTagName('name')[0].textContent,
    country: cluster.getElementsByTagName('country')[0].text || cluster.getElementsByTagName('country')[0].innerHTML || cluster.getElementsByTagName('country')[0].textContent,
    region: cluster.getElementsByTagName('region')[0].text || cluster.getElementsByTagName('region')[0].innerHTML || cluster.getElementsByTagName('region')[0].textContent,
    city: cluster.getElementsByTagName('city')[0].text || cluster.getElementsByTagName('city')[0].innerHTML || cluster.getElementsByTagName('city')[0].textContent,
    type: cluster.getElementsByTagName('typeDescription')[0].text || cluster.getElementsByTagName('typeDescription')[0].innerHTML || cluster.getElementsByTagName('typeDescription')[0].textContent,
    photo: cluster.getElementsByTagName('photo')[0].text || cluster.getElementsByTagName('photo')[0].innerHTML || cluster.getElementsByTagName('photo')[0].textContent,
    isSelectCamp:     cluster.getElementsByTagName('accommodation')[0].getAttribute("isSelectCamp") == "true",
    isCamp2Relax:     cluster.getElementsByTagName('accommodation')[0].getAttribute("isCamp2Relax") == "true"
  };
};
  
GoogleMapResultsInfoWindow.prototype.toHtml = function(cluster) {  
  var acc = this.getAccFromCluster(cluster);
  
  var infoWindowEl = document.getElementById('googleMapResultsInfoWindow');
  var submitEl = document.getElementById('googleMapResultsInfoWindowSubmitButton').getElementsByTagName('a')[0];
  
  var titleEl = document.getElementById('googleMapResultsInfoWindowTitle');
  titleEl.innerHTML = acc.title;
  titleEl.href = submitEl.href = acc.url;
  
  var countryEl = document.getElementById('googleMapResultsInfoWindowCountry');
  countryEl.innerHTML = acc.country;
  
  var regionEl = document.getElementById('googleMapResultsInfoWindowRegion');
  regionEl.innerHTML = acc.region;
  
  var cityEl = document.getElementById('googleMapResultsInfoWindowCity');
  cityEl.innerHTML = acc.city;
  
  var typeEl = document.getElementById('googleMapResultsInfoWindowContentType');
  typeEl.innerHTML = acc.type;
  
  var photoEl = document.getElementById('googleMapResultsInfoWindowContentPhoto');
  photoEl.src = acc.photo;
  
  if (acc.isSelectCamp)
  {
    Spif.ClassNameAbstraction.add(infoWindowEl, "showSelectCamp");
  }
  else
  {
    Spif.ClassNameAbstraction.remove(infoWindowEl, "showSelectCamp");
  }
  
  if (acc.isCamp2Relax)
  {
    Spif.ClassNameAbstraction.add(infoWindowEl, "showCamp2Relax");
  }
  else
  {
    Spif.ClassNameAbstraction.remove(infoWindowEl, "showCamp2Relax");
  }
  
  var footerEl = document.getElementById('googleMapResultsInfoWindowContentFooter');
  var href = footerEl.getElementsByTagName('a')[0];
  href.id = "add-to-favorites_" + acc.id;
  href.className = href.className.replace(/ code-(.+)\b/, '');
  href.className += " code-" + acc.code;
  Spif.DOMEvents.attach(href, "click", function(){ favorites.addItemToFavs(href) });
  
  if (Cookie.read("favorites").indexOf(acc.id) != -1)
  {
    if (!Spif.ClassNameAbstraction.contains("added"))
    {
      Spif.ClassNameAbstraction.add(href, "added");
    }
    href.innerHTML = resources.messages.favorites.already_added;
  }
  else
  {
    href.innerHTML = resources.messages.favorites.add_to_favorites;
  }
};
