﻿/* Copyright (c) Hoseasons Holidays Limited
 * Authors: Chris O'Brien
 * Date: 2nd July 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: "",
  regionLat: 54.313919,
  regionLong: -2.23218,
  zoom: 12,
  distance: 20,
  _minZoom: 5,
  _maxZoom: 14,
  
  // Cluster markers will be plotted along with the single markers for each zoom level.
  // A single click on a cluster marker will zoom into max zoom and show the individual cottages with out any clustering.
  // The name in the cluserMarkers object is the zoom level. i.e. Number between 6 and 14. Example:
  // clusterMarkers = {
  //  6 : [ { marker: GMarker, lat: 50.0, lng: 0.0, count: 5 }, { lat: 50.37, lng: 0.0, count: 5 } ],
  //  7 : []
  //};
  clusterMarkers: { },
  
  //  Single markers will contain only cottages at each zoom level that do no fall in a cluster marker.
  //  The name is the zoom level and value is an array of siteCodes that can be used to reference the siteData object. Example:
  //  singleMarkers = {
  //    6 : ['A004', 'A017'],
  //    7 : []
  //  };
  singleMarkers: { },
  
  //  Object with name of siteCode that is referenced from singleMarkers and
  //  value of { marker: GMarker, clickHandler: function, lng: number, lat: number, name: string, address: string, image: string,
  //        distance: number, siteCode: string, accommodationCode: string, place: string,
  //        county: string, maxSleepCount: number, isInShortlist: boolean, priceRange: string,
  //        introText: string, minPrice: string, isComplex: boolean, uniqueInfo: string }
  //  siteData = { 
  //    'A004' : {},
  //    'A017' : {}
  //  };
  siteData: { },
  
  overlays: [],
  
  /// <summary>
  /// This should be called by the page's onload event.
  /// </summary>
  mapLoad: function() {
    //try { Throbber.beginRequest(); } catch (error) { alert(Error); }
    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.enableScrollWheelZoom();
      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._minZoom };
      G_NORMAL_MAP.getMinimumResolution = function() { return Hos.MaxiMap._minZoom };
      G_SATELLITE_MAP.getMinimumResolution = function() { return Hos.MaxiMap._minZoom };
      G_HYBRID_MAP.getMinimumResolution = function() { return Hos.MaxiMap._minZoom };

      G_PHYSICAL_MAP.getMaximumResolution = function() { return Hos.MaxiMap._maxZoom };
      G_NORMAL_MAP.getMaximumResolution = function() { return Hos.MaxiMap._maxZoom };
      G_SATELLITE_MAP.getMaximumResolution = function() { return Hos.MaxiMap._maxZoom };
      G_HYBRID_MAP.getMaximumResolution = function() { return Hos.MaxiMap._maxZoom };

      Hos.MaxiMap.PlotPointOnMap();
    }
    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 = '#000';

    // Insert into map container
    this.getContainer().insertBefore(info, this.getContainer().firstChild);
  },
  
  PlotPointOnMap: function() {
    Hos.MaxiMap.startingpoint = new GLatLng(Hos.MaxiMap.regionLat, Hos.MaxiMap.regionLong);
    Hos.MaxiMap.map.setCenter(Hos.MaxiMap.startingpoint, parseInt(Hos.MaxiMap.zoom));
    Hos.MaxiMap.CallSuccess({clusterMarkers : Hos.MaxiMap.clusterMarkers, singleMarkers : Hos.MaxiMap.singleMarkers, siteData : Hos.MaxiMap.siteData });
  },
  
  setmapcenter: function() {
    Hos.MaxiMap.map.setCenter(Hos.MaxiMap.startingpoint, parseInt(Hos.MaxiMap.zoom));
  },
  
  usePointFromPostcode: function(pCode, callbackFunction) {
    Hos.MaxiMap.localSearch.setSearchCompleteCallback(null, function() {
      var resultLat = 54.313919;
      var resultLng = -2.23218;
      if (Hos.MaxiMap.localSearch.results[0]) {
        resultLat = Hos.MaxiMap.localSearch.results[0].lat;
        resultLng = Hos.MaxiMap.localSearch.results[0].lng;
      }
      if (!Hos.MaxiMap.localSearch.results[0] || resultLat < 48.5083 || resultLat > 60.0 || resultLng < -8.63 || resultLng > 2.0) {
        resultLat = 54.313919;
        resultLng = -2.23218;
        try {
          document.getElementById('noResultsMessage').style.display = 'block';
        } catch (Error) {};
        return;
      }
      
      var point = new GLatLng(resultLat, resultLng);
      var marker = new GMarker(point, Hos.MaxiMap.GetCentreIcon());
      Hos.MaxiMap.map.setCenter(point, parseInt(Hos.MaxiMap.zoom));
      Hos.MaxiMap.map.addOverlay(marker);
      Hos.MaxiMap.startingpoint = point;
      callbackFunction(resultLat, resultLng);
    });
    Hos.MaxiMap.localSearch.execute(pCode + ", UK");
  },
  
  GetCottageIcon: function() {
    var icon = new GIcon();
    icon.image = "../../Images/UKCottage/GoogleMapIcons/Complex.png";
    icon.iconAnchor = new GPoint(16, 16);
    icon.infoWindowAnchor = new GPoint(16, 0);
    icon.iconSize = new GSize(33, 28);
    return icon;
  },
  
  GetCottageClusterIcon: function(number) {
    //Icons only go upto 15.
    if (number > 15) {
      number = 15;
    }
    var icon = new GIcon();
    icon.image = "../../Images/UKCottage/GoogleMapIcons/ComplexCluster" + number + ".png";
    icon.iconAnchor = new GPoint(16, 16);
    icon.infoWindowAnchor = new GPoint(16, 0);
    icon.iconSize = new GSize(49, 32);
    return icon;
  },
  
  createMarkerClickHandler: function(site) {
    //Clip intro text.
    var introText = site.introText + "...";

    return function() {
      scrollTo(0, 180);
      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="../UKCottage/ProductDetailPage.aspx?ISDLNK=1&amp;SCODE=' + site.siteCode + '&ACODE=' + site.accommodationCode + '&TIDPDUKCOTTAGE=cottageComplex\
                  ">' + site.name + '</a>\
                <br/>\
                <p id="introText">' + introText + '</p>\
              </td>\
              <td>\
                <a href="../UKCottage/ProductDetailPage.aspx?ISDLNK=1&amp;SCODE=' + site.siteCode + '&ACODE=' + site.accommodationCode + '&TIDPDUKCOTTAGE=cottageComplex\
                   "><img id="searchResultImage"\ src="' + site.image + '"></a>\
              </td>\
            </tr>\
            <tr >\
              <td>\
                <div id="viewComplex">\
                  <a href="../UKCottage/ProductDetailPage.aspx?ISDLNK=1&amp;SCODE=' + site.siteCode + '&ACODE=' + site.accommodationCode + '&TIDPDUKCOTTAGE=cottageComplex">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();
  },
  
  CallSuccessString: function(res) {
    Hos.MaxiMap.CallSuccess(eval("(" + res + ")"));
  },
  
  //res will have the form res = { clusterMarkers : { },  singleMarkers : { },  siteData : { }}
  CallSuccess: function(res) {
    Hos.MaxiMap.clusterMarkers = res.clusterMarkers;
    Hos.MaxiMap.singleMarkers = res.singleMarkers;
    Hos.MaxiMap.siteData = res.siteData;
    
    //Create Markers
    var index = 0;
    for(i in Hos.MaxiMap.siteData) {
      var site = Hos.MaxiMap.siteData[i];
      Hos.MaxiMap.siteData[i].marker = Hos.MaxiMap.createMarker(parseFloat(site.lat), parseFloat(site.lng));
        
      var handler = Hos.MaxiMap.createMarkerClickHandler(Hos.MaxiMap.siteData[i]);
      GEvent.addListener(Hos.MaxiMap.siteData[i].marker, "click", handler);
      Hos.MaxiMap.siteData[i].clickHandler = handler;
      index++;
    }
    Hos.MaxiMap.count = index;
    for(i in Hos.MaxiMap.clusterMarkers) {
      for(var k = 0; k < Hos.MaxiMap.clusterMarkers[i].length; k++) {
        Hos.MaxiMap.clusterMarkers[i][k].marker = Hos.MaxiMap.createClusterMarker(Hos.MaxiMap.clusterMarkers[i][k].lat,
         Hos.MaxiMap.clusterMarkers[i][k].lng, Hos.MaxiMap.clusterMarkers[i][k].count);
      }
    }

    Hos.MaxiMap.drawOverlays(); //Uses Hos.MaxiMap.clusterMarkers and Hos.MaxiMap.singleMarkers
  },
  
  drawOverlays: function() {
    try {
      //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 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();

      var clusterMarkersForZoom = Hos.MaxiMap.clusterMarkers[zoom];
      var singleMarkersForZoom = Hos.MaxiMap.singleMarkers[zoom];

      //Draw single markers.
      var singleSiteData = {};
      for (var k = 0; k < singleMarkersForZoom.length; k++) {
        if(Hos.MaxiMap.siteData[singleMarkersForZoom[k]]) {
          singleSiteData = Hos.MaxiMap.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.GetCottageClusterIcon(count));
    var handler = Hos.MaxiMap.createClusterMarkerClickHandler(marker);
    GEvent.addListener(marker, "click", handler);
    return marker;
  },
  
  createMarker: function(lat, lng) {
    var point = new GLatLng(lat, lng);
    var marker;
    marker = new GMarker(point, Hos.MaxiMap.GetCottageIcon());
    return marker;
  },
  
  viewOnMapClick: function(siteCode) {
    try {
      Hos.MaxiMap.siteData[siteCode].clickHandler();
    } catch(Error) { }
  }
}
