var SearchMapController = Class.create(MapController, {

  initialize: function() {
    this.location_displayed = false;
    this.address_overlay = null;
  },

  setLayer: function(options) {
    this.zoomMin = options.stopAreasZoomThresholdMax;
    this.zoomCurrent = this.mapView.getZoom();

    this.mapView.addLayer("stop_area",
      new LayerStopProperties(options.stopAreasZoomThresholdMax,null));
    this.mapView.addLayer("place",
      new LayerPlaceProperties(options.placesZoomThresholdMax,null));
  },

  onZoomChanged: function() {
    if ( this.loadingRequired()) {
      this.loadPlacesAndStops();
    } else if ( this.unloadingRequired()) {
      this.mapView.cleanLocations("stop_area");
      this.mapView.cleanLocations("place");
    }
    this.zoomCurrent = this.mapView.getZoom();
  },

  onDragEnd: function() {
    if (this.zoomMin <= this.zoomCurrent) {
      this.loadPlacesAndStops();
    }
  },

  onClick: function(event) {
    this.address_overlay.hide();
    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({ 'latLng': event.latLng }, this.display_address.bind(this.address_overlay));
  },

  display_address: function(responses, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      this.set("geocoderResponse", responses.first());
      this.draw();
    }
  },

  onDoubleClick: function() {
    this.zoomToLocationLevel();
  },

  displayPlacesAndStops: function(transport) {
//    console.log( "SearchMapController.displayPlacesAndStops");
    this.mapView.cleanLocationsOutOfBound("stop_area");
    this.mapView.cleanLocationsOutOfBound("place");

    var response_json = eval(transport.responseText);
    response_json.each(function(point) {

      var location = new Location(point.lat,point.lng,
                                  point.type+'_'+point.stop_id, point.name,
                                  null, point.type);
      location.setTopology( point.stop_id, point.type);
      if (typeof(point.place_type)!='undefined')
        location.setTopoPlaceType( point.place_type);

      this.displayLocation(location);

    }.bind(this.mapView));

  },

  loadPlacesAndStops: function() {
    var bounds   = this.mapView.extendedBounds();

    var url = '/areas?min_lat=' + bounds.minLat +
                   '&max_lat=' + bounds.maxLat +
                   '&min_lng=' + bounds.minLng +
                   '&max_lng=' + bounds.maxLng;
    if (typeof(placeParamRequest)!='undefined')
       url += '&' + placeParamRequest;
   
    new Ajax.Request(url, {
      method: 'get',
      onSuccess: this.displayPlacesAndStops.bind(this)
    });
  },

  // -----------------------------------------------------
  // private methods
  // -----------------------------------------------------
  
  zoomToLocationLevel: function() {
    if (this.zoomCurrent < this.zoomMin) {
      this.mapView.setZoom(this.zoomMin-1);
      this.zoomCurrent = this.zoomMin-1
    }
  },

  zoomCompliant: function(zoom) {
    return this.zoomMin <= zoom;
  },

  loadingRequired: function() {
    return !this.zoomCompliant( this.zoomCurrent) &&
            this.zoomCompliant( this.mapView.getZoom());
  },

  unloadingRequired: function() {
    return this.zoomCompliant( this.zoomCurrent) &&
          !this.zoomCompliant( this.mapView.getZoom());
  }
});

SearchMapController.addMethods({
  setMapView: function($super,mapView) {
    $super(mapView);

    if ( itinerariesMapAddressOnClick) {
      this.address_overlay = new AddressOverlay({ map: mapView.map,
                                                  mapView: mapView,
                                                  label: mapView.label});
      google.maps.event.addListener(mapView.map, "rightclick", this.onClick.bindAsEventListener(this));
    }
    google.maps.event.addListener(mapView.map, "dblclick", this.onDoubleClick.bindAsEventListener(this));
    google.maps.event.addListener(mapView.map, "dragend", this.onDragEnd.bindAsEventListener(this));
    google.maps.event.addListener(mapView.map, "zoom_changed", this.onZoomChanged.bindAsEventListener(this));
  }
});
