if (typeof Sprint == 'undefined' ) {Sprint = function() {};};

Sprint.Map = {
   js_arr_locations: null,
   zoomLevel: 14,
   mapOptions : { mapTypeId: google.maps.MapTypeId.ROADMAP},
   geocoder: new google.maps.Geocoder(),
   marker: null,
   currentIndex: 0,
   directionsDisplay: null,
   marker_offset_x: 12,
   marker_offset_y: 12,
   image: null,
   overlay: null,
   map: null,
   popup_width: 220,
   popup_height: 120,
   location : null,
   lat_offset : 0,
   lon_offset : 0
};

Sprint.Map.init = function(arr_locations ) {
   Sprint.Map.image = new google.maps.MarkerImage('/images/map-overlay.png', null, null, new google.maps.Point(Sprint.Map.marker_offset_x,Sprint.Map.marker_offset_y))
   Sprint.Map.js_arr_locations = arr_locations;
   Sprint.Map.map = new google.maps.Map(document.getElementById("map_canvas"), Sprint.Map.mapOptions);
   
};

Sprint.Map.plotAllLocations = function() {
   
   Sprint.Map.clearMap();
   var arr_coordinates = null;
   var max_north = null;
   var max_south = null;
   var max_east = null;
   var max_west = null;
   var bounds = new google.maps.LatLngBounds();
   var bol_bounds_increased = null;
   
   for(int_i=0;int_i<Sprint.Map.js_arr_locations.length;int_i++) {
      arr_coordinates = Sprint.Map.js_arr_locations[int_i]['location'].split(',');
      if (arr_coordinates.length==2) {
         if (!(isNaN(arr_coordinates[0]) || isNaN(arr_coordinates[1]))) {
            Sprint.Map.marker = new google.maps.Marker({
               map: Sprint.Map.map,
               position: new google.maps.LatLng(arr_coordinates[0],arr_coordinates[1]),
               icon: Sprint.Map.image
            });
            Sprint.Map.marker.setTitle(Sprint.Map.js_arr_locations[Sprint.Map.currentIndex]['label']);
            bol_bounds_increased = false;
            if (arr_coordinates[0] > max_north || max_north == null) {
               max_north = arr_coordinates[0];
               bol_bounds_increased = true;
            }
            if (arr_coordinates[0] < max_south || max_south == null) {
               max_south = arr_coordinates[0];
               bol_bounds_increased = true;
            }
            if (arr_coordinates[1] > max_east || max_east == null) {
               max_east = arr_coordinates[1];
               bol_bounds_increased = true;
            }
            if (arr_coordinates[1] < max_west || max_west == null) {
               max_west = arr_coordinates[1];
               bol_bounds_increased = true;
            } 
            if (bol_bounds_increased) {
               bounds = new google.maps.LatLngBounds(new google.maps.LatLng(max_south, max_west, false) , new google.maps.LatLng(max_north, max_east, false));
               Sprint.Map.map.fitBounds (bounds);
            }          
         }
      }
      if (Sprint.Map.multi_location == null) {
         Sprint.Map.geocoder.geocode({ 'address': Sprint.Map.js_arr_locations[int_i]['location']}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
               
               Sprint.Map.marker = new google.maps.Marker({
                  map: Sprint.Map.map,
                  position: results[0].geometry.location,
                  icon: Sprint.Map.image
               });
               Sprint.Map.marker.setTitle(Sprint.Map.js_arr_locations[Sprint.Map.currentIndex]['label']);
               
               bol_bounds_increased = false;
               if (results[0].geometry.location.lat() > max_north || max_north == null) {
                  max_north = results[0].geometry.location.lat();
                  bol_bounds_increased = true;
               }
               if (results[0].geometry.location.lat() < max_south || max_south == null) {
                  max_south = results[0].geometry.location.lat();
                  bol_bounds_increased = true;
               }
               if (results[0].geometry.location.lng() > max_east || max_east == null) {
                  max_east = results[0].geometry.location.lng();
                  bol_bounds_increased = true;
               }
               if (results[0].geometry.location.lng() < max_west || max_west == null) {
                  max_west = results[0].geometry.location.lng();
                  bol_bounds_increased = true;
               } 
               if (bol_bounds_increased) {
                  bounds = new google.maps.LatLngBounds(new google.maps.LatLng(max_south, max_west, false) , new google.maps.LatLng(max_north, max_east, false));
                  Sprint.Map.map.fitBounds (bounds);
               } 
            } 
         });
      } 
   }
}



Sprint.Map.plotLocation = function(index) {

   Sprint.Map.clearMap();

   Sprint.Map.currentIndex = index;
   Sprint.Map.location = null;

   // if we are passed coordinates (as a string, use them as the location) otherwise assume that
   // we are receiving an address or partial address to bt geocoded.
   var arr_coordinates = Sprint.Map.js_arr_locations[index]['location'].split(',');
   if (arr_coordinates.length==2) {
      if (!(isNaN(arr_coordinates[0]) || isNaN(arr_coordinates[1]))) {
         Sprint.Map.location = new google.maps.LatLng(arr_coordinates[0],arr_coordinates[1]);
         Sprint.Map.updateMap();
      }
   }
   if (Sprint.Map.location == null) {
      Sprint.Map.geocoder.geocode({ 'address': Sprint.Map.js_arr_locations[index]['location']}, function(results, status) {
         if (status == google.maps.GeocoderStatus.OK) {
            Sprint.Map.location = results[0].geometry.location;
            Sprint.Map.updateMap();
         } else {
            alert('Error geocoding '+Sprint.Map.js_arr_locations[index]['location']+' : '+status)
         }
      });
   }
};

Sprint.Map.clearMap = function() {
   // remove any previous routes from map
   if (Sprint.Map.directionsDisplay!==null) {
      Sprint.Map.directionsDisplay.setMap(null);
   }
   // remove any previous markers from map
   if (Sprint.Map.marker!==null) {
      Sprint.Map.marker.setMap(null);
   }
   // remove any previous map overlay from map
   if (Sprint.Map.overlay!==null) {
      $('#location_info').remove();
      Sprint.Map.overlay=null;
   }
}

Sprint.Map.updateMap = function() {

   if (Sprint.Map.lat_offset == 0 && Sprint.Map.lat_offset == 0 ) {
      Sprint.Map.map.setCenter(Sprint.Map.location);
   } else {
      Sprint.Map.map.setCenter(new google.maps.LatLng(Sprint.Map.location.lat()+Sprint.Map.lat_offset,Sprint.Map.location.lng()+Sprint.Map.lon_offset, false ));
   }

   Sprint.Map.map.setZoom(Sprint.Map.zoomLevel);

   Sprint.Map.marker = new google.maps.Marker({
      map: Sprint.Map.map,
      position: Sprint.Map.location,
      icon: Sprint.Map.image
   });
   Sprint.Map.marker.setTitle(Sprint.Map.js_arr_locations[Sprint.Map.currentIndex]['label']);

   if (Sprint.Map.js_arr_locations[Sprint.Map.currentIndex]['address'] != undefined) {
      var content = Sprint.Map.js_arr_locations[Sprint.Map.currentIndex]['address'];
      Sprint.Map.overlay = new Sprint.Map.MapOverlay(Sprint.Map.location, content, Sprint.Map.map);
   }
};

Sprint.Map.MapOverlay = function(anchor, content, map) {

  this.anchor_ = anchor;
  this.content_ = content;
  this.map_ = map;

  // We define a property to hold the image's
  // div. We'll actually create this div
  // upon receipt of the add() method so we'll
  // leave it null for now.
  this.div_ = null;

  // Explicitly call setMap() on this overlay
  this.setMap(map);
};

Sprint.Map.MapOverlay.prototype = new google.maps.OverlayView();

Sprint.Map.MapOverlay.prototype.onAdd = function() {

   // Note: an overlay's receipt of onAdd() indicates that
   // the map's panes are now available for attaching
   // the overlay to the map via the DOM.

   // Create the DIV and set some basic attributes.
   var div = document.createElement('DIV');
   div.id = "location_info";
   div.style.backgroundColor = "transparent";
   div.style.border = "none";
   div.style.borderWidth = "0px";
   div.style.position = "absolute";
   div.style.visibility = "visible";

   div.innerHTML = this.content_;

   // Set the overlay's div_ property to this DIV
   this.div_ = div;

   // We add an overlay to a map via one of the map's panes.
   // We'll add this overlay to the overlayImage pane.
   var panes = this.getPanes();
   panes.floatPane.appendChild(div);

   $('.map_dismiss').click(function(){$('#location_info').fadeOut(500);});
};

Sprint.Map.MapOverlay.prototype.draw = function() {

   // get the anchor point location (south east corner) and from that and the
   // height and width calculate the div position

   var overlayProjection = this.getProjection();
   var se = overlayProjection.fromLatLngToDivPixel(this.anchor_);

   // Resize the image's DIV to fit the indicated dimensions.
   var div = this.div_;

   div.style.left = (se.x - Sprint.Map.popup_width) + 'px';
   div.style.top = (se.y - Sprint.Map.popup_height) + 'px';
   div.style.width =  Sprint.Map.popup_width + 'px';
   div.style.height =  Sprint.Map.popup_height + 'px';
}

Sprint.Map.MapOverlay.prototype.hide = function() {
  if (this.div_) {
    this.div_.style.visibility = "hidden";
  }
};

Sprint.Map.showDirections = function() {

   // remove any previous routes from map
   if (Sprint.Map.directionsDisplay!=undefined) {
      Sprint.Map.directionsDisplay.setMap(null);
   }
   // tell google to prefer results within a certain distance of the map centre
   Sprint.Map.location.lat()
   var distance = 0.35;
   var req_bounds = new google.maps.LatLngBounds(new google.maps.LatLng(Sprint.Map.location.lat()-distance , Sprint.Map.location.lng()-distance ), new google.maps.LatLng(Sprint.Map.location.lat()+distance , Sprint.Map.location.lng()+distance));

   Sprint.Map.geocoder.geocode(
   { 'address': document.getElementById('start_loc').value, 'bounds': req_bounds},
   function(results, status) {

      if (status == google.maps.GeocoderStatus.OK) {

         var directionsService = new google.maps.DirectionsService();
         var request = {
         origin:results[0].geometry.location,
         destination: Sprint.Map.js_arr_locations[Sprint.Map.currentIndex]['location'],
         travelMode: google.maps.TravelMode.DRIVING
      };

      directionsService.route(request, function(result, status) {
         if (status == google.maps.DirectionsStatus.OK) {
            if (Sprint.Map.overlay!=null) {
               Sprint.Map.overlay.hide();
            }
            Sprint.Map.directionsDisplay = new google.maps.DirectionsRenderer({suppressMarkers: true, suppressInfoWindows: true});
            Sprint.Map.directionsDisplay.setDirections(result);
            Sprint.Map.directionsDisplay.setMap(Sprint.Map.map);
         }});
      } else {
         alert('Sorry couldn\'t locate '+$('#start_loc').val());
      }
   })
};
