// FIXME: Clean up!
var OsamaMap=Class.create({
  initialize:function(mapWrapper, options){
    if(!mapWrapper||!GBrowserIsCompatible()){return}
    this.mapWrapper=mapWrapper;
    if(typeof options=='undefined'){options={}}
    this.zoom=4;
    // this.zoom=options['zoom'] ? options['zoom'] : 4;
    this.map=new GMap2(mapWrapper)
    this.mapCenter=options['mapCenter'] ? options['mapCenter'] : [51.500152, -0.126236]; // London, UK (starting point; lat, lng)
    this.currentMarker=null;
    this.icon=new GIcon();
    
    this.map.addControl(new GLargeMapControl());
    this.map.addControl(new GMapTypeControl());
    
    this.icon.image='/images/map-marker.png';
    this.icon.iconSize=new GSize(17,17);
    this.icon.shadow='/images/map-marker-shadow.png';
    this.icon.shadowSize=new GSize(20,20);
    this.icon.iconAnchor=new GPoint(8,8);
    this.icon.infoWindowAnchor=new GPoint(8,8);
    // this.icon.infoShadowAnchor=new GPoint(20,20);
    // this.icon.transparent='/images/map-marker-shadow.png';
    // this.icon.printImage='/images/map-marker-ie.gif';
    // this.icon.mozPrintImage='/images/map-marker-moz.gif';
    // this.icon.printShadow='/images/map-marker-shadow.gif';
  },
  createGMarker:function(latlng){
    return new GMarker(latlng, this.icon);
  },
  addGLatLngAsMarker:function(latlng){
    var marker=this.createGMarker(latlng);
    this.addGMarker(marker);
    return marker;
  },
  addGMarker:function(marker){
    this.map.addOverlay(marker);
  },
  addGMarkers:function(markers){
    var _this=this;
    for(var markerID in markers){
      this.map.addOverlay(markers[markerID]);
    }
    // The following code allows for clicking the map to hide an info window,
    // but unfortunately also closes any info window that attempts to reopen.
    // GEvent.addListener(this.map,'click',function(){
    //   for(var markerID in markers){
    //     markers[markerID].closeOsamaInfoWindow(_this);
    //   }
    // });
  }
});

var OsamaOverlay=function(marker,html){
  this.marker=marker; this.html=html;
};
var currentMarker=null;
OsamaOverlay.prototype=new GOverlay();
OsamaOverlay.prototype.initialize=function(map){
  var infoWindow=new Element('div',{'class':'osama-info-window'}).update(this.html);
  this._map=map;
  this._infoWindow=infoWindow;
  $(map.getPane(G_MAP_FLOAT_PANE)).appendChild(infoWindow);
    // http://code.google.com/apis/maps/documentation/reference.html#GMapPane

  infoWindow.down('a.close').observe('click',function(ev){
    infoWindow.fade(); // May look weird in IE?
    ev.stop();
  });
  $(map.getPane(G_MAP_FLOAT_PANE)).observe('click',function(){ infoWindow.fade() });
    // Allows for clicking the info window or its shadow to close and access other markers
};
OsamaOverlay.prototype.remove=function(){
  if(this._infoWindow.parentNode)
  this._infoWindow.parentNode.removeChild(this._infoWindow);
};
OsamaOverlay.prototype.copy=function(){
  return new OsamaOverlay(this.marker, this.html);
};
OsamaOverlay.prototype.redraw=function(force){
  if(!force){return}
  var infoWindowAnchor=[73,118], markerPoint=this._map.fromLatLngToDivPixel(this.marker.getPoint());
  this._infoWindow.setStyle({
    position:'relative',
    left:markerPoint.x-infoWindowAnchor[0]+'px',
    top: markerPoint.y-infoWindowAnchor[1]+'px'
  });
};
GMarker.prototype.openOsamaInfoWindow=function(osamaMap,html){
  // this.openInfoWindowHtml(html);return; // Use default info window
  if(typeof OsamaOverlay!='undefined'){
    if(typeof osamaMap.currentMarker!='undefined' && osamaMap.currentMarker){ this.closeOsamaInfoWindow(osamaMap); }
    if(!this.overlay){ this.overlay=new OsamaOverlay(this, html); }
    osamaMap.currentMarker=this;
    osamaMap.map.panTo(new GLatLng(this.getPoint().lat(),this.getPoint().lng()));
    osamaMap.map.addOverlay(this.overlay);
    // this.hide();
  }else{
    this.openInfoWindowHtml(html);
  }
};
GMarker.prototype.closeOsamaInfoWindow=function(osamaMap){
  if(osamaMap.currentMarker){
    osamaMap.map.removeOverlay(osamaMap.currentMarker.overlay);
    // currentMarker.show();
  }
};

var EditableOsamaMap=Class.create(OsamaMap, {
  initialize:function($super, mapWrapper, fieldset){
    $super(mapWrapper);
    this.fieldset=fieldset;
    this.locationBtn=fieldset.down('button#google-map-location-button');
    this.locationInput=fieldset.down('input[name="osama[location]"]');
    this.latInput=fieldset.down('input[name="osama[lat]"]');
    this.lngInput=fieldset.down('input[name="osama[lng]"]');
    this.latLngBtn=fieldset.down('button#google-map-latlng-button');
    
    this.locationBtn.show();
    this.locationBtn.observe('click',this.locationToLatLng.bindAsEventListener(this));
    this.locationInput.observe('keydown',this.locationToLatLng.bindAsEventListener(this));
    
    this.latLngBtn.show();
    this.latLngBtn.observe('click',this.latLngToMarker.bindAsEventListener(this));
    this.latInput.observe('keydown',this.latLngToMarker.bindAsEventListener(this));
    this.lngInput.observe('keydown',this.latLngToMarker.bindAsEventListener(this));
    
    GEvent.addListener(this.map,'click', this.setMarker.bind(this));
  },
  locationToLatLng:function(ev){
    if(ev.keyCode && ev.keyCode!=Event.KEY_RETURN){return}
    ev.stop(); // Don't submit form
    
    var el=ev.element();

    if(el!=this.locationInput && el!=this.locationBtn){return}

    var geocoder = new GClientGeocoder();
    var error=new Element('span', {'class':'error'}).update($F(this.locationInput)+' not found');
    
    var location = geocoder.getLatLng($F(this.locationInput), function(latlng) {
      if (!latlng) {
        if(!this.locationBtn.adjacent('span.error').any()){
          this.locationBtn.insert({after:error});
        }
      } else {
        this.locationBtn.adjacent('span.error').invoke('remove');
        var marker=this.setMarker(null, latlng);
        marker.openInfoWindow($F(this.locationInput));
      }
    }.bind(this));
  },
  latLngToMarker:function(ev){
    if(ev.keyCode && ev.keyCode!=Event.KEY_RETURN){return}
    ev.stop(); // Don't submit form
    
    var el=ev.element();
    if(el!=this.latInput && el!=this.lngInput && el!=this.latLngBtn){return}
    
    var latlng=new GLatLng($F(this.latInput), $F(this.lngInput));
    // this.setMarker(null, latlng);
    this.map.clearOverlays();
    this.addGLatLngAsMarker(latlng);
    this.map.panTo(latlng);
  },
  setMarker:function(overlay,latlng){
    this.map.clearOverlays();
    var marker=this.addGLatLngAsMarker(latlng);
    this.latInput.value=latlng.y;
    this.lngInput.value=latlng.x;
    return marker;
  }
});
