var OM_mooGoogleMaps = new Class({
	Implements: [Options, Events],
	options: {
		adminMode: {
			enabled: false,
			mode: null
		},
		ajaxFile: '/maps/pointers.asp',
		debugMode: false,
		enableTooltips: false,
		mapCenterLat: 0,
		mapCenterLng: 0,
		mapHolder: '',
		mapType: 'ROADMAP',
		mapId: 0,
		coordId: null,
		zoomLevel: 8
	},
	initialize: function(options){
		this.mapObject = null;
		this.mapOptions = null;
		this.mapCenter = null;
		this.markers = new Object();
		this.singleMarker = null;
		this.setOptions(options);
		this.mapHolder = this.options.mapHolder;
		this.domReady();
	},
	domReady: function(){
		var that = this;
		this.mapHolder = $(this.mapHolder);
		
		if($defined(this.mapHolder)){
			this.mapCenter = new google.maps.LatLng(this.options.mapCenterLat, this.options.mapCenterLng);
			this.mapOptions = {
				zoom: this.options.zoomLevel,
				center: this.mapCenter,
				mapTypeId: eval('google.maps.MapTypeId.' + this.options.mapType)
			};
			this.mapObject = new google.maps.Map(this.mapHolder, this.mapOptions);
			this.getAjaxMarkers();
			
			if(this.options.adminMode.enabled){
				switch(this.options.adminMode.mode){
					case 'moduleMaps':
						var centerPin = new google.maps.Marker({
							position: this.mapObject.getCenter(),
							map: this.mapObject
						});
						this.initializeAdminMode(centerPin);
						break;
					case 'moduleCoords':
						if(!this.options.coordId){
							this.initializeCoordsAdminMode();
						};
						break;
					default:
						return false;
				};
			};

			if(this.options.debugMode){
				google.maps.event.addListener(this.mapObject, 'click', function(event){
					var coords = that.returnCoords(event);
					$('coordsLat').set('text', 'Latitude : ' + coords.lat());
					$('coordsLng').set('text', 'Longitude : ' + coords.lng());
				});	
			};
		};
	},
	getAjaxMarkers: function(){
		var mooXhr = new Request.JSON({
			url: this.options.ajaxFile,
			link: 'chain',
			noCache: true,
			onRequest: function(){
			}.bind(this),
			onSuccess: function(stringJson,responseText){
				for (var key in stringJson.icons){
					var iconOptions = stringJson.icons[key];
					this.markers[key] = new google.maps.MarkerImage(
						'/images/maps/' + iconOptions.filename,
						new google.maps.Size(iconOptions.filewidth,iconOptions.fileheight),
						new google.maps.Point(iconOptions.originx,iconOptions.originy),
						new google.maps.Point(iconOptions.anchorx,iconOptions.anchory)
					);
				};

				for (var key in stringJson.markers){
					var markerOptions = stringJson.markers[key];
					var latLng = new google.maps.LatLng(markerOptions.latitude, markerOptions.longitude);
					var marker = new google.maps.Marker({
						position: latLng,
						icon: eval(this.markers[markerOptions.icon]),
						map: this.mapObject,
						title: markerOptions.title,
						zIndex: parseInt(markerOptions.zIndex),
						clickable: eval(markerOptions.clickable)
					});
					
					if(this.options.adminMode.mode=='moduleCoords'){
						this.singleMarker = marker;
						this.initializeCoordsAdminMode();
					};
					
					if(this.options.enableTooltips&&eval(markerOptions.clickable)){
						var map = this.mapObject;
						var tooltipContent = '<div style="background: red;">' + markerOptions.title + '<' + '/div>';
						var infowindow = new google.maps.InfoWindow({
							content: tooltipContent
						});
						google.maps.event.addListener(marker, 'click', function(event){
							infowindow.open(map,marker);
						});
					};
				};
			}.bind(this),
			onFailure: function(response){
				alert(response.responseText);
			}.bind(this)
		},this);
		
		mooXhr.get({
			mapId: this.options.mapId,
			coordId: this.options.coordId,
			zoomLevel: this.options.zoomLevel,
			mapCenterLat: this.options.mapCenterLat,
			mapCenterLng: this.options.mapCenterLng
		});
	},
	initializeCoordsAdminMode: function(){
		var that = this;
		var singleMarker = this.singleMarker;
		var inpLat = $('Latitude');
		var inpLng = $('Longitude');
		var inpIcone = $('Icone');
		var inpGeocode = $$('input.geocode');
		var newMarker = null;
		var geoCoder = new google.maps.Geocoder();
		
		if(this.options.coordId){
			newMarker = singleMarker;
		};
		
		google.maps.event.addListener(this.mapObject, 'click', function(event){
			var latLng = that.returnCoords(event);
			if(newMarker){
				newMarker.setPosition(latLng);
			}
			else{
				newMarker = new google.maps.Marker({
					position: latLng,
					map: that.mapObject
				});
			};
			if($defined(inpLat)){
				inpLat.set('value', latLng.lat());
			};
			if($defined(inpLng)){
				inpLng.set('value', latLng.lng());
			};
		});
		
		inpIcone.addEvent('change', function(event){
			if(this.selectedIndex>0){
				var optionString = this.getElements('option')[this.selectedIndex].get('title').split('|');
				if(!optionString==''){
					var options = {
						iconFileName: optionString[0],
						iconWidth: optionString[1],
						iconHeight: optionString[2],
						iconOriginX: optionString[3],
						iconOriginY: optionString[4],
						iconAnchorX: optionString[5],
						iconAnchorY: optionString[6]
					};
					that.editMarkerOptions(newMarker,options);
				};
			};
		});
		
		inpGeocode.addEvent('blur', function(event){
			var geoCodeReady = true;
			inpGeocode.each(function(item,index){
				if(!item.get('value')){
					geoCodeReady = false;
				};
			},this);
			if(geoCoder&&geoCodeReady){
				var address = this.addressToString(inpGeocode);
				geoCoder.geocode({'address': address}, function(results,status){
					if(status==google.maps.GeocoderStatus.OK){
						if(newMarker){
							newMarker.setPosition(results[0].geometry.location);
						}
						else{
							newMarker = new google.maps.Marker({
								map: that.mapObject,
								position: results[0].geometry.location
							});
						}
						if($defined(inpLat)){
							inpLat.set('value', results[0].geometry.location.lat());
						};
						if($defined(inpLng)){
							inpLng.set('value', results[0].geometry.location.lng());
						};
					}
					else{
						alert('L\'erreur suivante s\'est produite : ' + status);
					};
				});
			};
		}.bind(this));
		
		google.maps.event.addListener(this.mapObject, 'click', function(event){
			var latLng = that.returnCoords(event);
			newMarker.setPosition(latLng);
			if($defined(inpLat)){
				inpLat.set('value', latLng.lat());
			};
			if($defined(inpLng)){
				inpLng.set('value', latLng.lng());
			};
		});
	},
	initializeAdminMode: function(centerPin){
		var that = this;
		var inpLat = $('CentreLatitude');
		var inpLng = $('CentreLongitude');
		var inpZoom = $('ZoomLevel');
		var inpMapType = $('TypeCarte');
		
		inpMapType.addEvent('change', function(event){
			that.mapObject.setMapTypeId(eval('google.maps.MapTypeId.' + String(inpMapType[this.selectedIndex].get('title'))));
		});
		
		inpZoom.addEvent('blur', function(event){
			var zoomLevel = parseInt(this.get('value'));
			if(!isNaN(zoomLevel)&&zoomLevel>0&&zoomLevel<=22){
				that.mapObject.setZoom(zoomLevel);
			};
		});
		
		google.maps.event.addListener(that.mapObject, 'dragend', function(event){
			var latLng = that.mapObject.getCenter();
			centerPin.setPosition(latLng);
			if($defined(inpLat)){
				inpLat.set('value', latLng.lat());
			};
			if($defined(inpLng)){
				inpLng.set('value', latLng.lng());
			};
		});
		
		google.maps.event.addListener(that.mapObject, 'zoom_changed', function(event){
			var zoomLevel = that.mapObject.getZoom();
			if($defined(inpZoom)){
				inpZoom.set('value', zoomLevel);
			};
		});
		
		google.maps.event.addListener(that.mapObject, 'maptypeid_changed', function(event){
			var mapTypeId = that.parseMapTypeId(that.mapObject.getMapTypeId());
			var mapTypeIdOptions = inpMapType.getElements('option');
			mapTypeIdOptions.each(function(item,index){
				var isSelected = (item.get('value')==mapTypeId) ? true : false;
				item.set('selected', isSelected);
			},this);
		});
	},
	editMarkerOptions: function(marker,options){
		marker.setIcon(
			'/images/maps/' + options.iconFileName,	
			new google.maps.Size(options.iconWidth,options.iconHeight),
			new google.maps.Point(options.iconOriginX,options.iconOriginY),
			new google.maps.Point(options.iconAnchorX,options.iconAnchorY)
		);
		marker.setOptions()
	},
	addressToString: function(inputs){
		var address = inputs[0].get('value') + ' ' + inputs[1].get('value') + ', ' + inputs[2].get('value') + ', ' + inputs[3].get('value') + ', ' + inputs[4].get('value') + ', ' + inputs[5].get('value');
		return address;
	},
	parseMapTypeId: function(mapTypeId){
		var localId = 0;
		switch(mapTypeId){
			case 'hybrid':
				localId = 1;
				break;
			case 'roadmap':
				localId = 2;
				break;
			case 'satellite':
				localId = 3;
				break;
			case 'terrain':
				localId = 4;
				break;
			default:
				localId = 2
		};
		return localId;
	},
	returnCoords: function(event){
		if(event){
			return new google.maps.LatLng(event.latLng.lat(), event.latLng.lng());
		}
		else return false;
	}
});
