$.fn.extend({
	// Déclaration des variables
	path: [],
	addresses: [],
	active: [true,false,false,false,true],
	gmarkers: [],
	state: 0,

	jmap: function(settings) {
		var version = "0.1";
		
		/* Default Settings*/	
		settings = jQuery.extend({
			maptype: G_HYBRID_MAP,
			center: [55.958858,-3.162302],
			zoom: 12,
			control: "small",
			showtype: true,
			showoverview: true,
			dragging: true,
			scrollzoom: true,
			smoothzoom: true,
			searchfield: "#Address",
			searchbutton: "#findaddress"
		},settings);
				
		if (GBrowserIsCompatible())
		{
			return this.each(function(){
				var jmap = this.GMap2 = new GMap2(this);
				GGeocoder = new GClientGeocoder();
				
				this.GMap2.setCenter(new GLatLng(settings.center[0],settings.center[1]),settings.zoom,settings.maptype);
				switch(settings.control)
				{
					case "small":
						this.GMap2.addControl(new GSmallMapControl());
						break;
					case "large":
						this.GMap2.addControl(new GLargeMapControl());
						break;
					case "none":
						break;
					default:
						this.GMap2.addControl(new GSmallMapControl());
				}
			
				if (settings.showtype == true){
					this.GMap2.addControl(new GMapTypeControl());
				}
				if (settings.showoverview == true){
					this.GMap2.addControl(new GOverviewMapControl());
				}
			
				if (settings.scrollzoom == true) {
					/* Off by default */
					this.GMap2.enableScrollWheelZoom();
				}
				if (settings.smoothzoom == true) {
					/* Off by default*/
					this.GMap2.enableContinuousZoom();
				}
				if (settings.dragging == false) {
					/* On by default */
					this.GMap2.disableDragging();
				}

				jQuery(document).unload(function(){ GUnload(); });
			});
		}
	},
    
	myMap: function() {
		return this[0].GMap2;
		
	},
    
	addPoint: function(pointlat, pointlng, pointhtml, isdraggable, removable, num_icon, i) {
		GEvent.addListener(this[0].GMap2, "click", function(overlay, point) {
			if (point) {
				if($('#gmap').state == 0) { $('#gmap').doStart(point) }
			}
		});
		
		var jmap = this[0].GMap2;
		
		// Création des icones
		var baseIcon = new GIcon(G_DEFAULT_ICON);
		baseIcon.iconSize=new GSize(24,38);
		
		var icon = new GIcon(baseIcon,"ressources/habillage/icone_aa_map.png");
		icon.iconSize= new GSize(40, 53);
		var icon1 = G_START_ICON;
		var icon2 = G_PAUSE_ICON;
		var icon3 = G_END_ICON;
		var icon4 = new GIcon(baseIcon,"http://labs.google.com/ridefinder/images/mm_20_white.png");
			icon4.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
			icon4.iconSize = new GSize(12, 20);
			icon4.shadowSize = new GSize(22, 20);
			icon4.iconAnchor = new GPoint(6, 20);
			icon4.infoWindowAnchor = new GPoint(5, 1);

		var marker = new GMarker(new GLatLng(pointlat,pointlng), {draggable: isdraggable, icon: eval('icon' + num_icon)} );
		$('#gmap').gmarkers[i]=marker;
		
		GEvent.addListener(marker, "click", function(){
			marker.openInfoWindowHtml(pointhtml);
		});
		
		if (isdraggable == true) {
			GEvent.addListener(marker, "dragend", function(){
				$('#gmap').path[i] = marker.getPoint();
				if (!$('#gmap').active[i]){
					setTimeout('$("#gmap").swapMarkers('+i+')', 1000);
				}
				$('#gmap').active[i] = true;
				$('#gmap').addresses[i] = "";
			});
		}
		
		if (removable == true) {
			GEvent.addListener(marker, "dblclick", function(){
				return jmap.removeOverlay(marker);
			});
		}
		jmap.addOverlay(marker);
		return marker;
	},
	addPoly: function (poly) {
		var jmap = this[0].GMap2;
		return jmap.addOverlay(poly);
	},
	/* FIXME: KML File not rendering*/
	addKml: function (kmlfile) {
		var jmap = this[0].GMap2;
		var geoXml = new GGeoXml(kmlfile);
		return jmap.addOverlay(geoXml);
	},
	
	showAddress: function(state, search) {
		var jmap = this[0].GMap2;
		
		var reasons=[];
		reasons[G_GEO_SUCCESS]            = "Success";
		reasons[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
		reasons[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
		reasons[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
		reasons[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
		reasons[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
		reasons[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
		reasons[G_GEO_BAD_REQUEST]        = "A directions request could not be successfully parsed.";
		reasons[G_GEO_MISSING_QUERY]      = "No query was specified in the input.";
		reasons[G_GEO_UNKNOWN_DIRECTIONS] = "The GDirections object could not compute directions between the points.";
		
		if(state == 0){
			$('#gmap').addresses[0] = search;
		}
		else if (state==1) {
			var search = $.pointx + ', ' + $.pointy;
			$('#gmap').addresses[4] = $.to;
		}

		var geo = new GClientGeocoder(new GGeocodeCache());
		geo.getLatLng(search, function (point){
			if (point){
				if(state==0) {$('#gmap').doStart(point)}
				else if(state==1) {$('#gmap').doEnd(point)}
			}
			else{
				var result=geo.getCache().get(search);
				if(result){
					var reason="Code "+result.Status.code;
					if(reasons[result.Status.code]){
						reason = reasons[result.Status.code]
					}
				} else {
					var reason = "";
				}
				alert('Could not find "'+search+ '" ' + reason);
			}
		});
	},

	doStart: function(point){
		$('#gmap').addPoint(point.lat(), point.lng(), '', true, false, 1, 6);
		$('#gmap').path[0] = point;

		$('#gmap').state = 1;
		$('#gmap').showAddress(1);
		
		$('#start').hide();
		$('#direction').show();
	},
	
	doEnd: function(point){
		var jmap = this[0].GMap2;
		
		$('#gmap').addPoint(point.lat(), point.lng(), '', false, false, '', 5);
		$('#gmap').path[4] = point;
		$('#gmap').state = 2;
		//handleState();
		for (var i=1; i<4; i++) {
			var lat = ($('#gmap').path[0].lat()*(4-i) + $('#gmap').path[4].lat()*i)/4;
			var lng = ($('#gmap').path[0].lng()*(4-i) + $('#gmap').path[4].lng()*i)/4;
			var p = new GLatLng(lat,lng);
			$('#gmap').addPoint(p.lat(), p.lng(), '', true, false, 4, i);
		}
	
		var bounds = new GLatLngBounds();
		bounds.extend($('#gmap').path[0]);
		bounds.extend($('#gmap').path[4]);
		jmap.setZoom(jmap.getBoundsZoomLevel(bounds));
		jmap.setCenter(bounds.getCenter());
	},

	directions: function(query, panel, language) {
		var jmap = this[0].GMap2;
		var dirpanel = document.getElementById(panel);
		
		if($('#gmap').addresses[0])
			var a = $('#gmap').addresses[0] + "@" + $('#gmap').path[0].toUrlValue(6);
		else
			var a = $('#gmap').path[0].toUrlValue(6);

		if($('#gmap').addresses[4])
			var b = $('#gmap').addresses[4] + "@" + $('#gmap').path[4].toUrlValue(6);
		else
			var b = $('#gmap').path[4].toUrlValue(6); 

		for(var i=3; i>0; i--) {
			if($('#gmap').active[i]){
				b = $('#gmap').path[i].toUrlValue(6) +" to: "+b;
			}
		}
	
		var query = "from: "+a + " to: " + b;
		
		if(typeof(directions) == 'undefined')
			directions = new GDirections(jmap, dirpanel);
	
		directions.load(query, {getPolyline:true, "locale":language});

		jmap.removeOverlay($('#gmap').gmarkers[0]);
		jmap.removeOverlay($('#gmap').gmarkers[5]);
		jmap.removeOverlay($('#gmap').gmarkers[6]);
		
		$('#path').show();
	},
	
	swapMarkers: function(i) {
		var jmap = this[0].GMap2;
		jmap.removeOverlay($('#gmap').gmarkers[i]);
		$('#gmap').addPoint($('#gmap').path[i].lat(), $('#gmap').path[i].lng(), '', true, false, 4);
	}
});