﻿/* Copyright (c) Hoseasons Holidays Limited
 * Author: Chris O'Brien
 * Date: 19th August 2009
 */
 
 /// <summary>
/// Make sure global namespace Hos for all hoseasons JavaScript is defined.
/// </summary>
if (typeof Hos == 'undefined') {
Hos = {};
}

/// <summary>
/// Maxi map.
/// </summary>

Hos.MaxiMap = {
  MAP_CANVAS_ID: "map_canvas",
  map: null,
  startingpoint: "",
  count: 0,
  data: {
    center: { lat: 0.0, lng: 0.0 },
    freeTypeLocation: { lat: 0.0, lng: 0.0 },
    minZoom: 3,
    maxZoom: 14,
    zoom: 6,
    clusterMarkers: {},
    singleMarkers: {},
    siteData: {},
    airportsAndPorts: [],
    proximitySearch: false
  },
  overlays: [],
  airportsAndPortsOn: false,


  /// <summary>
  /// This should be called by the page's onload event.
  /// </summary>
  mapLoad: function() {
    if (GBrowserIsCompatible()) {
      Hos.MaxiMap.localSearch = new GlocalSearch();
      Hos.MaxiMap.map = new GMap2(document.getElementById(this.MAP_CANVAS_ID));
      GEvent.addListener(Hos.MaxiMap.map, "load", Hos.MaxiMap.addLoadingReport);
      Hos.MaxiMap.map.addControl(new GMapTypeControl());
      Hos.MaxiMap.map.addControl(new GLargeMapControl());
      Hos.MaxiMap.map.addControl(new GScaleControl());
      G_PHYSICAL_MAP.getMinimumResolution = function() { return Hos.MaxiMap.data.minZoom };
      G_NORMAL_MAP.getMinimumResolution = function() { return Hos.MaxiMap.data.minZoom };
      G_SATELLITE_MAP.getMinimumResolution = function() { return Hos.MaxiMap.data.minZoom };
      G_HYBRID_MAP.getMinimumResolution = function() { return Hos.MaxiMap.data.minZoom };

      G_PHYSICAL_MAP.getMaximumResolution = function() { return Hos.MaxiMap.data.maxZoom };
      G_NORMAL_MAP.getMaximumResolution = function() { return Hos.MaxiMap.data.maxZoom };
      G_SATELLITE_MAP.getMaximumResolution = function() { return Hos.MaxiMap.data.maxZoom };
      G_HYBRID_MAP.getMaximumResolution = function() { return Hos.MaxiMap.data.maxZoom };

      Hos.MaxiMap.PlotPointOnMap();
      scrollTo(0, 180);
    }
    GEvent.addListener(Hos.MaxiMap.map, "zoomend", Hos.MaxiMap.mapOnZoomEnd);
    GEvent.addListener(Hos.MaxiMap.map, "dragend", Hos.MaxiMap.mapOnDragEnd);
  },

  addLoadingReport: function() {
    // Text to display 
    var loadingText = 'Loading Map...';

    // Create a new element 
    var info = document.createElement('div');
    info.appendChild(document.createTextNode(loadingText));

    // Add an id to the element, in case you want to access it later 
    info.setAttribute('id', 'mapLoading');

    // Alternatively, you could apply the styles through a CSS stylesheet, using the #mapLoading selector 
    info.style.position = 'relative';
    info.style.padding = '2em';
    info.style.fontWeight = 'bold';
    info.style.fontSize = '12px';
    info.style.color = '#333';

    // Insert into map container
    this.getContainer().insertBefore(info, this.getContainer().firstChild);
  },

  PlotPointOnMap: function() {
    Hos.MaxiMap.startingpoint = new GLatLng(Hos.MaxiMap.data.center.lat, Hos.MaxiMap.data.center.lng);
    Hos.MaxiMap.map.setCenter(Hos.MaxiMap.startingpoint, parseInt(Hos.MaxiMap.data.zoom));
    if (Hos.MaxiMap.data.proximitySearch) {
      Hos.MaxiMap.map.addOverlay(new GMarker(
          new GLatLng(Hos.MaxiMap.data.freeTypeLocation.lat, Hos.MaxiMap.data.freeTypeLocation.lng),
          Hos.MaxiMap.GetCentreIcon()
        ));
    }
    Hos.MaxiMap.CallSuccess();
  },

  setmapcenter: function() {
    Hos.MaxiMap.map.setCenter(Hos.MaxiMap.startingpoint, parseInt(Hos.MaxiMap.zoom));
  },

  GetIcon: function() {
    var icon = new GIcon();
    icon.image = "../../Images/EUVilla/GoogleMapIcons/Complex.png";
    icon.iconAnchor = new GPoint(24, 15);
    icon.infoWindowAnchor = new GPoint(16, 0);
    icon.iconSize = new GSize(49, 31);
    return icon;
  },

  GetClusterIcon: function(number) {
    //Icons only go upto 15.
    if (number > 15) {
      number = 15;
    }
    var icon = new GIcon();
    icon.image = "../../Images/EUVilla/GoogleMapIcons/ComplexCluster" + number + ".png";
    icon.iconAnchor = new GPoint(29, 15);
    icon.infoWindowAnchor = new GPoint(16, 0);
    icon.iconSize = new GSize(58, 30);
    return icon;
  },

  GetCentreIcon: function() {
    var icon = new GIcon();
    icon.image = "../../Images/EUVilla/GoogleMapIcons/CenterMarker.png";
    icon.iconAnchor = new GPoint(16, 16);
    icon.infoWindowAnchor = new GPoint(16, 0);
    icon.iconSize = new GSize(54, 44);
    return icon;
  },

  createMarkerClickHandler: function(site) {
    //Clip intro text.
    var introText = site.introText + "...";

    return function() {
      try {
        if (!site.marker.overlayOn) {
          Hos.MaxiMap.map.addOverlay(site.marker);
          site.marker.overlayOn = true;
          Hos.MaxiMap.map.setCenter(site.marker.getLatLng(), Hos.MaxiMap.viewOnMapZoom);
        }
        site.marker.openInfoWindowHtml(
          '<table id="balloon">\
            <tr>\
              <td>\
                <a id="balloonTitle" href="ProductDetailPage.aspx?ISDLNK=1&amp;SCODE=' + site.siteCode + '&ACODE=' + site.accommodationCode + '&TID=villaComplex\
                  ">' + site.name + '</a>\
                <br/>\
                <span class="SleepLbl">Sleeps: </span><span class="SleepText">' + site.sleepText + '</span><br/>\
                ' + (site.price ? '<span class="PriceLbl">Price from: </span><span class="PriceText">' + site.price + '</span>' : '') + '\
                <p id="introText">' + site.introText + '</p>\
              </td>\
              <td>\
                <a href="ProductDetailPage.aspx?ISDLNK=1&amp;SCODE=' + site.siteCode + '&ACODE=' + site.accommodationCode + '&TID=villaComplex\
                   "><img id="searchResultImage"\ src="' + site.image + '"></a>\
              </td>\
            </tr>\
            <tr >\
              <td>\
                <div id="viewComplex">\
                  <a href="ProductDetailPage.aspx?ISDLNK=1&amp;SCODE=' + site.siteCode + '&ACODE=' + site.accommodationCode + '&TID=villaComplex">Read more>></a>\
                </div>\
              </td>\
            </tr>\
          </table>'
        );
      }
      catch (Error) {
      }
      return false;
    };
  },

  createClusterMarkerClickHandler: function(marker) {
    return function() {
      Hos.MaxiMap.map.setCenter(marker.getLatLng());
      Hos.MaxiMap.map.zoomIn();
      return false;
    };
  },

  mapOnZoomEnd: function(oldZoom, newZoom) {
    Hos.MaxiMap.zoom = newZoom;
    Hos.MaxiMap.drawOverlays();
  },

  mapOnDragEnd: function() {
    Hos.MaxiMap.drawOverlays();
  },

  CallSuccess: function() {

    //Create Markers
    var index = 0;
    for (i in Hos.MaxiMap.data.siteData) {
      var site = Hos.MaxiMap.data.siteData[i];

      Hos.MaxiMap.data.siteData[i].marker = Hos.MaxiMap.createMarker(parseFloat(site.lat), parseFloat(site.lng));

      var handler = Hos.MaxiMap.createMarkerClickHandler(Hos.MaxiMap.data.siteData[i]);
      GEvent.addListener(Hos.MaxiMap.data.siteData[i].marker, "click", handler);
      Hos.MaxiMap.data.siteData[i].clickHandler = handler;
      index++;
    }
    Hos.MaxiMap.count = index;
    for (i in Hos.MaxiMap.data.clusterMarkers) {
      for (var k = 0; k < Hos.MaxiMap.data.clusterMarkers[i].length; k++) {
        Hos.MaxiMap.data.clusterMarkers[i][k].marker = Hos.MaxiMap.createClusterMarker(Hos.MaxiMap.data.clusterMarkers[i][k].lat,
         Hos.MaxiMap.data.clusterMarkers[i][k].lng, Hos.MaxiMap.data.clusterMarkers[i][k].count);
      }
    }

    if (Hos.MaxiMap.data.airportsAndPorts) Hos.MaxiMap.plotAirportsAndPorts(Hos.MaxiMap.data.airportsAndPorts);
    Hos.MaxiMap.drawOverlays(); //Uses Hos.MaxiMap.clusterMarkers and Hos.MaxiMap.singleMarkers
  },

  drawOverlays: function() {
    try {
      var latitude = 0.0;
      var longitude = 0.0;

      //Divide map into grid.
      var gLatLngBounds = Hos.MaxiMap.map.getBounds();
      var southWest = gLatLngBounds.getSouthWest();
      var northEast = gLatLngBounds.getNorthEast();
      var zoom = Hos.MaxiMap.map.getZoom();

      //Airports and ports
      if (Hos.MaxiMap.airportsAndPortsOn && zoom < 5) { // Clear Airport and port Markers
        Hos.MaxiMap.airportsAndPortsOn = false;
        for (var k = 0; k < Hos.MaxiMap.data.airportsAndPorts.length; k++) {
          Hos.MaxiMap.map.removeOverlay(Hos.MaxiMap.data.airportsAndPorts[k].marker);
        }
      }
      if (!Hos.MaxiMap.airportsAndPortsOn && zoom > 4) { // Add Airport and port Markers
        Hos.MaxiMap.airportsAndPortsOn = true;
        for (var k = 0; k < Hos.MaxiMap.data.airportsAndPorts.length; k++) {
          Hos.MaxiMap.map.addOverlay(Hos.MaxiMap.data.airportsAndPorts[k].marker);
        }
      }

      //Clear overlays
      for (var k = 0; k < Hos.MaxiMap.overlays.length; k++) {
        Hos.MaxiMap.overlays[k].overlayOn = false;
        Hos.MaxiMap.map.removeOverlay(Hos.MaxiMap.overlays[k]);
      }
      Hos.MaxiMap.overlays = [];


      var clusterMarkersForZoom = Hos.MaxiMap.data.clusterMarkers[zoom];
      var singleMarkersForZoom = Hos.MaxiMap.data.singleMarkers[zoom];

      //Draw single markers.
      var singleSiteData = {};
      for (var k = 0; k < singleMarkersForZoom.length; k++) {
        if (Hos.MaxiMap.data.siteData[singleMarkersForZoom[k]]) {
          singleSiteData = Hos.MaxiMap.data.siteData[singleMarkersForZoom[k]];
          if (singleSiteData.lng > southWest.lng() && singleSiteData.lng < northEast.lng() &&
            singleSiteData.lat > southWest.lat() && singleSiteData.lat < northEast.lat()) {
            Hos.MaxiMap.drawSingleOverlay(singleSiteData);
          }
        }
      }

      //Draw cluster markers
      for (var k = 0; k < clusterMarkersForZoom.length; k++) {
        clusterMarkerData = clusterMarkersForZoom[k];
        if (clusterMarkerData.lng > southWest.lng() && clusterMarkerData.lng < northEast.lng() &&
            clusterMarkerData.lat > southWest.lat() && clusterMarkerData.lat < northEast.lat()) {
          Hos.MaxiMap.drawClusterMarker(clusterMarkerData);
        }
      }
    } catch (Error) { }
  },

  drawSingleOverlay: function(markerData) {
    Hos.MaxiMap.map.addOverlay(markerData.marker);
    markerData.marker.overlayOn = true;
    Hos.MaxiMap.overlays.push(markerData.marker);
  },

  drawClusterMarker: function(markerData) {
    Hos.MaxiMap.map.addOverlay(markerData.marker);
    markerData.marker.overlayOn = true;
    Hos.MaxiMap.overlays.push(markerData.marker);
  },

  createClusterMarker: function(lat, lng, count) {
    var point = new GLatLng(lat, lng);
    var marker = new GMarker(point, Hos.MaxiMap.GetClusterIcon(count));
    var handler = Hos.MaxiMap.createClusterMarkerClickHandler(marker);
    GEvent.addListener(marker, "click", handler);
    return marker;
  },

  createMarker: function(lat, lng) {
    var point = new GLatLng(lat, lng);
    return new GMarker(point, Hos.MaxiMap.GetIcon());
  },

  viewOnMapClick: function(siteCode) {
    try {
      Hos.MaxiMap.data.siteData[siteCode].clickHandler();
    } catch (Error) { }
  },

  plotAirportsAndPorts: function(airportsAndPorts) {
    var baseIcon = new GIcon(G_DEFAULT_ICON);
    baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
    baseIcon.iconSize = new GSize(24, 24);
    baseIcon.shadowSize = new GSize(37, 24);
    baseIcon.iconAnchor = new GPoint(12, 12);
    baseIcon.infoWindowAnchor = new GPoint(9, 2);

    for (var k = 0; k < airportsAndPorts.length; k++) {
      var icon = new GIcon(baseIcon);
      icon.image = airportsAndPorts[k].type == "airport" ? "../../Images/EUVilla/GoogleMapIcons/airportIcon.png" : "../../Images/EUVilla/GoogleMapIcons/ferryIcon.png";
      var marker = new GMarker(new GLatLng(airportsAndPorts[k].lat, airportsAndPorts[k].lng), icon);
      GEvent.addListener(marker, "click", createClickHandler(marker, airportsAndPorts[k]));
      //Hos.MaxiMap.map.addOverlay(marker);
      airportsAndPorts[k].marker = marker;
    }
    function createClickHandler(marker, airportOrPort) {
      return function() {
        marker.openInfoWindowHtml(
          '<table id="balloon">\
            <tr>\
              <td>\
                <h3>' + airportOrPort.name + (airportOrPort.code ? ' (' + airportOrPort.code + ')' : '') + '</h3>\
              </td>\
            </tr>\
          </table>'
        );
      }
    }
  }
}