(function($) {

	var current = null;    
	
	function Googlemap(root, conf) {
		// current instance
		var self = this;
		if (!current) { current = self; }
		
		 // internal variables
		var map;
		var geo;
		
		// configuration (comments show default values)
		var latitude    	= conf.latitude;    // -35
		var longitude   	= conf.longitude;   // 150
		var zoom        	= conf.zoom;        // 4
		var maptype		= conf.maptype;
		var defaulticon 	= conf.defaulticon;
		var enablecontrols 	= conf.enablecontrols;
		var backgroundcolor	= conf.backgroundcolor;
		var scroll		= conf.scroll;
		var zoomcenter		= conf.zoomcenter;
		var searchfield		= conf.searchfield;
		//Conf markers
		var markers		= conf.markers;
		var infowindows		= conf.infowindows;
		var addresses		= conf.addresses;
		var draggablemarker	= conf.draggablemarker;
		var centertomarker	= conf.centertomarker;
		var latfield		= conf.latfield;
		var lngfield		= conf.lngfield;
		
		// methods
		$.extend(self, {
			// plugin specific
			getVersion: 	function() { return [1, 0, 0]; },
			getRoot: 	function() { return root; },
			getMap: 	function() { return map; },
			initialise: 	function() {
				var center = new google.maps.LatLng(latitude, longitude);
				var myOptions = {
					zoom: zoom,
					center: center,
					mapTypeId: maptype,
					disableDefaultUI: !enablecontrols,
					backgroundColor: backgroundcolor,
					scrollwheel: scroll
				};
				map = map || new google.maps.Map(document.getElementById($(root)[0].id), myOptions );				

				$(root).prev('div.search').remove();
				$(root).before('<div class="search" style="display:none;"><input type="text" class="text" value="'+addresses[0]['address']+'"/><input type="submit" class="submit" value="Trouver l\'adresse" /></div>')
			    $(root).prev('div.search').children('input.submit').click(function(){ self.geocode(0,{'address':$(this).parent().find('input.text').val(),'icon':defaulticon,'text':''}); });
				
				if(addresses){					
					for(var i = 0; i < addresses.length; i++){ 
						if(addresses[i]['address']) {
							self.geocode(i, addresses[i]); }
						else if(addresses[i]['lat'] && addresses[i]['lng']) {
							var markerPoint = new google.maps.LatLng(addresses[i]['lat'], addresses[i]['lng']);
							self.addMarker(i,markerPoint,addresses[i]['text'],addresses[i]['icon'],addresses[i]['setcenter']); }
					}
				}								

				if(searchfield){ $(root).prev('div.search').show().children('input.submit').trigger('click');	}				
			},
			geocode:	function(index, address) {
				geo = geo || new google.maps.Geocoder();
				
				geo.geocode({'address': address['address']}, function(results, status) {
					if (status == google.maps.GeocoderStatus.OK) {
						if(markers[index]){ 
							markers[index].setPosition(results[0].geometry.location);
							map.setCenter(markers[index].getPosition());
						}
						else markers[index] = self.addMarker(index, results[0].geometry.location, address['text'], address['icon']);	
					} else { alert("La géolocalisation n'a pas fonctionné pour la raison suivante : " + status + " / id : " + address['address']); }
				});
			},
			addMarker:	function(index, position, label, icon, setcenter) {
				var marker = new google.maps.Marker({
					map: map, 
					position: position,
					icon: icon || defaulticon,
					draggable: draggablemarker
				});
				if(centertomarker){
					map.setCenter(position);
					map.setZoom(zoomcenter);
				}
				if(draggablemarker){
					self.outputMarkerPosition(marker);
					google.maps.event.addListener(marker, 'dragend', function() { self.outputMarkerPosition(marker); });
				}
				if(label){
					infowindows[index] = new google.maps.InfoWindow({content: label, maxWidth:300});
					if(setcenter) infowindows[index].open(map,marker);
					google.maps.event.addListener(marker, 'click', function() {
						infowindows[index].open(map,marker);						
					});
				}
				google.maps.event.addListener(marker, 'dblclick', function() { 
					map.setCenter(marker.getPosition()); 
					map.setZoom(zoomcenter);
					infowindows[index].open(map,marker);
				});
				google.maps.event.addListener(marker, 'rightclick', function() { 
					map.setCenter(new google.maps.LatLng(latitude, longitude)); 
					map.setZoom(zoom);
					infowindows[index].close();
				});
				return marker;
			},
			outputMarkerPosition:	function(marker) {
				$(latfield).val(marker.getPosition().lat());
				$(lngfield).val(marker.getPosition().lng());
			}
		});
		    
		function load() {
            		self.initialise();
            		return self;
        	}
        
        	load();		    
	}
                
        $.fn.jgooglemap = function(conf) {
		// already constructed --> return API
		if(!conf.newmap){
			var api = this.eq(typeof conf == 'number' ? conf : 0).data("googlemap");
			if (api) { return api; }	
		}
		
		var opts = {
		    latitude		: 	45.7477607727051,
		    longitude		: 	-0.637035369873047,
		    zoom		: 	10,
		    zoomcenter		: 	17,
		    maptype		: 	google.maps.MapTypeId.ROADMAP,
		    enablecontrols	: 	true,
		    backgroundcolor	: 	'#ffffff',
		    scroll		: 	true,
    		addresses		: 	null,
		    draggablemarker	: 	false,
		    centertomarker	: 	false,
		    latfield 		: 	'#googlemap-lat',
		    lngfield 		: 	'#googlemap-lng',		    
		    defaulticon		: 	'/img/picto-gmap.png',		    
		    markers		: 	new Array(),
		    infowindows		: 	new Array(),
		    searchfield		:	false
		};
		
		$.extend(opts, conf);		
				
		return this.each(function() { $(this).data("googlemap", new Googlemap($(this), opts)); });
    	};
    	$.fn.jgooglemap.getmarkers = function() { return 'ok'; };
	
})(jQuery);
