AppAssistant.url = "";
AppAssistant.webViewWidget = undefined;
AppAssistant.googleMapsURL = "http://maps.google.com/maps/m";
//AppAssistant.googleMapsURL = "http://gjm.google.com/mwm?sky=tfb";
AppAssistant.urlClientParam = "client=ms-mwm-palm";

function AppAssistant(appController) {
	Mojo.Log.info("MAPS App: AppAssistant");
    this.appController = appController;
	
	var countryCode = Mojo.Locale.getCurrentLocale().slice(-2).toLowerCase();
	// HACK for google: they need "uk" intead of "gb" that we set
	if (countryCode == "gb") {
		countryCode = "uk";
	}
	AppAssistant.countryCodeParam = "gl=" + countryCode;
	
	window.document.addEventListener(Mojo.Event.activate, this.onAppActivate.bind(this));
	window.document.addEventListener(Mojo.Event.deactivate, this.onAppDeactivate.bind(this));
	
	// subscribe for notifications from connection manager
	this._startConnectionWatch();
	
	// register for entering msm notifications
 	this.storageNotificationSession = new Mojo.Service.Request(
		'palm://com.palm.bus/signal',
		{
			method: 'addmatch',
			parameters:
			{
				"category" : "/storaged",
				"method" : "MSMProgress",
				"subscribe" : true
			},
			onSuccess: AppAssistant.prototype.storagedProgress,
			onComplete: AppAssistant.prototype.storagedProgress
		}
	);
	
	appController.enableManualSplashScreenMode();
}

function StageAssistant(stageController){
	Mojo.Log.info("Maps: StageAssistant %s", stageController);
	
	// we will be doing our own cross-fade
	stageController.useSceneTransitions(false);
	
	if (PalmSystem.version.indexOf("desktop") >= 0) {
		// call ourseves with internet connection update
		AppAssistant.prototype.internetConnectionUpdate(
			{isInternetConnectionAvailable: true, wifi: {state: "connected"}});
	}
		
}

AppAssistant.prototype.handleLaunch = function(appLaunchParams) {
	Mojo.Log.info("Maps App: handleLaunch Launch Params: %j", appLaunchParams);
	AppAssistant.url = AppAssistant.prototype.composeURL(appLaunchParams);
	Mojo.Log.info("Maps App: handleLaunch AppAssistant.url %s", AppAssistant.url);
	
	// focus the stage controller if we have one
	if (Mojo.Controller && Mojo.Controller.stageController) {
		Mojo.Log.info("MAPS App: handleLaunch stageController.activate");
		Mojo.Controller.stageController.activate();
	}
	
	// re-evaluate and load the URL only if webview widget is already setup
	if (AppAssistant.webViewWidget) {
		Mojo.Log.info("MAPS App: handleLaunch AppAssistant.webViewWidget is set");
				
		// change the URL only if we were passed some launch parameters
		var baseUrl = AppAssistant.prototype.getBaseUrl();
		if (AppAssistant.url && AppAssistant.url != baseUrl) {
			// we need to remeber to load this URL when internet becomes available
			Mojo.Log.info("Maps App: handleLaunch AppAssistant.deferedUrl: %s", AppAssistant.url);
			AppAssistant.deferedUrl = AppAssistant.url;
		}
	}
};

AppAssistant.prototype.cleanup = function() {
	Mojo.Log.info("Maps: AppAssistant cleanup");
	this._cleanupConnectionWatch();	
	this.storageNotificationSession.cancel();
};

AppAssistant.prototype.internetConnectionUpdate = function(response) {
	Mojo.Log.info("Maps App: internetConnectionUpdate %j", response);
	if (response) {
		var oldConnectionState = this.internetConnectionAvailable;
		this.internetConnectionAvailable = response.isInternetConnectionAvailable;
		var sceneStack = Mojo.Controller.stageController.getScenes();
		
		// if there is no internet connection prompt the user to turn it on
		// show no-wifi scene only if app have just been launched
		if (!this.internetConnectionAvailable) {
			if (!sceneStack || sceneStack.size() == 0) {
				Mojo.Log.info("Maps: internetConnectionUpdate network NOT available show no-wifi scene");
				Mojo.Controller.stageController.pushScene("no-wifi", response.wifi.state);
			}
			else {
				AppAssistant.prototype.showConnectionWidget(response.wifi.state);
			}
		}
		else {
			/*
			var curr = new Date();
			console.log("@@@@@@@@@@@@@@@@@@@ internetConnectionUpdate diff: " + (curr.getTime() - timer.getTime()));
			console.log("@@@@@@@@@@@@@@@@@@@ internetConnectionUpdate total: " + (curr.getTime() - total.getTime()));
			timer = new Date();
			*/
			
			// if internet is available we are certainly not in MSM
			AppAssistant.MSMmodeActive = false;
			
			// figure out if we need to remove no-wifi splash screen
			var sceneStack = Mojo.Controller.stageController.getScenes();
			if (sceneStack && sceneStack.size() == 1 && Mojo.Controller.stageController.topScene().sceneName == "no-wifi") {
				Mojo.Controller.stageController.swapScene("mapshell");
			}
			else if (!sceneStack || sceneStack.size() == 0) {
				Mojo.Controller.stageController.pushScene("mapshell");
			}
			
			// if connection switched from not available to available refresh the page
			if ((this.internetConnectionAvailable != oldConnectionState || AppAssistant.deferedUrl) 
				&& AppAssistant.webViewWidget ) 
			{
				if (AppAssistant.deferedUrl) {
					Mojo.Log.info("Maps: AppAssistant internetConnectionUpdate loading deffered URL %s", AppAssistant.deferedUrl);
					AppAssistant.webViewWidget.mojo.openURL(AppAssistant.url);
					AppAssistant.deferedUrl = null;
				}
				/* Don't reload the page, maps should be able to recover by itself
				 * reload missing tiles etc. Reloading here causes more problems than it solves:
				 * after the phone call, map will reload and lose all your current setup
				 * in low coverage case it will keep reloading and show blank map sometimes etc
				else {
					Mojo.Log.info("Maps: AppAssistant internetConnectionUpdate reloading page");
					AppAssistant.webViewWidget.mojo.reloadPage();
				}
				*/
			}
		}
	}	
};

AppAssistant.prototype.showConnectionWidget = function(wifiState) {
	// popup connection widget if wifi is disconnected and we are not in MSM
	if (wifiState == "disconnected" && !AppAssistant.MSMmodeActive) {
		Mojo.Log.info("Maps App: showConnectionWidget calling connection widget");
		// popup connection widget
		var params = {type: "data", onSuccess: 
			function(response) {
				if (response == "WiFi-UserCancelled") {
					Mojo.Log.info("Maps app: showConnectionWidget user canceled Wifi prompt.");
					// don't close the app, user might be looking at the map
					// window.close();
				}					
			}};
		ConnectionWidget.connect(params, Mojo.Controller.stageController);
	}
};

AppAssistant.prototype.storagedProgress = function(response) {	
	if (!response) {
		return;
	}
	Mojo.Log.info ("Maps: AppAssistant storagedProgress: %j", response);
	if (response.stage == 'attempting') {
		Mojo.Log.info ("Maps: AppAssistant storagedProgress: in MSM");
		AppAssistant.MSMmodeActive = true;
	}
};
		
// do this only once, when the first scene is pushed on stack
// called from the activate() method of the first scene that 
// got pushed when app was launched. Can be mapshell or no-wifi  
AppAssistant.prototype.doneLaunch = function() {
	Mojo.Log.info ("Maps: app-assistant doneLaunch");
	
	if (!AppAssistant.initialLaunchDone) {
		Mojo.Log.info ("AppAssistant.doneLaunch hide splash screen");
		Mojo.Controller.getAppController().hideSplashScreen();
		AppAssistant.initialLaunchDone = true;
	}
};

/*
* For general queries
q= address, lat&long etc
t= Map Type. The available options are "m" map, "k" satellite
z= Sets the zoom level. 
layer= Activates overlays. Current option is "t" traffic

* For driving directions:
daddr = destination address
saddr = start address

// passing location parameter from global search
"il=g,lat,lng,acc,age" (without the quotes) where:
il denotes implicit location (fyi)
g denotes "geolocation" (must always be included)
lat = latitude in degrees (float)
lng = longitude in degrees (float)
acc = accuracy in meters - optional (float)
age = age of fix in seconds - optional (int)
*/
AppAssistant.prototype.composeURL = function(launchParams) {
	var url;
		
	// if there are any launch params append them to the URL
	if (launchParams.target != undefined && launchParams.target != "") {
		Mojo.Log.info("Maps App: composeURL target url %s", launchParams.target);
		
		var foundIndex = launchParams.target.indexOf("mapto:");
		if (foundIndex >= 0) {
			url = AppAssistant.prototype.getBaseUrl() + 
				"daddr=" + launchParams.target.substr(foundIndex + "mapto:".length);
			
			Mojo.Log.info("Maps App: composeURL query is: %s", url);	
		}
		else {
			foundIndex = launchParams.target.indexOf("maploc:");
			if (foundIndex >= 0) {
				url = AppAssistant.prototype.getBaseUrl() +
					"q=" + launchParams.target.substr(foundIndex + "maploc:".length);
				Mojo.Log.info("Maps App: composeURL query is: %s", url);	
			}
			else {
				// use entire URL string
				url = launchParams.target;
				Mojo.Log.info("Maps App: composeURL query is: %s", url);	
			}
		}
	}
	else {		
		url = AppAssistant.prototype.getBaseUrl();
		
		if (launchParams.query != undefined) {
			url += "&q=" + launchParams.query;
		}
		if (launchParams.zoom != undefined) {
			url += "&z=" + launchParams.zoom;
		}
		if (launchParams.type != undefined) {
			url += "&t=" + launchParams.type;
		}
		if (launchParams.layer != undefined) {
			url += "&layer=" + launchParams.layer;
		}
		if (launchParams.saddr != undefined) {
			url += "&saddr=" + launchParams.saddr;
		}
		if (launchParams.daddr != undefined) {
			url += "&daddr=" + launchParams.daddr;
		}
			
		if (launchParams.location && launchParams.location.lat && launchParams.location.lng) 
		{	
			// append "il" parameter
			url += "&il=g," + launchParams.location.lat + "," + launchParams.location.lng;
				
			if (launchParams.location.acc) {
				url += "," + launchParams.location.acc; // add accuracy
			}
			if (launchParams.location.age) {
				url += "," + launchParams.location.age; // add age
			}	
		}
		else if (launchParams.location == "null") 
		{
			// use the last viewport location stored in a cookie
			var cookie = new Mojo.Model.Cookie("maps-lastviewport");
			var storedCookie = cookie.get();
			if (storedCookie) {
				Mojo.Log.info("Maps: composeURL: maps-lastviewport cookie exists");
				// append "il" parameter
				url += "&il=g," + storedCookie.lat + "," + storedCookie.lng;
				
				// add accuracy if present in the cookie
				if (storedCookie.acc) {
					url += "," + storedCookie.acc;
				}
			}
		}
	}
	
	Mojo.Log.info("Maps App: composeURL final URL is: %s", url);
	return url;
}

// return the URL with parameters that we always send
AppAssistant.prototype.getBaseUrl = function() {
	
	var baseUrl = AppAssistant.googleMapsURL; 
	if (baseUrl.indexOf("?") > 0)
		baseUrl += "&";
	else
		baseUrl += "?";
	
	baseUrl += AppAssistant.countryCodeParam + "&" + AppAssistant.urlClientParam + "#";
	return baseUrl;
};

AppAssistant.prototype.onAppActivate = function() {
	Mojo.Log.info("Maps App: onAppActivate");
	this._startConnectionWatch();
};
	
AppAssistant.prototype.onAppDeactivate = function() {
	Mojo.Log.info("Maps App: onAppDeactivate");
	this._cleanupConnectionWatch();
};
	 
AppAssistant.prototype._cleanupConnectionWatch = function() {
 	Mojo.Log.info("Maps App: _cleanupConnectionWatch");
	if (this.connectionInfoRequest) {
		this.connectionInfoRequest.cancel();
		this.connectionInfoRequest = null;
	}
	// close connection's widget stage if active
	ConnectionWidget.cancel();
};
	 
AppAssistant.prototype._startConnectionWatch = function() {
 	Mojo.Log.info("Maps App: _startConnectionWatch");
		// sign up for connection notifications
	if (!this.connectionInfoRequest) {
		Mojo.Log.info("Maps App: onAppActivate creating new connectionInfoRequest");
		this.connectionInfoRequest = new Mojo.Service.Request("palm://com.palm.connectionmanager", {
			method: 'getstatus',
			parameters: {
				'subscribe': true
			},
			onSuccess: this.internetConnectionUpdate.bind(this)
		}, true);
	}
};


