(function() {

	/**
	 * @exports mxn.util.$m as $m
	 */
	var $m = mxn.util.$m;

	/**
	 * Initialise our provider. This function should only be called from within mapstraction code, not exposed as part
	 * of the API.
	 *
	 * @private
	 */
	var init = function() {
		this.invoker.go('init', [ this.map, this.api ]);
	};

	/**
	 * MapstractionNavigator instantiates a navigation source with some API choice
	 *
	 * @name mxn.MapstractionNavigator
	 * @constructor
	 * @param {String} api The API to use
	 * @param {Bool} debug optional parameter to turn on debug support - this uses alert panels for unsupported actions
	 * @exports MapstractionNavigator as mxn.MapstractionNavigator
	 */
	var MapstractionNavigator = mxn.MapstractionNavigator = function(map, api, debug) {
		if (!api) {
			api = mxn.util.getAvailableProviders()[0];
		}

		/**
		 * The name of the active API.
		 *
		 * @name mxn.MapstractionNavigator#api
		 * @type {String}
		 */
		this.api = api;

		this.map = map;

		this.navigators = {};
		this.maps = {};
		this.currentLocation = {};

		// set up our invoker for calling API methods
		this.invoker = new mxn.Invoker(this, 'MapstractionNavigator', function() {
			return this.api;
		});

		init.apply(this);
	};

	mxn.addProxyMethods(MapstractionNavigator, [
	/**
	 * Implements the navigation process
	 */
	'navigate'

	]);

	/**
	 * Change the Navigation API to use
	 *
	 * @param {String} api The API to swap to
	 */
	MapstractionNavigator.prototype.swap = function(api) {
		if (this.api == api) {
			return;
		}

		this.api = api;
		if (this.navigators[this.api] == undefined) {
			init.apply(this);
		}
	};

	MapstractionNavigator.prototype.getCurrentPosition = function(callback) {
		var me = this;
		if (navigator) {
			navigator.geolocation.getCurrentPosition(function(result) {
				me.handleCurrentPosition(result, callback);
			}, function(error) {
				me.handleCurrentPosition(error, callback);
			});
		}
	};

	MapstractionNavigator.prototype.handleCurrentPosition = function(position, callback) {
		if (position.coords) {
			var location = new mxn.Location("",
					new mxn.LatLonPoint(position.coords.latitude, position.coords.longitude));
			this.currentLocation = location;
			callback();
		} else {
			if (position.code) {
			// no current position available
			}
		}
	};

})();
