var SpotBuilder = Class.create({

  initialize: function(map, options) {
    this.map = map;
    this.setOptions(options);

    this.cookies = new Cookies();
    this.options.help = this.cookies.get("spot_help") != "false";

    this.geocoder = new GClientGeocoder();
    this.geocoder.setBaseCountryCode("de");

    this.marker = new GMarker(this.map.getCenter(), { draggable: true });
    this.map.addOverlay(this.marker);
    this.marker.hide();

    GEvent.addListener(this.marker, "click", this.show.bind(this));
    GEvent.addListener(this.marker, "infowindowopen", this.onInfoWindowOpen.bind(this));
    GEvent.addListener(this.marker, "dragstart", this.marker.closeInfoWindow);

    this.loadFormular();
  },

  hide: function() {
    this.marker.closeInfoWindow();
    this.marker.hide();
  },

  loadFormular: function() {
    new Ajax.Request("/spots/new", { method: 'get', onSuccess: function(transport) {
      this.formularHTML = transport.responseText;
    }.bind(this)});
  },

  placeMarker: function(pos) {
    this.marker.setLatLng(pos);
  },

  show: function(attributes) {
    this.attributes = attributes;

//    if (!this.map.getBounds().containsLatLng(this.marker.getLatLng())) {
//      this.marker.setLatLng(this.map.getCenter());
//    }

    if(this.options.help) {
      this.showHelp();
    } else {
      this.showFormular();
    }
  },

  showFormular: function() {
    this.marker.show();
    this.marker.bindInfoWindowHtml(this.formularHTML);
    this.marker.openInfoWindowHtml(this.formularHTML, { maxWidth: 300 });
  },

  showHelp: function() {
    this.marker.show();
    this.marker.bindInfoWindowHtml(j$('#help').html());
    this.marker.openInfoWindowHtml(j$('#help').html(), { maxWidth: 400 });
  },

  onInfoWindowOpen: function() {
    this.marker.show();

    if ($('spot_latitude') && $('spot_longitude')) {
      this.geocoder.getLocations(this.marker.getLatLng(), this.onReverseGeocoding.bind(this));
      this.updateFormWithAttributes(this.attributes);
    }
  },

  onReverseGeocoding: function(response) {
    if (response.Status.code != 200) {
      return;
    }

    this.updateFormWithPlacemark(response.Placemark[0]);
  },

  setHelpStatus: function(status) {
    this.options.help = !status;
    this.cookies.put("spot_help", this.options.help);
  },

  setOptions: function(options) {
    this.options = Object.extend({
      help: true
    }, options || { });
  },

  updateFormWithAttributes: function(attributes) {
    $('spot_latitude').value = this.marker.getLatLng().lat();
    $('spot_longitude').value = this.marker.getLatLng().lng();

    if (attributes && attributes.spot && attributes.spot.category_id) {
      $('spot_category_id').value = attributes.spot.category_id;
    }
  },

  updateFormWithPlacemark: function(placemark) {
    if (placemark && placemark.AddressDetails && placemark.AddressDetails.Country) {
      // ADDRESS
      if (placemark.AddressDetails.Country.AdministrativeArea &&
          placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea &&
          placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality &&
          placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.DependentLocality &&
          placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.DependentLocality.Thoroughfare &&
          placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.DependentLocality.Thoroughfare.ThoroughfareName) {
        $('spot_address').value = placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.DependentLocality.Thoroughfare.ThoroughfareName.gsub(/(\d+(\s*-\s*\d+)?)\s+(.*)/, "#{3} #{1}");
      }

      if ($('spot_address').value == null || $('spot_address').value.strip() == "" && placemark.address) {
        $('spot_address').value = placemark.address.gsub(/([^,]+).*/, "#{1}").gsub(/\d+/, '').strip();
      }
    }
  }

});

var Map = Class.create({

  mapId: 'map',
  defaultZoom: 13,

  initialize: function() {
    this.map = new GMap2($(this.mapId));
    this.map.enableScrollWheelZoom();
    this.map.addControl(new GLargeMapControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10, 10)));
    this.map.addControl(new GMapTypeControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(90, 10)));
    this.map.setCenter(new GLatLng(latitude, longitude), this.defaultZoom);

    this.spotBuilder = new SpotBuilder(this.map);
  },

  centerTo: function(latitude, longitude) {
    this.map.panTo(new GLatLng(latitude, longitude));
  },

  getSpotBuilder: function() {
    return this.spotBuilder;
  },

  showSpotBuilder: function(attributes) {
    this.getSpotBuilder().placeMarker(this.map.getCenter());
    this.getSpotBuilder().show(attributes);
  },

  hideSpotBuilder: function() {
    this.getSpotBuilder().hide();
  },
  
  setMarkerSelection: function(marker) {
    this.marker = marker;
  },
  
  getMarkerSelection: function() {
    return this.marker;
  },
  
  closeInfoWindow: function() {
    this.map.closeInfoWindow();
  }

});

