/*
 * MapController class
 * Code based on Pentura prototype
 *
 * @author Matt Ladd
 */

function MapController()
{
  this.map = null;
}
 
var streetviewMap = null;
var worldMapBounds = null;
 
/*
 * Initializes the MapController - initial settings indicate the map co-ordinates that will be displayed.
 * map_div - the name of the <div> tag where the map (image) should be inserted on the page
 * latitiude - starting center latitude
 * longitude - starting center longitude
 * zoom - indicates the zoom factor on the map (zero indicates no zoom; eg. birds-eye-view)
 * callback - handle for callback
 */
MapController.prototype.initialize = function(map_div, latitude, longitude, zoom, callback)
{ 
  // verify browser compatibility
  if (!GBrowserIsCompatible()) alert("Sorry your browser is not compatible with Google Maps!");

  // create, initialize and insert the map into the div tag specified by 'map_div'
  this.map = new GMap2(document.getElementById(map_div));
  this.map.addControl(new GMapTypeControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(2,25)));
  this.map.enableContinuousZoom();
  this.map.setCenter(new GLatLng(latitude, longitude), zoom);
  this.map.setMapType(G_NORMAL_MAP);
  this.map.addControl(new GLargeMapControl(), new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(2,25)));
  this.geocoder = new GClientGeocoder();
  // set 'bounds' to the visible rectangular region of the map view in geographical coordinates.
  this.bounds = this.map.getBounds();
  // cache the bounds of the original world map for future use.
  this.worldMapBounds = this.map.getBounds();

  GEvent.addListener(this.map, "moveend", function() {
    callback(this.getBounds());
  });

  GEvent.addListener(this.map, "maptypechanged", function() {
    this.clearOverlays();
    APP_CONTROLLER.populateOfficeLocations(this);
  });

  streetviewMap = new GStreetviewPanorama(document.getElementById(map_div), {enableFullScreen:false});
  GEvent.addListener(this.map, "dblclick", function(overlay, latlng) {
    if (this.getZoom() >= 19) {
      streetviewMap.setLocationAndPOV(latlng);
    }
  });
}

MapController.prototype.clearMap = function() {
  this.map.clearOverlays();
}

MapController.prototype.getWorldMapBounds = function() {
  return this.worldMapBounds;
}

MapController.prototype.centreOnAddress = function(lat, lng, zoom) {
  streetviewMap.hide();

  var point = null;
  if(lat && lng)
    point = new GLatLng(lat, lng);
  else
    point = this.map.getCenter();

  this.map.setCenter(point, zoom);
}

MapController.prototype.addOfficeMarker = function(lat, lon, html, title) {
  var marker = null;
  var icon = this.map.getCurrentMapType() == G_NORMAL_MAP ? MapController.OFFICE_ICON_GREY : MapController.OFFICE_ICON_WHITE;
  var opts = {icon:icon};
  if (title) opts.title = title;
  marker = new GMarker(new GLatLng(lat,lon), opts);
  this.map.addOverlay(marker);
  marker.bindInfoWindowHtml(html, {maxWidth:280});
  return marker;
}

MapController.prototype.addEventMarker = function(lat, lon, html, title) {
  var marker = null;
  var icon = G_DEFAULT_ICON;
  var opts = {icon:icon};
  if (title) opts.title = title;
  marker = new GMarker(new GLatLng(lat,lon), opts);
  this.map.addOverlay(marker);
  marker.bindInfoWindowHtml(html, {maxWidth:280});
  return marker;
}

MapController.prototype.addEventBinMarker = function(lat, lon, html, num, title) {
  var marker = null;
  var iconOptions = {};
  iconOptions.primaryColor = "#00FFFF";
  iconOptions.strokeColor = "#000000";
  iconOptions.label = "" + num;
  iconOptions.labelColor = "#000000";
  iconOptions.addStar = false;
  iconOptions.starPrimaryColor = "#FFFF00";
  iconOptions.starStrokeColor = "#0000FF";
  var icon = MapIconMaker.createLabeledMarkerIcon(iconOptions);
  var opts = {"icon": icon};
  if (title) opts.title = title;
  marker = new GMarker(new GLatLng(lat,lon), opts);
  this.map.addOverlay(marker);
  marker.bindInfoWindowHtml(html, {maxWidth:280});
  return marker;
}

MapController.prototype.addAdvisoryPoly = function(points, level, html) {
  var colour = MapController.POLY_COLOURS[level];
  for (var i=0; i<points.length; i++) {
    var poly = new GPolygon(points[i], colour, 2, 0.4, colour, 0.3, {clickable:true});
    this.map.addOverlay(poly);
    var handleClick = GEvent.callback(this.map, function(latlng) {
      this.openInfoWindowHtml(latlng, html);
    });
    GEvent.addListener(poly, "click", handleClick);
  }
}

MapController.getGeocodeErrorMsg = function(code) {
  switch(code) {
    case G_GEO_MISSING_ADDRESS: return "Sorry, the address was either missing or had no value.";
    case G_GEO_UNKNOWN_ADDRESS: return "Sorry, no corresponding geographic location could be found for the specified address. This may be due to the fact that the address is relatively new, or it may be incorrect.";
    // case G_GEO_UNAVAILABLE_ADDRESS: return "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
    case G_GEO_BAD_KEY: return "Sorry, the API key is either invalid or does not match the domain for which it was given";
    case G_GEO_TOO_MANY_QUERIES: return "Sorry, the daily geocoding quota for this site has been exceeded.";
    case G_GEO_SERVER_ERROR: return "Sorry, the geocoding request could not be successfully processed.";
    case G_GEO_MISSING_QUERY: return "Sorry, no query was specified in the input.";
    case G_GEO_BAD_REQUEST: return "Sorry, the directions request could not be understood.";
    case G_GEO_UNKNOWN_DIRECTIONS: return "Sorry, we could not compute directions between the two points, either because there is no route available or we do not have data for routing in that region.";
    default: return "Geocoding error: " + code;
  }      
}

MapController.OFFICE_ICON_GREY = new GIcon();
MapController.OFFICE_ICON_GREY.image = "../images/maps/canada_flag2.png";
MapController.OFFICE_ICON_GREY.iconSize = new GSize(16,25);
MapController.OFFICE_ICON_GREY.iconAnchor = new GPoint(0,25);
MapController.OFFICE_ICON_GREY.infoWindowAnchor = new GPoint(7,2);

MapController.OFFICE_ICON_WHITE = new GIcon();
MapController.OFFICE_ICON_WHITE.image = "../images/maps/canada_flag1.png";
MapController.OFFICE_ICON_WHITE.iconSize = new GSize(16,25);
MapController.OFFICE_ICON_WHITE.iconAnchor = new GPoint(0,25);
MapController.OFFICE_ICON_WHITE.infoWindowAnchor = new GPoint(7,2);

MapController.POLY_COLOURS = ["#FFFFFF", "#FFFF00", "#FF0000"];

