asics.storeLocator = new Object();

asics.storeLocator.setupMap = function() {
    var m = asics.storeLocator;
    if (m.initializeMap()) {

  	var mapBounds = m.markStores(stores);

	if (m.mapCenter != null) {
	    m.addCenter(map, m.mapCenter[0], m.mapCenter[1]);
	}

  	if (stores.length > 0) { // At least one store here
        map.setCenter(asics.storeLocator.lngBounds.getCenter(), map.getBoundsZoomLevel(asics.storeLocator.lngBounds));
  	} else {		// Show the postcode area
  	    if (m.zipCode == null) m.zipCode = "";
  	    m.geocoder.setBaseCountryCode(m.countryCode);
  	    m.geocoder.getLatLng(m.zipCode + " " + m.countryName, function(countryPoint) {
            if(m.countryCode == 'ru'){
              map.setCenter(new GLatLng(55.7522222, 37.6155556),6);
            }else{
      		  map.setCenter(countryPoint, 6);
            }
		stores = [];
  	    });
  	}

	GEvent.addListener(map, 'dragend', function() { 
	    $(".update").removeClass("meta");
	    $(".title h2").addClass("grey"); 
	});
    }    
}

asics.storeLocator.addCenter = function(map, lat, lng) {
    var point = new GLatLng(lat, lng);
    var icon = asics.storeLocator.icons["center"];
    asics.storeLocator.centerMarker = new GMarker(point, {icon: icon, clickable: false});
    map.addOverlay(asics.storeLocator.centerMarker);
}

asics.storeLocator.update = function() {
  var m = asics.storeLocator;
  $('#message').hide();
  var center = map.getCenter();
  stores = [];
  $.getJSON("/store_locator/at", {lat: center.lat(), lng: center.lng(), category_id: $('#store_category_id')[0].value}, function(json) {
      $(".stores .section").html(json["list"]);
      $(".title h2").html(json["title"]);
      map.closeInfoWindow();
      for (marker in storeMarkers) {
      map.removeOverlay(storeMarkers[marker]);
      }

      $("#store-locator-content .meta").removeClass("meta");
      $(".update").addClass("meta");
      $(".grey").removeClass("grey");

      $("#error-message").remove();

      storeMarkers = [];
      m.markStores(stores);
      m.centerMarker.setLatLng(center);
      });
}

var storeMarkers = [];

asics.storeLocator.markStores = function(stores) {
  var m = asics.storeLocator;

  var mapBounds = new GLatLngBounds();
  var store;
  for (storeId in stores) {
    store = stores[storeId];

    // Setup callback for store mouseover
    store.select = function() {
      $('#message').hide();
      m.deselectStores();
      m.selectStore(this.id, false);
    };

    var point = new GLatLng(store.lat, store.long);
    var icon = store.specialist ? m.icons["specialist"] : m.icons["normal"];
    var marker = new GMarker(point, {icon: icon});
    map.addOverlay(marker);
    storeMarkers.push(marker);

    GEvent.bind(marker, "mouseover", store, store.select);

    mapBounds.extend(point);
  }
  return mapBounds;
}


// === Array for decoding the failure codes ===
var reasons=[];
reasons[G_GEO_SUCCESS]            = "Success";
reasons[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
reasons[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
reasons[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
reasons[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
reasons[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
reasons[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
reasons[G_GEO_BAD_REQUEST]        = "A directions request could not be successfully parsed.";
reasons[G_GEO_MISSING_QUERY]      = "No query was specified in the input.";
reasons[G_GEO_UNKNOWN_DIRECTIONS] = "The GDirections object could not compute directions between the points.";

var gdir;

asics.storeLocator.initializeMap = function(elementId) {
  var m = asics.storeLocator;

  if (elementId == null) elementId = "asics_store_locator_google_map";
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById(elementId));
    map.setCenter(new GLatLng(0, 0), 8);

    var mapControl = new GMapTypeControl();
    map.addControl(mapControl);
    map.addControl(new GSmallMapControl());

    map.getMapTypes().length = 0;
    map.addMapType(new GMapType(G_NORMAL_MAP.getTileLayers(), G_NORMAL_MAP.getProjection(), m.normalMapName));
    map.addMapType(new GMapType(G_SATELLITE_MAP.getTileLayers(), G_SATELLITE_MAP.getProjection(), m.satelliteMapName));
    map.addMapType(new GMapType(G_HYBRID_MAP.getTileLayers(), G_HYBRID_MAP.getProjection(), m.hybridMapName));
    gdir = new GDirections(map, document.getElementById("directions"));
    GEvent.addListener(gdir, "error", function() {
        var code = gdir.getStatus().code;
        var reason="Code "+code;
        if (reasons[code]) {
        reason = reasons[code];
        } 
        alert("Failed to obtain directions, "+reason);
        });

    m.initializeMaps();

    return true;
  } else {
    return false;
  }
}

asics.storeLocator.mapsInitialized = false;
asics.storeLocator.initializeMaps = function(countryCode, countryName) {
  var m = asics.storeLocator;
  if (!m.mapsInitialized) {
    m.geocoder = new GClientGeocoder();

    m.countryCode = countryCode;
    m.countryName = countryName;

    m.geocoder.setBaseCountryCode(countryCode);

    m.icons = {};
    m.icons["normal"] = m.createIcon("/img2/icon_store_locator_normal.png", 26, 38, 12, 32);
    m.icons["specialist"] = m.createIcon("/img2/icon_store_locator_specialist.png", 26, 38, 12, 32);
    m.icons["center"] = m.createIcon("/img2/icon_store_locator_center.png", 55, 55, 27, 27);

    m.mapsInitialized = true;
  }
}

asics.storeLocator.createIcon = function(imagePath, width, height, anchorX, anchorY) {
  var icon = new GIcon();
  icon.image = imagePath;
  icon.iconSize = new GSize(width, height);
  icon.iconAnchor = new GPoint(anchorX, anchorY);
  return icon;
}

asics.storeLocator.selectStore = function(id, pan) {
  var store = stores[id];
  $('#store-'+id).addClass("selected");               
  var point = new GLatLng(store.lat, store.long);

  if (pan) {
    map.setCenter(new google.maps.LatLng(store.lat, store.long), 14);
  }

  // opening info window will pan to point if necessary
  map.openInfoWindow(point, asics.storeLocator.storeMapWindowHTML(id), {pixelOffset: new GSize(0, -22)});
}

asics.storeLocator.deselectStores = function() {
  $('.store').removeClass("selected");                
}

var to_htmls = [];
var from_htmls = [];
var send_htmls = [];

asics.storeLocator.storeMapWindowHTML = function(id) {
  var store = stores[id];
  var html = $("#store-"+id+"-content")[0].innerHTML;

  // ERROR: 
  // This line isn't doing anything: just returns '<</p>'
  //
  //html = html.substring(1, html.lastIndexOf("<br>", html.lastIndexOf("<br>")-1)) + "</p>";

  // The info window version with the "to here" form open
  to_htmls[id] = html + directionsName+' <b>'+toHereName+'<\/b> - <a href="javascript:fromhere(' + id + ')">'+fromHereName+'<\/a> / <a href="javascript:sendMap('+id+')">'+sendName+'</a>' +
    '<br>'+startAddressName+'<form action="javascript:getDirections()">' +
    '<input type="text" SIZE=40 MAXLENGTH=40 name="saddr" id="saddr" value="" /><br>' +
    '<INPUT value="'+getDirectionsName+'" TYPE="SUBMIT"><br>' +
    walkName+' <input type="checkbox" name="walk" id="walk" /> &nbsp; '+avoidHighwaysName+' <input type="checkbox" name="highways" id="highways" />' +
    '<input type="hidden" id="daddr" value="'+store.name+"@"+ store.lat + ',' + store.long + 
    '"/>';
  // The info window version with the "from here" form open
  from_htmls[id] = html + directionsName+': <a href="javascript:tohere(' + id + ')">'+toHereName+'<\/a> - <b>'+fromHereName+'<\/b> / <a href="javascript:sendMap('+id+')">'+sendName+'</a>' +
    '<br>'+endAddressName+'<form action="javascript:getDirections()">' +
    '<input type="text" SIZE=40 MAXLENGTH=40 name="daddr" id="daddr" value="" /><br>' +
    '<INPUT value="'+getDirectionsName+'" TYPE="SUBMIT"><br>' +
    walkName+' <input type="checkbox" name="walk" id="walk" /> &nbsp; '+avoidHighwaysName+' <input type="checkbox" name="highways" id="highways" />' +
    '<input type="hidden" id="saddr" value="'+store.name+"@"+ store.lat + ',' + store.long +
    '"/>';
  send_htmls[id] = html + '<form action="javascript:submitSend(this)">' +
    toName+'<br><input type="text" id="send_to" />' +
    '&nbsp;&nbsp;<input value="'+sendName+' &#187;" type="submit">' +
    '<input type="hidden" id="store_id" value="'+store.id+'" />';

  // The inactive version of the direction info
  html = html + directionsName+' <a href="javascript:tohere('+id+')">'+toHereName+'<\/a> - <a href="javascript:fromhere('+id+')">'+fromHereName+'<\/a>' +
    ' / <a href="javascript:sendMap('+id+')">'+sendName+'</a>';

  return html;
}

function tohere(id) {
  var store = stores[id];
  var point = new GLatLng(store.lat, store.long);
  map.openInfoWindow(point, to_htmls[id], {pixelOffset: new GSize(0, -22)});
}
function fromhere(id) {
  var store = stores[id];
  var point = new GLatLng(store.lat, store.long);
  map.openInfoWindow(point, from_htmls[id], {pixelOffset: new GSize(0, -22)});
}
function sendMap(id) {
  var store = stores[id];
  var point = new GLatLng(store.lat, store.long);
  map.openInfoWindow(point, send_htmls[id], {pixelOffset: new GSize(0, -22)});
}
function submitSend(form) {
  form.action = "/store_locator/send_map";
    $.post(form.action, { store_id: $("#store_id").val(), send_to: $("#send_to").val()}, function(response) { 
        if (response == "success") {
        message = successMessage;
        map.closeInfoWindow();
        } else {
        message = errorMessage;
        }
        $('#message').html(message).show();
        });
}

// ===== request the directions =====
function getDirections() {
  // ==== Set up the walk and avoid highways options ====
  var opts = {};
  if (document.getElementById("walk").checked) {
    opts.travelMode = G_TRAVEL_MODE_WALKING;
  }
  if (document.getElementById("highways").checked) {
    opts.avoidHighways = true;
  }
  // ==== set the start and end locations ====
  var saddr = document.getElementById("saddr").value;
    var daddr = document.getElementById("daddr").value;
    gdir.load("from: "+saddr+" to: "+daddr, opts);
  $('div#directions').fadeIn('slow');
  map.closeInfoWindow();
}


asics.storeMap = function(store, set_location_map, geocodeAddress) {
  this.store = store;
  this.address = geocodeAddress;

  element = $(".map", set_location_map).get(0);

    this.latField = $(".latitude_field", set_location_map);
  this.lngField = $(".longitude_field", set_location_map);
  this.messageArea = $(".message", set_location_map);

  gMaps = google.maps;

  var storeMap = this; // To avoid naming problems with 'this' changing inside maps api callbacks

  this.placeStore = function(storeLocation, successZoom) {
    if (successZoom == null) successZoom = 17;

    if (storeLocation != null) { // found the location
      this.map.setCenter(storeLocation, successZoom);
      storeMap.setMarkerLocation(storeLocation);
      $(this.messageArea).text("");
    } else {
      asics.storeLocator.geocoder.getLatLng(asics.storeLocator.countryName, function(countryPoint) {
          if (countryPoint != null) {
          storeMap.map.setCenter(countryPoint, 6);
          storeMap.setMarkerLocation(countryPoint);
          }
          $(storeMap.messageArea).text("Couldn't find location").effect("highlight", {}, 1000);
          });
    }

  }

  this.setMarkerLocation = function(location, zoomLevel) {
    this.map.clearOverlays();

    $(this.latField)[0].value = location.lat();
    $(this.lngField)[0].value = location.lng();

    var marker = new gMaps.Marker(location, {draggable: true, icon: asics.storeLocator.icons["normal"]});
    gMaps.Event.addListener(marker, "dragend", function() {
        $(storeMap.latField)[0].value = marker.getLatLng().lat();
        $(storeMap.lngField)[0].value = marker.getLatLng().lng();                
        $(storeMap.messageArea).text("");
        });
    this.map.addOverlay(marker);

    if (zoomLevel != null) this.map.setCenter(location, zoomLevel);
  }

  this.placeMarker = function() {
    if (this.store.latitude != 0) { // location is known
      var storeLocation = new gMaps.LatLng(this.store.latitude, this.store.longitude);
      this.setMarkerLocation(storeLocation, 17);
    } else {		// search for address
      asics.storeLocator.geocoder.getLatLng(this.address, function(point) { storeMap.placeStore(point); });
    }	    
  }

  if (gMaps.BrowserIsCompatible()) {
    var m = asics.storeLocator;
    var map = this.map = new gMaps.Map2(element);
    map.setCenter(new gMaps.LatLng(0, 0), 8);

    var mapControl = new gMaps.MapTypeControl();
    map.addControl(mapControl);
    map.addControl(new gMaps.SmallMapControl());

    map.getMapTypes().length = 0;
    map.addMapType(new gMaps.MapType(G_NORMAL_MAP.getTileLayers(), G_NORMAL_MAP.getProjection(), m.normalMapName));
    map.addMapType(new gMaps.MapType(G_SATELLITE_MAP.getTileLayers(), G_SATELLITE_MAP.getProjection(), m.satelliteMapName));
    map.addMapType(new gMaps.MapType(G_HYBRID_MAP.getTileLayers(), G_HYBRID_MAP.getProjection(), m.hybridMapName));

    this.placeMarker();
  }
}

