if (!com) var com={};
if (!com.lastminute) com.lastminute={};
if (!com.lastminute.labs) com.lastminute.labs={};











// Create the API
com.lastminute.labs.gears=
{
	// Some status codes
	RESULT_OK:1,
	RESULT_INIT_ERROR:-1,
	RESULT_GEARS_NOT_INSTALLED:-2,
	RESULT_POSITION_NOT_FOUND:-3,

	/**
	 * Holds the reference to the Google Gears object.
	 * This gets initialized automatically, you don't need to worry about it at all!
	 */
	geo:null,
	
	/**
	 * Holds the last position that this API found from Gears. Get it through the function get_last_location().
	 */
	position:null,
	
	/**
	 * Holds the geocoder object (created by a call to get_location_from_string) - You don't need to 
	 * care about it, it's just a cached object to prevent it from being re-created every call.
	 */
	geocoder:null,
	
	/**
	 * Holds the watch that's used to get the wifi location
	 */
	watch_id:null,
	
	/**
	 * Just a little debug function - outputs a message to console.log
	 * 
	 * @param message The message to output
	 */
	debug:function(message)
	{
		try
		{
			console.log(message);
		}
		catch(e) { }
	},
	
	/**
	 * Is gears initialised OK?
	 */
	initialised:false,
	
	/**
	 * Initializes the Gears API
	 * Call this before you do anything in any other function to make sure that
	 * everything is OK with the gears API.
	 * 
	 * @return RESULT_OK if initialization is successful, either RESULT_GEARS_NOT_INSTALLED or RESULT_INIT_ERROR otherwise
	 */
	init:function()
	{
		// Only initialize gears once
		if (null==this.geo)
		{
			// Check to see if gears is installed
			if (!window.google || !google.gears)
				return this.RESULT_GEARS_NOT_INSTALLED;
			
			// Initialize the Geolocation object and store the last position
			this.geo=google.gears.factory.create('beta.geolocation');
			if (this.geo)
			{
				this.position=this.geo.lastPosition;
				
				this.initialised=true;
			}
		}

		// Return the correct error code
		return null!=this.geo?this.RESULT_OK:this.RESULT_INIT_ERROR;
	},
	
	/**
	 * Triggers a get position call to the Gears API.
	 * 
	 * It will use the best possible method, falling back to useing the last known position.
	 * 
	 * @param positionCallback A function that will be called when the position is found, passing the position as the first parameter
	 * @param errorCallback (optional) A callback that will be triggered if there is an error, passing the error code as the first parameter
	 * @param lastPositionFallback (optional, default true) If the position fails, we will just return the last position if this is true.
	 * 
	 * @return nothing
	 */
	get_location:function(positionCallback, errorCallback, lastPositionFallback)
	{
		if (this.RESULT_OK==this.init())
		{
			if (null!=this.watch_id)
			{
				try
				{
					this.geo.clearWatch(this.watch_id);
					this.watch_id=null;
				}
				catch (e)
				{
					this.watch_id=null;
				}
			}
			
			this.watch_id=this.geo.watchPosition(
				function(position)
				{
					com.lastminute.labs.gears.debug("Watch triggered - accuracy is "+position.accuracy);
					
					// Start getting the hotels data
					com.lastminute.labs.gears.position=position;
					positionCallback(position);

					if (position.accuracy < 1000)
					{
						com.lastminute.labs.gears.debug("Watch cancelled - accuracy is "+position.accuracy);
						com.lastminute.labs.gears.geo.clearWatch(com.lastminute.labs.gears.watch_id);
					}
				},
				function(error)
				{
					com.lastminute.labs.gears.debug('Error with gears : '+ error.message);
					
					if (true===lastPositionFallback && com.lastminute.labs.gears.geo.lastPosition)
					{
						com.lastminute.labs.gears.position=com.lastminute.labs.gears.geo.lastPosition;
						if (positionCallback)
							positionCallback(com.lastminute.labs.gears.geo.lastPosition);
					}
					else
						if (errorCallback)
							errorCallback(com.lastminute.labs.gears.RESULT_POSITION_NOT_FOUND);
				},
				{
					gearsLocationProviderUrls: [ 'http://www.google.com/loc/json' /*, 'http://amp.google.com/loc/json' */ ]
				} );			
		}
		else
			if (errorCallback)
				errorCallback(com.lastminute.labs.gears.RESULT_INIT_ERROR);
	},
	
	
	/**
	 * @param positionCallback Gets called with the position (or null if not available)
	 * @param errorCallback Called if there is an error getting the last position (i.e. Gears not installer or initialised)
	 * 
	 * @return The last position that gears got from this machine (or null in case of an error)
	 */
	get_last_location:function(positionCallback, errorCallback)
	{
		var result=this.init();
		if (this.RESULT_OK==result)
		{
			positionCallback(this.position);
			return this.position;
		}

		if (errorCallback)
			errorCallback(result);

		return null;
	},
	
	/**
	 * Given a string, it will return a position object (well, an obejct with latitude, longitude and timestamp set)
	 * 
	 * NB This function only works if you're also using the Google maps API!
	 * 
	 * @param address The string to geocode
	 * @param positionCallback The function to call, passing in the position
	 * @param errorCallback (optional) This is called in the case of an error
	 * 
	 * @return nothing
	 */
	get_location_from_string:function(address, positionCallback, errorCallback)
	{		
		if (!com.lastminute.labs.gears.geocoder)
			com.lastminute.labs.gears.geocoder = new GClientGeocoder();
			
		com.lastminute.labs.gears.geocoder.getLatLng(
			address,
			function(point)
			{
				if (point)
				{
					com.lastminute.labs.gears.position={latitude:point.lat(), longitude:point.lng(), timestamp:new Date(), from_text:true };
					positionCallback(com.lastminute.labs.gears.position);
				}
				else
				{
					com.lastminute.labs.gears.debug("Location not found '"+address+"'");
					if (errorCallback)
						errorCallback();
				}
			}
		);
	}
}
