var NedGMap = Class.create({
  initialize: function(config) {
    if(!GBrowserIsCompatible()) {
      if(confirm("Your browser is not Google Maps compatible!\nCheck Google Maps Support for more information.\nDo you want to go there now?")) {
        window.open("http://maps.google.com/support/bin/answer.py?hl=en&answer=16532");
      }
    } else {
      this.startUp(config);
    }
  },
  startUp: function(config) {
    this.initialized = false;
    this.admin = config.admin;
    this.form_element = config.form_element;
    this.markers = config.markers || [];
    this.map = new GMap2(config.map_element);
    this.configMap();
    this.setPosition({
      lat: config.start_pos.lat || 0,
      long: config.start_pos.long || 0,
      zoom: config.zoom || 1
    });
    this.setControls(config.controls || 'small');
    this.startUpMarkerManager();
    this.createInitialMarkers();
    if(this.admin) { this.startUpAdmin(); }
    this.watchForUnload();
  },
  configMap: function() {
    var HYBRID = new GMapType([G_HYBRID_MAP.getTileLayers()[0],G_HYBRID_MAP.getTileLayers()[1]], new GMercatorProjection(32), "Satellite", {shortname:"Hyb"});
    this.map.addMapType(HYBRID);
    this.map.removeMapType(G_HYBRID_MAP);
    this.map.removeMapType(G_SATELLITE_MAP);
    this.map.enableScrollWheelZoom();
  },
  startUpMarkerManager: function() {
    this.marker_manager = new GMarkerManager(this.map);
    this.gmarkers = [];
  },
  startUpAdmin: function() {
    if(this.markers.length == 0) { this.handleMouse(); }
    this.watchForSubmit();
  },
  watchForUnload: function() {
    Event.observe(window, 'unload', GUnload);
  },
  setPosition: function(config) {
    if(this.initialized) {
      this.map.panTo(new GLatLng(config.lat, config.long));
      this.setZoom(config.zoom || this.map.getZoom());
    } else {
      this.map.setCenter(new GLatLng(config.lat, config.long), config.zoom || this.map.getZoom());
      this.initialized = true;
    }
  },
  setZoom: function(zoom) { this.map.setZoom(parseInt(zoom)); },
  getZoom: function() { return this.map.getZoom(); },
  setControls: function(size) {
    this.map.addControl(new GMapTypeControl());
    size == 'small' ? this.map.addControl(new GSmallMapControl()) : this.map.addControl(new GLargeMapControl());
  },
  createInitialMarkers: function() {
    if(this.markers.length > 0) {
      this.markers.each(function(m) {
        if(this.admin) { var draggable = {draggable: true}; } else { {draggable: false}; }
        var gmarker = new GMarker(new GLatLng(m.lat, m.long), draggable);
        this.gmarkers.push(gmarker);
        this.marker_manager.addMarker(gmarker, 0, 17);
        GEvent.addListener(gmarker, 'click', function() {
          gmarker.openInfoWindowHtml(m.info, { maxWidth: 470, maxHeight: 160 });
        });
      }.bind(this));
      this.marker_manager.refresh();
    }
  },
  createMarker: function(config) {
    this.markers.push({lat: config.lat, long: config.long});
    var gmarker = new GMarker(new GLatLng(config.lat, config.long), {draggable: true});
    this.gmarkers.push(gmarker);
    this.marker_manager.addMarker(gmarker, 0, 17);
    this.marker_manager.refresh();
    GEvent.removeListener(this.add_event);
  },
  watchForSubmit: function() {
    this.form_element.select('input[type=submit]')[0].observe('click', function(e) {
      if(this.gmarkers.length > 0) {
        var active_marker = this.gmarkers[0].getLatLng();
        e.stop();
        this.form_element.appendChild(new Element('input', {type: 'hidden', id: 'project_latitude', name: 'project[latitude]', value: active_marker.lat() }));
        this.form_element.appendChild(new Element('input', {type: 'hidden', id: 'project_longitude', name: 'project[longitude]', value: active_marker.lng() }));
        this.form_element.submit();
      }
    }.bind(this));
  },
  handleMouse: function() {
    var point;
    GEvent.addListener(this.map, "mousemove", function(this_point) {
      point = this_point;
    });
    this.add_event = GEvent.addListener(this.map, "click", function() {
      var click_pos = point.lat().toFixed(14) + ', ' + point.lng().toFixed(14);
      this.createMarker({lat: point.lat().toFixed(14), long: point.lng().toFixed(14)});
    }.bind(this));
  }
});