var Map = new Class({
	Implements: Options,
	
	options : {
		target : 'map',
		marker : '/img/google/marker.png',
		copy : true,
		scale : false,
		lang : 'fr',
		
		timer : 5000,
		groupSize : 5,
		
		points : [
			{
				lng : '',
				lat : '',
				address : 'Montreux, Schweiz',
				msg : 'PAS cocorico'
			}
		],
		
		zoom : 10
	},
	
	initialize : function(options){
		this.setOptions(options);
		this.points = [];
		this.geoPointsIN = [];
		this.geoPoints = [];
		this.initialized = false;
		
		this.target = $(this.options.target);
		if(this.target != null) this.loadMaps();
	},
	
	loadMaps : function(){
		var $this = this;
		var next = function(){
			$this.setPoints()
		}
		
		google.load("maps", "3", {
			callback : next,
			language : this.options.lang,
			other_params:"sensor=false" 
		});
	},
	
	setPoints : function(){
		//create points list and add them to the bound
		this.bound = new google.maps.LatLngBounds();
		this.options.points.each(function(point){
			//do we have coordinates?
			if(point.lat != '0.000000' && point.lng != '0.000000' && point.lat != '' && point.lng != '') {
				var gPoint = new google.maps.LatLng(point.lat, point.lng);
				gPoint.eslUrl = publish == 1 ? point.url : point.urln;
				gPoint.zoom = point.zoom ? point.zoom : this.options.zoom;
				this.bound.extend(gPoint);
				this.points.push(gPoint);
			} else {
				this.geoPoints.push(point);
			}
			if (point.zoom && point.zoom.toInt()) this.options.zoom = point.zoom;
		}, this);
		
		this.length = this.options.points.length;
		
		//geopoints
		if(!this.geoPoints.length) {
			//get center of all points
			this.center = this.bound.getCenter();
			
			//setMap
			this.setMap();
			this.addPoints();
			this.setCopy();
		} else {
			this.geoPoints.each(function(point){
				this.geoPointsIN.push(point);
			}, this);
			this.geoCode();
		}
	},
	
	geoCode : function(){
		var geocoder = new google.maps.Geocoder();
		//code point by packets
		if(this.geoPointsIN.length) {
			var lh = this.geoPointsIN.length > this.options.groupSize ? this.options.groupSize : this.geoPointsIN.length;
			for (var i = 0; i < lh; i++) {
				//compute coordinates with geocoder
				geocoder.geocode({ 'address': this.geoPointsIN[i].address}, function(results, status) {
					if (status == google.maps.GeocoderStatus.OK) {
						var point = this.geoPointsIN.shift();
						var gPoint = results[0].geometry.location;
						gPoint.eslUrl = publish == 1 ? point.url : point.urln;
						gPoint.zoom = point.zoom;
						this.bound.extend(gPoint);
						this.points.push(gPoint);
						
						//set map
						if (!this.initialized) {
							this.setMap();
							this.setCopy();
						}
						this.addPoints();
					} 
				}.bind(this));
			}
		}
		
		if(this.geoPointsIN.length) this.geoCode.delay(this.options.timer, this);
		
	},
	
	setMap : function(){
		//get center of all points
		this.center = this.bound.getCenter();
		
		//create the map
		var zoom = this.options.zoom-1;
		this.map = new google.maps.Map($('map'), {
			zoom: zoom,
			center: this.center,
			navigationControl: true,
			navigationControlOptions: {
				style: google.maps.NavigationControlStyle.SMALL
			},
			scrollwheel : false,
    		scaleControl: this.options.scale ? true : false,
    		mapTypeControl: false,
			mapTypeId: google.maps.MapTypeId.ROADMAP
	    });
		
		//fit map to points
		this.initialized = true;
	},
	
	addPoints : function(){
		//add all points to map
		this.points.each(function(){
			var point = this.points.shift();
			var marker = new google.maps.Marker({
				position: point,
				map: this.map,
				icon: this.options.marker,
				flat : true
			});
			if (point.eslUrl != undefined)
			google.maps.event.addListener(marker, 'click', function() {
				window.location = point.eslUrl;
			});
		}, this);
		
		if(this.length > 1) this.map.fitBounds(this.bound);
	},
	
	setCopy : function(){
		if (this.options.copy) return;
		//remove copy left and right
		var cleaned = false;
		var map = this.map;
		google.maps.event.addListener(this.map, 'tilesloaded', function() {
			if(!cleaned) {
				map.n.getFirst().getNext().destroy();
				map.n.getFirst().getNext().destroy();
				cleaned = true;
			}
		});
	}
});
