var Marker = {
  init: function() {
    this.baseIcon = new GIcon();
    this.baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
    this.baseIcon.iconSize = new GSize(20, 34);
    this.baseIcon.shadowSize = new GSize(37, 34);
    this.baseIcon.iconAnchor = new GPoint(9, 34);
    this.baseIcon.infoWindowAnchor = new GPoint(9, 2);
    this.baseIcon.infoShadowAnchor = new GPoint(18, 25);    

    this.groupIcon = new GIcon();
    this.groupIcon.image = '/images/group.png';
    this.groupIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
    this.groupIcon.iconSize = new GSize(26, 34);
    this.groupIcon.shadowSize = new GSize(37, 34);
    this.groupIcon.iconAnchor = new GPoint(13, 34);
    this.groupIcon.infoWindowAnchor = new GPoint(25, 7);
    this.groupIcon.infoShadowAnchor = new GPoint(18, 25);    
  },
  
  _setIconInfo: function(marker, png) {
    marker.getIcon().image =  "/images/gmap/" + png + ".png";
    marker.getIcon().shadow = "http://www.google.com/mapfiles/shadow50.png";
    marker.getIcon().iconSize = new GSize(20, 34);
    marker.getIcon().shadowSize = new GSize(37, 34);
    marker.getIcon().iconAnchor = new GPoint(9, 34);
    marker.getIcon().infoWindowAnchor = new GPoint(9, 2);
    marker.getIcon().infoShadowAnchor = new GPoint(18, 25);    
  },
  
  _setEventIconInfo: function(marker, png) {
    marker.getIcon().image =  "/images/gmap/" + png + ".png";
    marker.getIcon().iconSize = new GSize(20, 20);
    marker.getIcon().iconAnchor = new GPoint(10, 10);
    marker.getIcon().infoWindowAnchor = new GPoint(10, 10);
    marker.getIcon().shadow = null;
  },
  
  singleUser: function(info) { 
    if (!this.baseIcon)
      this.init();
      
    var icon = new GIcon(this.baseIcon);
    icon.image = "/images/gmap/markerUser.png";
    var marker = new GMarker(new GLatLng(info[1], info[2]), icon);
    marker.id = info[0];  
    GEvent.addListener(marker, 'click', function() {Map.showInfo(info[0])});
    return marker;
  },
  
  event: function(info, png) { 
    var marker = new GMarker(new GLatLng(info[1], info[2]), {zIndexProcess:Marker.zIndexEvent});
    this._setEventIconInfo(marker, png)  
    marker.id = info[0];  
    GEvent.addListener(marker, 'click', function() {Map.showInfo(info[0])});
    return marker;
  },
    
  group:function(info, zoom) {
    if (!this.groupIcon)
      this.init();
    var latlng = new GLatLng(info[1], info[2]);
      
  	opts = {
  		"icon":        this.groupIcon,
  		"clickable":   true,
  		"labelText":   info[3],
  		"labelOffset": new GSize(-16, -16),
  		"title":       info[4]
  	};
  	var marker = new LabeledMarker(latlng, opts);	 
    marker.id = info[0];  
 
  	GEvent.addListener(marker, "click", function() {map.setCenter(latlng, zoom)});
  	return marker;
  },
  
  zIndexEvent: function() {
    return 100000;
  }
  
}   

var Map =  {
  markers: new Array(),
  currentViewing: null, 
  viewingRequestRunning: false,
  
  updateUserPosition: function(marker) {
    $('user_lat').value = marker.getPoint().lat();
    $('user_lon').value = marker.getPoint().lng();  
    map.panTo(marker.getPoint());
  },            
  
  updateViewLocation: function() { 
    if (Map.currentViewing && Map.currentViewing.equals(map.getBounds()))
      return;
    var center = map.getCenter();
    Map.currentViewing = map.getBounds(); 
    var span =  Map.currentViewing.toSpan();  
    var size = map.getSize();
    var xGeo = span.lng() /size.width;
    var yGeo = span.lat() / size.height;                                                   
    Map.updateViewingParameters = {lat:     center.lat(), 
                                   lon:     center.lng(), 
                                   zoom:    map.getZoom(),
                                   swLat:   Map.currentViewing.getSouthWest().lat(), 
                                   swLon:   center.lng() - span.lng()/2,
                                   neLat:   Map.currentViewing.getNorthEast().lat(), 
                                   neLon:   center.lng() + span.lng()/2,
                                   xGeo:    xGeo,
                                   yGeo:    yGeo }    
    if (!Map.viewingRequestRunning) {
      Map.viewingRequestRunning = true;
      new Ajax.Request("/update_viewing", {parameters:Map.updateViewingParameters, onComplete: Map.updateViewingDone}); 
      Map.updateViewingParameters = null;
    }
  },     

  updateViewingDone: function() {   
    if (Map.updateViewingParameters){ 
      Map.viewingRequestRunning = true;
      new Ajax.Request("/update_viewing", {parameters:Map.updateViewingParameters, onComplete: Map.updateViewingDone});      
      Map.updateViewingParameters = null;
    } else 
      Map.viewingRequestRunning = false;
  },
  
  showInfo: function(id) {    
    m = Map.markers.find(function(marker) {return marker.id == id})
    if (m)
      new Ajax.Request("/info/" + id);
    else
      document.location.href = "/user/" + id
  },

  openInfoWindow: function(id, html) {
    m = Map.markers.find(function(marker) {return marker.id == id})
    if (m)        
      m.openInfoWindowHtml(html, {maxWidth: 400}); 
  },
    
  loaded: function(event, id) { 
    if (!map || !map.isLoaded() || map.getSize().width == 0) {
      setTimeout(this.loaded.bind(this), 100);
      return;
    }           
    if (!map.getCenter().equals(mapCenter)) {
      map.setCenter(mapCenter)
      this.showId = id;
    }
    else {
    this.updateViewLocation();  
      if (id != '0')  {  
        this.showId = id;
      }
    }
    Event.observe(window, "resize", Map.updateViewLocation.bind(Map))
  },
  
  updateMarkers: function(markerList) {    
    this._updateMarkers(markerList, 3);   
    if (this.showId) {    
       this.showInfo(this.showId);  
       this.showId = null;
    }
  },
  
  updateGroupMarkers: function(markerList, zoom) {
    this._updateMarkers(markerList, zoom)
  },
  
  updatePeopleMouseOver: function() {  
    $$("#card_content .mini-card").each(function(element) {
      element.observe("mouseover", function() {element.addClassName('hover')})
      element.observe("mouseout", function() {element.removeClassName('hover')})
    });   
  },
  
  _updateMarkers: function(markerList, zoom) {
    // Mark all markers as not used
    Map.markers.each(function(m) {m.used = false});  
    // Create only new markers
    markerList.each(function(info) {
      var marker = Map.markers.find(function(marker) {return marker.id == info[0]})   
      // Check marker type _u = single user, _g = group, _c = country, _e = event
      if (!marker) {                  
        // Compute zoom according to group bound
        if (info[4] instanceof Array) 
          zoom = map.getBoundsZoomLevel(new GLatLngBounds(new GLatLng(info[4][0], info[4][2]), new GLatLng(info[4][1], info[4][3])))
                  
        if (info[0].indexOf("_u") != -1)
          marker = Marker["singleUser"](info, zoom);
        else if (info[0].indexOf("_g") != -1)
          marker = Marker["group"](info, zoom);
        else if (info[0].indexOf("_c") != -1)
          marker = Marker["group"](info, zoom);
        else if (info[0].indexOf("_eg") != -1)
          marker = Marker["event"](info, "markerEvent");
        else if (info[0].indexOf("_ea") != -1)
          marker = Marker["event"](info, "markerApero");
        else if (info[0].indexOf("_eb") != -1)
          marker = Marker["event"](info, "markerBarcamp");
        else if (info[0].indexOf("_ey") != -1)
          marker = Marker["event"](info, "markerYulbiz");
        
        map.addOverlay(marker);    
        Map.markers.push(marker);     
        if (marker.id == "1_eg") {   
          mm = marker
        }
      }
      marker.used = true;
    });
    
    // Remove unused markers (not visible)    
    this._updateMarkerList();
  },
  
  _updateMarkerList: function(markers) {
    // Remove unused marker (not visible)
    var new_markers = new Array();
    Map.markers.each(function(marker) {
      if (marker.used) 
        new_markers.push(marker);
      else 
        map.removeOverlay(marker);
    });
    Map.markers = new_markers;        
  }
} 
