var GoogleMapController = Class.create({
  
  name: false,
  map: false,
  mark: false,
  
  addressInputEl: false,
  longitudeInputEl: false,
  latitudeInputEl: false,
  
  initialize: function(owner, name, container, addressFieldId, latitudeFieldId, longitudeFieldId, width, height)
  {
    if (typeof(GBrowserIsCompatible) == 'undefined' || !GBrowserIsCompatible())
      return; 
    
    this.owner = owner;
    this.name = name;
    
    this.addressInputEl = typeof(addressFieldId)!='undefined' ? $(addressFieldId) : $('qrcode-data-' + this.name + '-address');
    this.latitudeInputEl = typeof(latitudeFieldId)!='undefined' ? $(latitudeFieldId) : $('qrcode-data-' + this.name + '-latitude');
    this.longitudeInputEl = typeof(longitudeFieldId)!='undefined' ? $(longitudeFieldId) : $('qrcode-data-' + this.name + '-longitude');
    if(typeof(width)=='undefined') {
      width=240;
    }
    if(typeof(height)=='undefined') {
      height=200;
    }
    
    // init the Google Map itself
    this.map = new GMap2(container, { size: new GSize(width,height) });
    
    var start = new GLatLng(37.774785412131244,-122.41962432861328);
    var zoomLevel = 14;
    this.map.setCenter(start, zoomLevel);
    this.map.addControl(new GSmallMapControl());
    this.geocoder = new GClientGeocoder();
    
    GEvent.addListener(this.map, 'click', function(overlay, point){
      if(!this.mark && point)
        this.setPoint(point, true); 
    }.bind(this));
    
    // catch return key in addrees input 
    this.addressInputEl.observe('keypress',function (e){
      if(e.keyCode == 13){
        Event.stop(e);
        this.showAddress();
      }
    }.bind(this));

    if(this.parseLatitude(this.latitudeInputEl.value)) {
      this.longLatChanged();
    }
  },
  
  showAddress: function()
  {
    var address = this.addressInputEl.value;
  
    if(address == "" || !this.geocoder) 
      return false;
    this.geocoder.getLatLng(
       address,
       function(point) {
         if (!point) 
           alert(address + " not found");
         else 
            this.setPoint(point, true);
         
       }.bind(this)
     );
  },
  
  setPoint: function(point, updateLatLong)
  {
    this.map.clearOverlays();
    this.map.setCenter(point);
    
    this.mark = new GMarker(point, {draggable: true});
    GEvent.addListener(this.mark, "dragend", function(point) {
      this.setLatLong(point.y, point.x);
      this.owner.scheduleRefreshPreview();
    }.bind(this));
    
    this.map.addOverlay(this.mark);
    
    this.map.getCenter(point);
    
    if (updateLatLong)
      this.setLatLong(point.y, point.x);
    
    this.owner.scheduleRefreshPreview();
  },

  setLatLong: function(lat, long)
  {
    this.latitudeInputEl.value = lat;
    this.longitudeInputEl.value = long;
  },

/*  
  setGoogleMapType: function(type)
  {
    $('qrcode-' + this.name + '-type').value = type;
    
    this.owner.scheduleRefreshPreview();
  },
*/
  
  longLatChanged: function()
  {
    var long = this.parseLongitude(this.longitudeInputEl.value); 
    var lat = this.parseLatitude(this.latitudeInputEl.value);
    if (long !== false && lat !== false)
      this.setPoint(new GLatLng(lat, long), false);
  },
  
  parseLongitude: function(s)
  {
    var long = parseFloat(s);
    return (long != Number.NaN && long >= -180 && long <= 180) ? long : false; 
  },
  
  parseLatitude: function(s)
  {
    var lat = parseFloat(s);
    return (lat != Number.NaN && lat > -85 && lat < 85) ? lat : false; 
  }  
});
