var CMapManager = Class.create();
var CMarkerManager = Class.create();
var whereToGoCalled = false;


var MARKER_TYPE_NOT_HIDEABLE = 0;

var MARKER_TYPE_POD = 10;
var MARKER_TYPE_POD_FAVORITE = 11;

var MARKER_TYPE_USER = 20;
var MARKER_TYPE_USER_FOLLOWING = 21;

CMapManager.prototype = {
	'initialize' : function(id,options){
		this.id = id;
		this.markerList = new Hash();
    options.coordinates = new GLatLng(options.lat, options.lng);
		this.options = {
			'moveEvent' : function(){},
			'moveStartEvent': function(){},
			'moveEndEvent' : function(){},

			'zoomStartEvent' : function(oldLevel, newLevel){},
			'zoomEndEvent' : function(oldLevel, newLevel){},

			'dragEvent': function() {},
			'dragStart': function() {},
			'dragEnd': function() {},

			'click': function() {}
		};
		Object.extend(this.options, options);
		if (GBrowserIsCompatible()) {
			this.map = new GMap2($(id));
			this.map.setCenter(this.options.coordinates, this.options.zoom, G_NORMAL_MAP);
      this.map.enableDoubleClickZoom();
      this.map.enableScrollWheelZoom();

  		GEvent.addListener(this.map,"zoomstart",  this.options.zoomStartEvent);
  		GEvent.addListener(this.map,"zoomend",  this.options.zoomEndEvent);

  		GEvent.addListener(this.map,"move",     this.options.moveEvent);
  		GEvent.addListener(this.map,"movestart",this.options.moveStartEvent);
  		GEvent.addListener(this.map,"moveend",  this.options.moveEndEvent);

  		GEvent.addListener(this.map,"drag",     this.options.dragEvent);
  		GEvent.addListener(this.map,"dragstart",this.options.dragStart);
  		GEvent.addListener(this.map,"dragend",  this.options.dragEnd);

  		GEvent.addListener(this.map,"click",    this.options.click);
		}
    this.setFilter([]);
	},
	'addMarker' : function(marker) {
		if(Object.isUndefined(this.markerList.get(marker.id))){
  		this.map.addOverlay(marker.GoogleMarker);
  		this.markerList.set(marker.id, marker);
    } else {
      var thisMarker = this.markerList.get(marker.id);
      if(thisMarker.justAMove(marker)){
        thisMarker.GoogleMarker.setLatLng(marker.coordinates);
      } else {
        var stopAndStartIW = (infoWindowManager.activeMessage!=null && infoWindowManager.activeMessage.handle==marker.id);
        if(stopAndStartIW) infoWindowManager.stop();
        this.deleteMarker(marker.id);
    		this.map.addOverlay(marker.GoogleMarker);
    		this.markerList.set(marker.id, marker);
        if(stopAndStartIW) infoWindowManager.start();
      }
    }
    this.refreshMarker([marker.id, this.markerList.get(marker.id)]);
//    delete marker;
	},
	'deleteMarker' : function() {
    var data = $A(arguments);
    var id = data[0];
    if(!Object.isUndefined(this.markerList.get(id))) {
			this.markerList.get(id).GoogleMarker.hide();
			this.map.removeOverlay(this.markerList.get(id).GoogleMarker);
			this.markerList.get(id).GoogleMarker = null;
			this.markerList.set(id, null);
			this.markerList.unset(id);
    }
	},
	'clearMarkerList' : function() {
		this.markerList.each(this.deleteMarker.bindAsEventListener(this));
	},
	'getMarker' : function(id) {
		return this.markerList.get(id);
	},
	'getMapBounds' : function(){
		var bounds = this.map.getBounds();
		var Ncornerpoint = bounds.getSouthWest();
		var Scornerpoint = bounds.getNorthEast();
		return {'lat1' : Scornerpoint.lat(), 'lng1' : Scornerpoint.lng(), 'lat2' : Ncornerpoint.lat(), 'lng2' : Ncornerpoint.lng()};
	},
	'getZoomLevel' : function(){
		return this.map.getZoom();
	},
	'getCenter' : function(){
		return this.map.getCenter();
	},
	'setCenter' : function(latlng, zoom){
		this.map.setCenter(latlng, zoom);
	},
	'whereToGo' : function(address){
		var geocoder =  new GClientGeocoder();
		geocoder.getLocations(address,this.updateMap.bindAsEventListener(this));
	},
	'updateMap' : function(response){
		if (!response || response.Status.code != 200) {
			openErrorForm('Warning', 'Address not found');
		} else {
      var tabAccuracy = new Array(2,4,6,10,12,13,16,16,17);
			this.options.dragStart();
			place = response.Placemark[0];
			point = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);
			this.map.setCenter(point,tabAccuracy[place.AddressDetails.Accuracy], G_NORMAL_MAP);
			whereToGoCalled = true;
			this.options.dragEnd();
		}
	},
	'setFilter' : function(data){
    var result = '';
    for(var i=0; i<data.length; i++){
      if(data[i]!=MARKER_TYPE_NOT_HIDEABLE){
        result += '|' + data[i];
      }
    }
    result += '|';
    this.filter = result;
    this.refreshDisplay();
  },
  'refreshDisplay' : function(){
		this.markerList.each(this.refreshMarker.bindAsEventListener(this));
  },
  'refreshMarker' : function(){
    var data = $A(arguments);
    var marker = data[0][1];
    if(this.filter.indexOf('|'+marker.type+'|')==-1){
      marker.GoogleMarker.show();
    } else {
      marker.GoogleMarker.hide();
    }
  }
};







CMarkerManager.prototype = {
	'initialize' : function(id_param, coordinates, label_param, type, options){
		this.id = id_param;
		this.label = label_param;
		this.coordinates = coordinates;
		this.type=type;
		this.options = {
			'title':'',
			'markerClickEvent' : function() {},
			'markerMouseOverEvent' : function() {},
      'markerMouseOutEvent': function() {},
      'drag': function() {},
      'dragstart' : function() {},
      'dragend' : function() {}
		};
		Object.extend(this.options, options || {});
		this.options.icon = this.createIcon();
		this.GoogleMarker = new GMarker(this.coordinates, this.options);

		GEvent.addListener(this.GoogleMarker, "click",      this.options.markerClickEvent.bindAsEventListener(this, this.id));
		GEvent.addListener(this.GoogleMarker, "mouseover",  this.options.markerMouseOverEvent.bindAsEventListener(this, this.id));
		GEvent.addListener(this.GoogleMarker, "mouseout",   this.options.markerMouseOutEvent.bindAsEventListener(this, this.id));
		GEvent.addListener(this.GoogleMarker, "drag",       this.options.drag.bindAsEventListener(this, this.id));
		GEvent.addListener(this.GoogleMarker, "dragstart",  this.options.dragstart.bindAsEventListener(this, this.id));
		GEvent.addListener(this.GoogleMarker, "dragend",    this.options.dragend.bindAsEventListener(this, this.id));
	},
	'justAMove': function(markerB){
  	var markerAOptions = this.options;
  	var markerBOptions = markerB.options;
  	Object.extend(markerAOptions, {"lat":0, "lng":0});
  	Object.extend(markerBOptions, {"lat":0, "lng":0});
  	return (Object.toJSON(markerAOptions) == Object.toJSON(markerBOptions));
	},
	'createIcon': function(){
		var mylabel = {
				"image":this.options.imageUrl,
				"iconSize":this.options.iconSize,
				"shadow":this.options.shadowUrl,
				"shadowSize":this.options.shadowSize,
				"infoWindowAnchor":this.options.infoWindowAnchor,
				"iconAnchor":this.options.iconAnchor,
				"imageMap":this.options.imageMap,
				"transparent":this.options.transparent
			};
		return new GIcon(mylabel);
	},
  'getLatLng': function(){
    return this.GoogleMarker.getLatLng();
  }
};





var savedNameValue = '';

var CMarkerManagerDrag = Class.create(CMarkerManager, {
  initialize: function($super, lat, lng, name, options) {
    this.id='addMarker';
    savedNameValue = '';
    this.options = {
      'id':this.id,
			'draggable' : true,
			'bouncy' : true,
			'imageUrl' : 'Img/pushpin/add_pushpin.gif',
			'imageMap' : [33, 1, 42, 6, 42, 12, 37, 15, 38, 20, 36, 24, 31, 24, 27, 30, 26, 26, 27, 24, 24, 20, 24, 14, 29, 10, 29, 4, 33, 1],
			'iconSize' : new GSize(55,54),
			'shadowUrl' : 'Img/pushpin/add_pushpin_shadow.png',
			'iconAnchor' : new GPoint(27,29),
			'infoWindowAnchor' :  new GPoint(32,3),
			'shadowSize' : new GSize(55,54),
			'markerClickEvent' : function(){},
			'markerMouseOverEvent' : function(){},
			'markerMouseOutEvent' : function(){},
      'stopAddMarkerMode':function(){
        map.deleteMarker(this.id);
        enableUserOnMap();
      },
      'dragstart' : function (){
        this.options.addWindow.options.onClose=null;
        if(this.options.addWindow != null){
          infoWindowManager.closeActiveInfoWindow();
        }
      },
      'dragend' : function (){
        this.options.addWindow.options.onClose=this.options.stopAddMarkerMode.bindAsEventListener(this);
        if(this.options.addWindow != null){
          infoWindowManager.setMinLevelPriority(PRIORITY_MESSAGE_SYSTEM);
          infoWindowManager.addMessage(this.options.addWindow);
        }
      },
      'submitfunction' : addPod
		};

		Object.extend(this.options, options || {});

    this.options.addWindow = new CInfoWindow(
      this.id,
      ' name: <input type="text" id="addMarkerName" value="" style="margin-left:5px; margin-right:5px; width:130px;" /><input type="button" value="add" onclick="map.getMarker(\''+this.id+'\').addMarker();" />',
      {
        'level':PRIORITY_MESSAGE_SYSTEM,
        'onClose':null,
        'onOpen':function(){
          var addMarkerNameInput = new CInputGestion('addMarkerName', {
                                  'defaultValue':'',
                                  'onKeyUp':function(){
                                    savedNameValue=$('addMarkerName').value;
                                  },
                                  'onSubmit':function(){
                                    map.getMarker('addMarker').addMarker();
                                  }
                                });
          addMarkerNameInput.options.setValue(savedNameValue);
          $('addMarkerName').focus();
        }
      }
    );

    $super(this.id,
           new GLatLng(lat, lng),
           name,
           MARKER_TYPE_NOT_HIDEABLE,
           this.options);

    setTimeout(this.options.dragend.bindAsEventListener(this), 50);

    disableUserOnMap();
  },
  addMarker:function(){
    var center = this.getLatLng();
    this.options.submitfunction(savedNameValue, center.lat(), center.lng());
  }
});


