/**

Copyright 2009 Palm, Inc.  All rights reserved.

*/

GeoControl = {
	_fixCache: {},

	/**
	 * Return the Location information
	 * 
	 * @return {Hash}  A hash of the latitude, log, accuracy and fix time
	 */
	getLocation: function(){
		return GeoControl._fixCache;
	},

	/**
	 * Check if the GEO service is enabled and start tracking.
	 * 
	 * If the user has not accepted the TOS for LBS then we will not add LBS info to 
	 * pictures taken with the camera.
	 */	
	lbsCheckAndStart: function(){
		if (GeoControl._checkServiceRequest){
			// request already pending
			return;
		}
		
		//Clearout stale fix info
		GeoControl._fixCache = {};

		GeoControl._checkServiceRequest = new Mojo.Service.Request(GeoControl.LBS.serviceUri, {
				method: GeoControl.LBS.getService,
				onSuccess: GeoControl._checkLBSResponse,
				onFailure: GeoControl._checkLBSErrorResponse
			});


		if (GeoControl._fixMonitorElem) {
			GeoControl._fixMonitorElem.style.backgroundColor = "#a0a000";
		}		
	},
	
	/**
	 * Callback that checks whether the LBS service is enabled
	 * 
	 * @param {Object} params    Parameter block from the service. 
	 * 
	 * @private
	 */
	_checkLBSResponse: function(params){
		delete GeoControl._checkServiceRequest;
		
		llog("_checkLBSResponse: "+Object.toJSON(params));

		if ( (params) && (params.geotagPhotos) ){
			GeoControl.startTracking();
		}
		else{
			llog("   Not starting tracking");
			
			if (GeoControl._fixMonitorElem) {
				GeoControl._fixMonitorElem.style.backgroundColor = "#ff0000";
			}		
		}
	},
	_checkLBSErrorResponse: function(){
		delete GeoControl._checkServiceRequest;
	},

	/**
	 * Start the periodic pinging of the service that returns the location.
	 * 
	 */
	startTracking: function(){
		llog("GeoControl::startTracking");

		if (GeoControl._activeRequest){
			delete GeoControl._activeRequest;
		}
		
		//Clearout stale fix info
		GeoControl._fixCache = {};

		
		var params = {
			appId: 'com.palm.app.camera',
			accuracy: 2,      /*low*/
			responseTime: 1,  /*fast*/
			maximumAge: 60    /*secs*/
		};

		GeoControl._activeRequest = new Mojo.Service.Request(GeoControl.LBS.serviceUri, {
				method: GeoControl.LBS.getFix,
				parameters: params,
				onSuccess: GeoControl._handleNewFix,
				onFailure: GeoControl._handleError
			});

			
		if (GeoControl._fixMonitorElem) {
			GeoControl._fixMonitorElem.style.backgroundColor = "#ffff00";
		}		
			
	},
	
	updateFix: function(){
		llog("GeoControl::updateFix");
		
		GeoControl._refixTimeout = setTimeout(GeoControl.updateFix, GeoControl.REFIX_FREQUENCY);

		if (GeoControl._activeRequest){
			//still waiting for the last fix to respond
			return;
		}
		
		var params = {
			appId: 'com.palm.app.camera',
			accuracy: 1,      /*high*/
			responseTime: 2,  /*medium*/
			maximumAge: 60    /*secs*/
		};

		GeoControl._activeRequest = new Mojo.Service.Request(GeoControl.LBS.serviceUri, {
				method: GeoControl.LBS.getFix,
				parameters: params,
				onSuccess: GeoControl._handleNewFix,
				onFailure: GeoControl._handleError
			});

	},

	// Used if the GPS accuracy monitor is up.
	_fixMonitorElem: null,

	_handleNewFix: function(data){
		llog("GEO GeoControl._handleNewFix: "+(data?Object.toJSON(data):"") );

		if (GeoControl._activeRequest) {
			delete GeoControl._activeRequest;
		}

		if ( !data || !data.latitude || !data.longitude ){
			llog("Fix had no lat or long");
			return;
		}

		var now = new Date().getTime();
		GeoControl._fixCache.time = now;		

		GeoControl._fixCache.latitude = data.latitude;
		GeoControl._fixCache.longitude = data.longitude;


		// Put in a periodic call to get a new fix
		if (GeoControl._refixTimeout) {
			clearTimeout(GeoControl._refixTimeout);
		}
		GeoControl._refixTimeout = setTimeout(GeoControl.updateFix, GeoControl.REFIX_FREQUENCY);

		if (GeoControl._fixMonitorElem){
			if (data.horizAccuracy <= 30){
				GeoControl._fixMonitorElem.style.backgroundColor = "#00ff00";
			}
			else if (data.horizAccuracy <= 300){
				GeoControl._fixMonitorElem.style.backgroundColor = "#60c060";
			}
			else {
				GeoControl._fixMonitorElem.style.backgroundColor = "#60a060";
			}
			
			// Just use the color for now.
			//GeoControl._fixMonitorElem.innerHTML = data.horizAccuracy;
		}
	},
	_handleError: function(data){
		llog("GEO GeoControl._handleError: ", Object.toJSON(data));

		GeoControl.stopTracking();
		delete GeoControl._activeRequest;
		
		if (GeoControl._fixMonitorElem) {
			GeoControl._fixMonitorElem.style.backgroundColor = "#ff0000";
		}
	},
	
	stopTracking: function(){
		llog("Stop tracking requsted");

		if (GeoControl._refixTimeout){
			clearTimeout(GeoControl._refixTimeout);
			delete GeoControl._refixTimeout;
		}
		
		if (GeoControl._activeRequest){
			GeoControl._activeRequest.cancel();
			delete GeoControl._activeRequest;
		}
		
		GeoControl._fixCache = {};
	},
	
	LBS: {
		serviceUri:'palm://com.palm.location',
		getFix: 'getCurrentPosition',
		getService: 'getGeotagPhotos',
		//getService: 'getUseLocationServices',
		stopTracking: 'stopTracking'
	},
	
	// How often should I poll the GPS service to get the current location
	REFIX_FREQUENCY: 60000,
	
	POI: {
		// Match to 4 decimal places
		palm:  '{latitude:37.392692, longitude:-122.040577}',
		step:  '{latitude:37.798333, longitude:-122.407222, code: 67046315320, map: [1,2,9,11,12,14,15,16]}',
		w3rd:  '{latitude:53.691869, longitude:-1.633192, code: 8167530342, map: [0,1,3,5,10,14,15,16,19] }'
	},
	
	/**
	 * 
	 * @param {Float} degrees   The position as a decimal
	 * 
	 * @return Value passed in converted to degrees minutes seconds.
	 */
	toDMS: function(degrees){
		var llBuilder = [];
		var llTemp = degrees;
		
		llBuilder[0] = Math.floor(llTemp);
		llTemp -= llBuilder[0];
		llTemp *= 60;
		llBuilder[1] = Math.floor(llTemp);
		llTemp -= llBuilder[1];
		llTemp *= 60;
		llBuilder[2] = Math.floor(llTemp);
		
		return llBuilder;
	}
}
