﻿/* 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 = {};
}
    
Hos.PromoMap = {
  MAP_CANVAS_ID: "map_canvas",
  map: null,
  regionLat: 54.313919,
  regionLong: -2.23218,
  zoom: 12,
  _minZoom: 5,
  _maxZoom: 17,
  markersData: [],
  isParkMode: true,
  overlays: [],
  
  mapLoad: function() {
    if (GBrowserIsCompatible()) {
      Hos.PromoMap.map = new GMap2(document.getElementById(this.MAP_CANVAS_ID));
      GEvent.addListener(Hos.PromoMap.map, "load", Hos.PromoMap.addLoadingReport);
      Hos.PromoMap.map.enableScrollWheelZoom();
      Hos.PromoMap.map.addControl(new GMapTypeControl());
      Hos.PromoMap.map.addControl(new GLargeMapControl());
      Hos.PromoMap.map.addControl(new GScaleControl());
      G_PHYSICAL_MAP.getMinimumResolution = function() { return Hos.PromoMap._minZoom };
      G_NORMAL_MAP.getMinimumResolution = function() { return Hos.PromoMap._minZoom };
      G_SATELLITE_MAP.getMinimumResolution = function() { return Hos.PromoMap._minZoom };
      G_HYBRID_MAP.getMinimumResolution = function() { return Hos.PromoMap._minZoom };

      G_PHYSICAL_MAP.getMaximumResolution = function() { return Hos.PromoMap._maxZoom };
      G_NORMAL_MAP.getMaximumResolution = function() { return Hos.PromoMap._maxZoom };
      G_SATELLITE_MAP.getMaximumResolution = function() { return Hos.PromoMap._maxZoom };
      G_HYBRID_MAP.getMaximumResolution = function() { return Hos.PromoMap._maxZoom };
      
      Hos.PromoMap.startingpoint = new GLatLng(54.313919, -2.23218);
      Hos.PromoMap.map.setCenter(Hos.PromoMap.startingpoint, parseInt(Hos.PromoMap.zoom));
      
      GEvent.addListener(Hos.PromoMap.map, "zoomend", Hos.PromoMap.mapOnZoomEnd);
      GEvent.addListener(Hos.PromoMap.map, "dragend", Hos.PromoMap.mapOnDragEnd);
      
      Hos.PromoMap.PlotPointOnMap();
    }
  },
  
  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.PromoMap.startingpoint = new GLatLng(Hos.PromoMap.regionLat, Hos.PromoMap.regionLong);
    Hos.PromoMap.map.setCenter(Hos.PromoMap.startingpoint, parseInt(Hos.PromoMap.zoom));
    Hos.PromoMap.CallSuccess(Hos.PromoMap.markersData);
  },
  
  setmapcenter: function() {
    Hos.PromoMap.map.setCenter(Hos.MaxiMap.startingpoint, parseInt(Hos.PromoMap.zoom));
  },
  
  GetParkIcon: function() {
    var icon = new GIcon();
    icon.image = Hos.PromoMap.isParkMode ? "../../Images/UKPark/GoogleMapIcons/Complex.png" : "../../Images/Lodge/GoogleMapIcons/Complex.png";
    icon.iconAnchor = new GPoint(11, 47);
    icon.infoWindowAnchor = new GPoint(16, 0);
    icon.iconSize = new GSize(64, 53);
    return icon;
  },
  
  GetParkClusterIcon: function(number) {
    //Icons only go upto 15.
    if (number > 15) {
      number = 15;
    }
    var icon = new GIcon();
    icon.image = Hos.PromoMap.isParkMode ? "../../Images/UKPark/GoogleMapIcons/ComplexCluster" + number + ".png" : "../../Images/Lodge/GoogleMapIcons/ComplexCluster" + number + ".png";
    icon.iconAnchor = new GPoint(11, 47);
    icon.infoWindowAnchor = new GPoint(16, 0);
    icon.iconSize = new GSize(64, 53);
    return icon;
  },
  
  createMarkerClickHandler: function(marker, uKParkSite) {
    return function() {
      scrollTo(0, 180);
      try {
        if (!marker.overlayOn) {
          Hos.PromoMap.map.addOverlay(marker);
          marker.overlayOn = true;
          Hos.PromoMap.map.setCenter(marker.getLatLng(), Hos.PromoMap.viewOnMapZoom);
        }
        marker.openInfoWindowHtml(
          '<table id="balloon">\
            <tr>\
              <td>\
                <a id="balloonTitle" href="../UKPark/ProductDetailPage.aspx?ISDLNK=1&amp;SCODE=' + uKParkSite.siteCode + '&ISPKMD=' + Hos.PromoMap.isParkMode + '\
                  ">' + uKParkSite.name + '</a>\
                <br/>\
                <span id="weeklyPriceFrom">Prices from </span>\
                <span id="minPrice">' + uKParkSite.minPrice + '</span>\
                <p id="introText">' + uKParkSite.introText + '</p>\
              </td>\
              <td>\
                <a href="../UKPark/ProductDetailPage.aspx?ISDLNK=1&amp;SCODE=' + uKParkSite.siteCode + '&ISPKMD=' + Hos.PromoMap.isParkMode + '\
                   "><img id="searchResultImage"\ src="' + uKParkSite.image + '"></a>\
              </td>\
            </tr>\
            <tr >\
              <td>\
                <div id="viewComplex">\
                  <a href="../UKPark/ProductDetailPage.aspx?ISDLNK=1&amp;SCODE=' + uKParkSite.siteCode + '&ISPKMD=' + Hos.PromoMap.isParkMode + '">Read more>></a>\
                </div>\
              </td>\
            </tr>\
          </table>'
        );
      }
      catch (Error) {
      }
      return false;
    };
  },
  
  createClusterMarkerClickHandler: function(marker) {
    return function() {
      Hos.PromoMap.map.setCenter(marker.getLatLng());
      Hos.PromoMap.map.zoomIn();
      return false;
    };
  },
  
  mapOnZoomEnd: function(oldZoom, newZoom) {
    Hos.PromoMap.zoom = newZoom;
    Hos.PromoMap.drawOverlays();
  },
  
  mapOnDragEnd: function() {
    Hos.PromoMap.drawOverlays();
  },
  
  CallSuccess: function(res) {
    //Hos.PromoMap.markersData = eval(res);
    if (!Hos.PromoMap.markersData) {
      Hos.PromoMap.markersData = [];
    }

    for (var i = 0; i < Hos.PromoMap.markersData.length; i++) {
      var latitude = parseFloat(Hos.PromoMap.markersData[i].lat);
      var longitude = parseFloat(Hos.PromoMap.markersData[i].lng);
      Hos.PromoMap.markersData[i].marker = Hos.PromoMap.createMarker(Hos.PromoMap.markersData[i]);
    }
    Hos.PromoMap.drawOverlays(); //Uses Hos.MaxiMap.markersData
  },
  
  drawOverlays: function() {

    //Clear overlays
    for (var k = 0; k < Hos.PromoMap.overlays.length; k++) {
      Hos.PromoMap.overlays[k].overlayOn = false;
      Hos.PromoMap.map.removeOverlay(Hos.PromoMap.overlays[k]);
    }
    Hos.PromoMap.overlays = [];

    try {
      var latitude = 0.0;
      var longitude = 0.0;

      //Divide map into grid.
      var gLatLngBounds = Hos.PromoMap.map.getBounds();
      var southWest = gLatLngBounds.getSouthWest();
      var northEast = gLatLngBounds.getNorthEast();
      var zoom = Hos.PromoMap.map.getZoom();

      if (zoom == Hos.PromoMap._maxZoom) { // Do not cluster when zoomed in this close.
        for (var k = 0; k < Hos.PromoMap.markersData.length; k++) {
          //Does fall in map area.
          if (Hos.PromoMap.markersData[k].lng > southWest.lng() && Hos.PromoMap.markersData[k].lng < northEast.lng() &&
            Hos.PromoMap.markersData[k].lat > southWest.lat() && Hos.PromoMap.markersData[k].lat < northEast.lat()) {
            Hos.PromoMap.drawSingleOverlay(Hos.PromoMap.markersData[k]);
          }
        }
      }
      else {

        //20x20 Grid. Each object in the grid will have the following properties when this method finishes { lngSW: 0.0, latSW: 0.0, lngNE: 0.0, latNE: 0.0, markerData: [] }
        var grid = [
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
        [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}]
        ];

        var fltGridWidth = parseFloat(grid[0].length);
        var fltGridHeight = parseFloat(grid.length);
        for (var y = grid.length - 1; y >= 0; y--) {
          for (var x = 0; x < grid[y].length; x++) {
            //Set bounds of grid cell.
            var cell = { latSW: 0.0, lngSW: 0.0, latNE: 0.0, lngNE: 0.0, markerData: [] };
            cell.lngSW = southWest.lng() + (x / fltGridWidth) * (northEast.lng() - southWest.lng());
            cell.latSW = southWest.lat() + (y / fltGridHeight) * (northEast.lat() - southWest.lat());
            cell.lngNE = southWest.lng() + ((x + 1) / fltGridWidth) * (northEast.lng() - southWest.lng());
            cell.latNE = southWest.lat() + ((y + 1) / fltGridHeight) * (northEast.lat() - southWest.lat());

            //Find all markers that fall in this grid cell.
            for (var k = 0; k < Hos.PromoMap.markersData.length; k++) {
              //Does marker intersect cell.
              if (Hos.PromoMap.markersData[k].lng > cell.lngSW && Hos.PromoMap.markersData[k].lng < cell.lngNE &&
                Hos.PromoMap.markersData[k].lat > cell.latSW && Hos.PromoMap.markersData[k].lat < cell.latNE) {
                cell.markerData.push(Hos.PromoMap.markersData[k]);
              }
            }

            //Put marker on map.
            if (cell.markerData.length == 0) { //Do not plot anything
            } else if (cell.markerData.length == 1) { //Plot the single park, not need to show cluster marker.
              Hos.PromoMap.drawSingleOverlay(cell.markerData[0]);
            } else {
              //Draw cluster marker in middle of grid. This could be changed to weight the position to the park locations
              //but could suffer a performance hit and also markers could be place near the edge of the grid.
              Hos.PromoMap.drawClusterMarker(cell.latSW + (cell.latNE - cell.latSW) / 2, cell.lngSW + (cell.lngNE - cell.lngSW) / 2, cell.markerData.length);
            }

            grid[(grid.length - 1) - y][x] = cell;
          }
        }
      }
    } catch (Error) {
    }
  },
  
  drawSingleOverlay: function(markerData) {
    try {
      Hos.PromoMap.map.addOverlay(markerData.marker);
      markerData.marker.overlayOn = true;
      Hos.PromoMap.overlays.push(markerData.marker);
    } catch (Error) {
    }
  },
  
  drawClusterMarker: function(lat, lng, count) {
    var point = new GLatLng(lat, lng);
    var marker;
    marker = new GMarker(point, Hos.PromoMap.GetParkClusterIcon(count));
    var handler = Hos.PromoMap.createClusterMarkerClickHandler(marker);
    GEvent.addListener(marker, "click", handler);
    Hos.PromoMap.map.addOverlay(marker);
    marker.overlayOn = true;
    Hos.PromoMap.overlays.push(marker);
  },
  
  createMarker: function(uKParkSite) {
    var point = new GLatLng(uKParkSite.lat, uKParkSite.lng);
    var tempCount = Hos.PromoMap.count + 1;
    var marker;
    marker = new GMarker(point, Hos.PromoMap.GetParkIcon());
    var handler = Hos.PromoMap.createMarkerClickHandler(marker, uKParkSite);
    GEvent.addListener(marker, "click", handler);
    return marker;
  }
}