/*
 * Provides L.Map with convenient shortcuts for using browser geolocation features.
 */

L.Map.include({
	_defaultLocateOptions: {
		watch: false,
		setView: false,
		maxZoom: Infinity,
		timeout: 10000,
		maximumAge: 0,
		enableHighAccuracy: false
	},

	locate: function (/*Object*/ options) {

		options = this._locationOptions = L.extend(this._defaultLocateOptions, options);

		if (!navigator.geolocation) {
			this._handleGeolocationError({
				code: 0,
				message: "Geolocation not supported."
			});
			return this;
		}

		var onResponse = L.bind(this._handleGeolocationResponse, this),
			onError = L.bind(this._handleGeolocationError, this);

		if (options.watch) {
			this._locationWatchId =
			        navigator.geolocation.watchPosition(onResponse, onError, options);
		} else {
			navigator.geolocation.getCurrentPosition(onResponse, onError, options);
		}
		return this;
	},

	stopLocate: function () {
		if (navigator.geolocation) {
			navigator.geolocation.clearWatch(this._locationWatchId);
		}
		return this;
	},

	_handleGeolocationError: function (error) {
		var c = error.code,
		    message = error.message ||
		            (c === 1 ? "permission denied" :
		            (c === 2 ? "position unavailable" : "timeout"));

		if (this._locationOptions.setView && !this._loaded) {
			this.fitWorld();
		}

		this.fire('locationerror', {
			code: c,
			message: "Geolocation error: " + message + "."
		});
	},

	_handleGeolocationResponse: function (pos) {
		var latAccuracy = 180 * pos.coords.accuracy / 4e7,
		    lngAccuracy = latAccuracy * 2,

		    lat = pos.coords.latitude,
		    lng = pos.coords.longitude,
		    latlng = new L.LatLng(lat, lng),

		    sw = new L.LatLng(lat - latAccuracy, lng - lngAccuracy),
		    ne = new L.LatLng(lat + latAccuracy, lng + lngAccuracy),
		    bounds = new L.LatLngBounds(sw, ne),

		    options = this._locationOptions;

		if (options.setView) {
			var zoom = Math.min(this.getBoundsZoom(bounds), options.maxZoom);
			this.setView(latlng, zoom);
		}

		this.fire('locationfound', {
			latlng: latlng,
			bounds: bounds,
			accuracy: pos.coords.accuracy
		});
	}
});

@@ -1543,102 +1543,8 @@
 var 
-latAccuracy = 180 * pos.coords.accuracy / 4e7,%0D%0A%09%09    lngAccuracy = latAccuracy * 2,%0D%0A%0D%0A%09%09    
 lat 
@@ -1640,24 +1640,157 @@
 t, lng),%0D%0A%0D%0A
+%09%09    latAccuracy = 180 * pos.coords.accuracy / 40075017,%0D%0A%09%09    lngAccuracy = latAccuracy / Math.cos(L.LatLng.DEG_TO_RAD * lat),%0D%0A%0D%0A
 %09%09    sw = n
@@ -2134,35 +2134,29 @@
 %0D%0A%09%09
-this.fire('locationfound', 
+var event = L.extend(
 %7B%0D%0A%09
@@ -2195,23 +2195,14 @@
 unds
-,
 %0D%0A%09%09
-%09accuracy:
+%7D,
  pos
@@ -2212,22 +2212,48 @@
 ords
-.accuracy%0D%0A%09%09%7D
+);%0D%0A%0D%0A%09%09this.fire('locationfound', event
 );%0D%0A

fix geolocation accuracy bounds, add more event data, close #984, related #584, #987, #1028