var MapScript = {};

MapScript.debug = function() {};

/*
  Loads a map.

  Parameters:
    divId - the id where to load the map.
    markerList - an array of marker data.
    divList - an array of divs, one per marker, or of their IDs, which will be displayed in the info baloon.
    centerAddress - the address where to center the map. must not be null.
    centerPlace - the name of the place where to center the map. if null no centering is performed.
*/

var map;

MapScript.mapLoad = function(divId, markerList, divList, centerAddress, centerPlace, iconURL, iconWidth, iconHeight, iconSet, zoom, addressResolvedCallback)
{
  if($defined(window.MyDebug))
  {
    MapScript.debug = MyDebug;
    MyDebug('activated debug');
  }
  if(!$defined(zoom))
    zoom=14;
  if (GBrowserIsCompatible()) {
    MapScript.debug('creating map');
    map = new GMap2($(divId));
    /*map.addControl(new GLargeMapControl());*/
    map.addControl(new GSmallZoomControl());
    map.addControl(new GOverviewMapControl());
    map.addControl(new GScaleControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT));

    var cazwise = new GLatLng(44.50, 11.32); 
    map.setCenter(cazwise, zoom);

    if($defined(centerAddress) && !$defined(centerPlace))
    {
      MapScript.debug('using centerAddress');
      MapScript.resolveAddress(centerAddress,
        function(point) {
          if (!point) {
            alert("Impossibile geolocalizzare l'indirizzo " + centerAddress);
          } else {
            map.setCenter(point, zoom);
          }
        }
      );
    }
    var icon;
    if($defined(markerList))
    {
      MapScript.debug('setting marker list:', markerList);
      for(var i = 0; i < markerList.length; i++) {
        var marker = markerList[i];
        var address = marker.address + " - " + marker.zipcode + " " + marker.city + " (" + marker.country + ")";
        var center = $defined(centerPlace) && marker.name == centerPlace;
        var latitude = null;
        var longitude = null;
        var markerId = null;
        var arc = addressResolvedCallback;
        if(center) MapScript.debug('marker', marker, 'is center');
        var div = divList[i];
        if($defined(iconSet)) {
          iconURL = iconSet[marker.icon][0];
          iconWidth = iconSet[marker.icon][1];
          iconHeight = iconSet[marker.icon][2];
        }
        if($defined(marker.longitude) && marker.longitude) {longitude = marker.longitude; arc = null;}
        if($defined(marker.latitude) && marker.latitude) {latitude = marker.latitude; arc = null; }
        if($defined(marker.markerId)) markerId = marker.markerId;
        if((latitude && longitude) || (marker.address && marker.city && marker.country))
         MapScript.displayMarker(map, address, center, div, iconURL, iconWidth, iconHeight, i, latitude, longitude, zoom, arc, markerId);
      }
    }
    MapScript.debug('all done.');
  }
}

/*
  Display a marker in a map.
  
  Parameters:
    map - the map object where to display the marker.
    address - the address of this marker to resolve.
    center - whether the map should be centered on given address.
    div - the div containing the HTML for the marker or its id.
    iconURL - the URL of the icon for the marker.
    iconWidth - the width of the icon for the marker.
    iconHeight - the height of the icon for the marker.
    markerNumber - this is marker no...
    markerId - this is marker id...
*/
MapScript.displayMarker = function(map, address, center, div, iconURL, iconWidth, iconHeight, markerNumber, latitude, longitude, zoom, addressResolvedCallback, markerId)
{
  var callback = function(point) {
    if(!$defined(zoom))
      zoom=14;
    if (!point) {
      // silently ignore the problem
      if($defined(window.console) && $defined(console.debug))
        console.debug("Failed geolocalization of address " + address);
    } else {
      if(center)
        map.setCenter(point, zoom);
      if($defined(addressResolvedCallback)) 
        addressResolvedCallback(markerId, point.lat(), point.lng())
      var icon = new GIcon(G_DEFAULT_ICON, iconURL);
      icon.iconSize = new GSize(iconWidth, iconHeight);
      icon.iconAnchor = new GPoint(0,0);
      icon.shadowSize = new GSize(iconWidth*2, iconHeight);
      var marker = new GMarker(point, {'icon': icon});
      map.addOverlay(marker);
      marker.bindInfoWindow($(div));
      if(center) {
        marker.openInfoWindow($(div));
      }
    }
  };

  if(latitude != null && latitude) {
      var latlng = new GLatLng(latitude, longitude);
      callback(latlng);

  } else
   (function() {
   MapScript.resolveAddress(address, callback);
   }).delay(markerNumber*250);
}

/*
  Resolve an address using google maps API and techniques to avoid
  pestering the Google servers.
*/
MapScript.resolveAddress = function(address, callback)
{
  var geocoder = new GClientGeocoder();
  //geocoder.getLatLng(address, callback);
  var myCallback = function(response)
  {
    var status = response.Status;
    if(status.code == 620) {
      // too frequent requests: retry at a random time in a second 
      (function() {
        MapScript.resolveAddress(address, callback);
      }).delay($random(0, 1000));
    }
    else
    {
      if(!$defined(response.Placemark) || response.Placemark.length == 0)
        // no results found
        callback(null);
      else {
        // at least one result found: return the first one
        var placemarks = response.Placemark;
        var pm = placemarks[0];
        callback(new GLatLng(pm.Point.coordinates[1], pm.Point.coordinates[0]));
      }
    }
  }
  geocoder.getLocations(address, myCallback);
}

MapScript.panTo = function(address, zoom) {
 if($defined(zoom))
   map.setZoom(zoom);
 $$('.BodySlot .item').each(function(el, i) {
   el.setStyle('display', 'none');
 });
 var a = address.replace(/ /g, '_');
 a = a.substr(0, a.length-5); // strip (country)
 $$('.BodySlot .'+a).each(function(el, i) {
   el.setStyle('display', 'block');
 });
 var callback = function(point) {
    if (!point) {
      // silently ignore the problem
      if($defined(window.console) && $defined(console.debug))
        MapScript.debug("Failed geolocalization of address " + address);
    } else {
      map.panTo(point);
    }
  }
  MapScript.resolveAddress(address, callback);
}