GMapsCoordPicker = Class.create();
GMapsCoordPicker.prototype = {

  params: {
    DEFAULT_LATITUDE    : 43.58039085560784,
    DEFAULT_LONGITUDE   : -39.375,
    DEFAULT_ZOOM        : 1,
    DEFAULT_QUERY_ADDON : ', United Kingdom'
  },

  /**
   * constructor: sets field objects for latitude, logintude, zoom factor and map
   */
  initialize: function(latFormId, lngFormId, zoomFormId, mapId) {
    if (!GBrowserIsCompatible()) {
      throw 'Your Browser is not supported';
    }
    this.latFormObj  = $(latFormId);
    this.lngFormObj  = $(lngFormId);
    this.zoomFormObj = $(zoomFormId);
    this.zoom        = parseInt(this.zoomFormObj.value);
    this.marker      = null;

    // build map
    this.map = new GMap2($(mapId));
    this.map.addControl(new GLargeMapControl());
    this.map.addControl(new GMapTypeControl());

    // initial handling
    if (this.hasValue()) {
      var point = new GLatLng(this.latFormObj.value, this.lngFormObj.value);
      this.map.setCenter(point, parseInt(this.zoomFormObj.value));

      this.resetMarker(point);
    }
    // if no point is set, center default point
    else {
      var point = new GLatLng(this.params.DEFAULT_LATITUDE,
                              this.params.DEFAULT_LONGITUDE);
      this.map.setCenter(point, this.params.DEFAULT_ZOOM);
    }

    // add event handler, call this::resetMarker() on click
    GEvent.addListener(this.map, 'click', function(marker, point) {
      this.resetMarker(point);
    }.bind(this));
  },

  /**
   * checks if point is set
   */
  hasValue: function() {
    return (this.latFormObj.value != '0' && this.lngFormObj.value != '0');
  },

  /**
   * ask google for coordinates, set marker if found and centrify
   */
  query: function(queryString) {
    var geocoder = new GClientGeocoder();
    geocoder.getLatLng(
      queryString,   // + this.params.DEFAULT_QUERY_ADDON,
      function(point) {
        if (point) {
          this.resetMarker(point);
          this.map.setCenter(this.point, 15);
        }
      }.bind(this)
    );
  },

  /**
   * ask google for coordinates, set marker if found and centrify
   */
  city_query: function(city, country) {
    var geocoder = new GClientGeocoder();
    geocoder.getLatLng(
      city + ', ' + country,
      function(point) {
        if (point) {
          this.resetMarker(point);
          this.map.setCenter(this.point, 9);
        }
      }.bind(this)
    );
    var locations = geocoder.getLocations(city + ', ' + country);
    return locations;
  },

  /**
   * set marker to city
   */
  go_to_city: function(lat, long, zoom) {
    var geocoder = new GClientGeocoder();
    geocoder.getLatLng( city + ', ' + country,
    	function(point) {
        	if (point) {
          		this.resetMarker(point);
          		this.map.setCenter(this.point, 9);
        	}
      	}.bind(this)
    );
  },

  /**
   * sets marker to map and implicitely writes coordinate values out to
   * form fields
   */
  resetMarker: function(point) {
    if(this.marker) {this.map.removeOverlay(this.marker);}
    this.point = point;
    this.marker = new GMarker(point);
    this.map.addOverlay(this.marker);
    this.store();
  },

  /**
   * write marker values to form fields
   */
  store: function() {
    this.latFormObj.value = this.point.lat();
    this.lngFormObj.value = this.point.lng();
    this.zoomFormObj.value = this.map.getZoom();
  }
}
