Object.extend(Array.prototype, {
  sum: function() {
    return this.inject(0, function(c,i) { return (c+i); })
  },
  average: function() {
    if (this.size() == 0) { return 0; }
    return (this.sum() / this.size());
  },
  empty: function() {
    return(this.size() == 0)
  }
})

var MapPoints = Class.create({
  initialize: function(pointsEl) {
    this.points = new Array();
    pointsEl.select(".point").collect(function(pointEl) {
      var latitude = this.parseGeo(pointEl.down(".latitude"));
      var longitude = this.parseGeo(pointEl.down(".longitude"));
      if (latitude && longitude) {
        var venue = pointEl.down(".event_venue");
        this.points.push(new MapPoint(latitude, longitude, venue))
      }
    }.bind(this))
  },
  parseGeo: function(el) {
    var html = el.innerHTML;
    if (html) { return parseFloat(html); }
  },
  latitudes: function() {
    return this.points.map(function(p) { return p.latitude; });
  },
  longitudes: function() {
    return this.points.map(function(p) { return p.longitude; });
  },
  averages: function() {
    return new Hash({
      latitude: this.latitudes().average(),
      longitude: this.longitudes().average()
    });
  },
  empty: function() {
    return this.points.empty();
  },
  bounds: function() {
    var bounds = new GLatLngBounds();
    this.points.each(function(point) {
      bounds.extend(new GLatLng(point.latitude, point.longitude));
    })
    return bounds;
  }
})

var MapPoint = Class.create({
  initialize: function(latitude, longitude, venue) {
    this.latitude = latitude;
    this.longitude = longitude;
    this.venue = venue;
  }
})

Event.observe(window, "load", function(){
  if (GBrowserIsCompatible()) {
    $$(".google_map").each(function(google_map) {
      
      var mapPoints = new MapPoints(google_map.down(".points"));
      if (mapPoints.empty()) { google_map.hide(); return; }
      
      var map = new GMap2(google_map);
      var averages = mapPoints.averages();
      
      var bounds = mapPoints.bounds();
      map.setCenter(new GLatLng(averages.get('latitude'), averages.get('longitude')), (map.getBoundsZoomLevel(bounds)));
      
      mapPoints.points.each(function(point) {
        var location = new GLatLng(point.latitude, point.longitude)
        var marker = new GMarker(location);
        GEvent.addListener(marker, "click", function(x,y) {
          map.openInfoWindow(location, point.venue);
        })
        map.addOverlay(marker);
      })


      var mapControl = new GMapTypeControl();
      map.addControl(mapControl);
      map.addControl(new GSmallMapControl());
      map.checkResize();
    })
  }
})

Event.observe(window, "unload", function() {
   GUnload();
})