/* Copyright 2009 Palm, Inc.  All rights reserved. */

function AppAssistant(appController) {
	//TODO Check if lightweight stage is to be used
  this.appController = appController;
}
	
function setupSimulator() {
	Mojo.Log.info("---------------- setupSimulator() --------------------");
	clearTimeout(powerMethod);
	isDevice = false;
	isActivated = true;
	isCamped = true;
	Account.platformType = "CDMA";
	simStatus = "simready";
	attemptCount = 0;
	isConnected = true;
	dbVersion = -1;
	tutorialScript = "back-tutorial-main";
	cdmaType = 'omadm';
	FirstUseUtil.emergencyNumbers = ["911"];
	//simStatus = "simnotfound";
	//simStatus = "siminvalid";
	//simStatus = "pinrequired";
	//simStatus = "pukrequired";
	
	firstUseDepot = new Mojo.Depot(stateEngine, dbSetUpSuccess, dbSetupFailure);	 
	Mojo.Controller.stageController.pushScene("language");
	//saveCurrentState("done");
	//tokenMethod = setTimeout(checkTokenState, 500);
}

function setUpFirstUse() {
Mojo.Log.info("---------------- setupFirstUse() --------------------");

	setupSimulator();
	isDevice = true;
	return;

	this.firstUseDepot = new Mojo.Depot(stateEngine, dbSetUpSuccess, dbSetupFailure);	
	isInitialized = true;
	attemptCount = 0;
	dbVersion = -1;
	sessionStatus = 'none';
	
	FirstUseUtil.loadValues();
	RoamUtil.checkNetworkStatus();
	isConnected = false;
	// Subscribe to connection manager
	conStatusRequest = AppAssistant.accountService.isConManUp(readConManStatus, errorConManStatus);
}

function readConManStatus(response) {
	Mojo.Log.info("----------------- isConManUp?? -------------------------%o", $H(response));
	if (response.connected == true) {
		connectionRequest = AppAssistant.accountService.getConnectionStatus(readConnectionStatus, errorConnectionStatus);
	}	
}

function errorConManStatus (response){
	Mojo.Log.error("---------------- error isConManUp?? -----------------%o", $H(response));
	isConnected = false;
}

function readConnectionStatus(response) {
	Mojo.Log.info("---------------- connection manager status -----------------%o", $H(response));
	if(response && response.isInternetConnectionAvailable == true) {
		isConnected = true;
	} else {
		isConnected = false;
	}
}

function errorConnectionStatus (response){
	Mojo.Log.error("---------------- error connection manager status -----------------%o", $H(response));
	isConnected = false;
}

function dbSetUpSuccess() {
Mojo.Log.info("---------------- created depot () --------------------");
	Mojo.Log.info("created depot successfully!");
}

function dbSetupFailure() {
	Mojo.Log.error("Failed to create depot");
	//TODO How to handle this failure?
}

function StageAssistant(stageController) {
	Mojo.Log.info("------------Stage assistant called ---------");
	isDemoMode = false;
	try {
      	var launchParams = PalmSystem.launchParams.toJSON();
	  	Mojo.Log.info("App Launch Params -------------- %j", launchParams);
		if(launchParams && (launchParams.indexOf("demomode") > -1)) {
			isDemoMode = true;
		}
    } 
    catch (err) {
      	Mojo.Log.info(" No launch params %j", err);
    }
	this.stageController = stageController;	

	// Requesting the overide setting before pushing the first scens
	FirstUseUtil.getTutorialOverride();

	displayRequest = AppAssistant.accountService.turnOffScreenTransitions();
	FirstUseUtil.handlePowerKey();
}

function pushHome() {
	Mojo.Log.info("--------------- isDemoMode -----------%j", isDemoMode);
	if(isDemoMode && (isDemoMode === true)) {
		Mojo.Controller.stageController.pushScene(tutorialScript);
		setUpFirstUse();
		return;
	}
	Mojo.Controller.stageController.pushScene("home");
	Mojo.Log.info("-------------- Home is pushed ------------", PalmSystem.version);
	
	if (FirstUseUtil.isSimulator()) {
		powerMethod = setTimeout(setupSimulator, 2000);
		return;
	}
	isInitialized = false;
	//Make it sit here for 2 seconds - Check if we need to cancel it later
	powerMethod = setTimeout(isTelephonyReady, 2000);
	initMethod = setTimeout(isFirstUseInitialized, 3*60*1000);
	return;
}

function isFirstUseInitialized () {
	clearTimeout(initMethod);
	Mojo.Log.info("------------this.isInitialized ---------", isInitialized);
	if (isInitialized == false) {
		// Show error screen
		if(telephonyRequest != undefined) {
			telephonyRequest.cancel();
		}
		setPowerRequest = AppAssistant.accountService.setPower(checkPowerStatus, setPowerError);
	}
}

function checkPowerStatus(response) {
	Mojo.Log.info("------------Is telephony ready power status ---------%o", $H(response));	
	if(response.returnValue && response.returnValue == false) {
		Mojo.Controller.stageController.pushScene("error");	
	} else if (response.returnValue && response.returnValue == true) {
		isTelephonyReady();	
	} else {
		Mojo.Controller.stageController.pushScene("error");	
	}
}

function setPowerError(response) {
	Mojo.Controller.stageController.pushScene("error");	
}


function isTelephonyReady() {
	clearTimeout(powerMethod);
	telephonyRequest = AppAssistant.accountService.isTelephonyReady(checkTelephonyStatus, telephonyError);
}

function checkTelephonyStatus(response) {
	Mojo.Log.info("------------Is telephony ready ---------%o", $H(response));
	if(response.returnValue && response.returnValue == true) {
		Mojo.Log.info("------------Is power on? ---------%o", $H(response.extended));
		if (response.extended.power == true) {
			Mojo.Log.info("------------Yes, power is power on---------");
			moveOntoSystemServiceCheck();
		}	
	} else if(response.macroEventTelReady && response.macroEventTelReady.power == true) {
		//If we are subscribed to isTelephonyReady request, it gives two diff types of responses	
		moveOntoSystemServiceCheck();
	}
}

function moveOntoSystemServiceCheck () {
	isInitialized = true;
	clearTimeout(initMethod);
	systemServiceRequest = AppAssistant.accountService.isSystemServiceUp(checkSystemServiceStatus);
	telephonyRequest.cancel();
}

function checkSystemServiceStatus(response) {
	Mojo.Log.info("------------checkSystemServiceStatus--------- %o", $H(response));
	if (response.connected == true) {
		systemServiceRequest.cancel();
		setUpFirstUse();
		activateDevice();
	}	
}

function telephonyError(response) {
	Mojo.Log.error("------------Is telephony ready error ---------%o", $H(response));
	//TODO What to do in this case? Add a timeout logic
	if (!FirstUseUtil.isSimulator()) {
		activateDevice();
	}	
}

function checkDatabase() {
	Mojo.Log.info("---------------- checkDatabase() --------------------");
	firstUseDepot.simpleGet("currentState", readCurrentState, noCurrentState);
}

function checkTokenState() {
	Mojo.Log.info("---------------- checkTokenState() --------------------");
	tokenRequest = AppAssistant.accountService.checkTokenState(readTokenState, errorTokenState);	
}

function readTokenState(response) {
	
	if(response) {
		if(tokenRequest) {
			tokenRequest.cancel();
		}
		Mojo.Log.info("--------------readTokenState---------------- %o", $H(response));
		if(response.accountState && response.accountState === 'Invalid') {
			Mojo.Log.info("---------------Token is invalid--------------");
			Account.email = response.accountAlias;
			Account.isInvalidToken = true;
			Mojo.Controller.stageController.pushScene("invalid-token");
		} else if(response.accountState && (response.accountState === 'Corrupted' || response.accountState === 'TokenCorrupted')) {
			Mojo.Log.info("---------------Db is corrupted--------------", response.accountState);
			Account.dbErrorType = response.accountState;
			Mojo.Controller.stageController.pushScene("language");
		} else {
			PalmSystem.shutdown();
			return;
		}
	}
}

function errorTokenState(response) {
	if (response) {
		Mojo.Log.error("----------------- token error --------------%o", $H(response));
		if (response.errorCode && response.errorCode != "-1") {
			if(tokenRequest) {
				tokenRequest.cancel();
			}
			Mojo.Controller.stageController.pushScene("language");
		}
	}	
}

function saveCurrentState(screenName) {
 	Mojo.Log.info("Save current state: screen name = %s ",screenName, "; isActivated = %s",isActivated);
  	firstUseState.screenName = screenName;
	firstUseState.account = Account;
	firstUseState.isActivated = isActivated;
	firstUseDepot.simpleAdd("currentState", firstUseState, currentStateSuccess, currentStateFailure);	
 }
  
 function currentStateSuccess() {
  	Mojo.Log.info("first use current state saved successfully %s ", firstUseState.screenName);		
 }
  
 function currentStateFailure() {
  	Mojo.Log.error("first use state save failed");
 }
  
function readCurrentState(response) {
	Mojo.Log.info("---------------- read current state() --------------------");
	
	var recordSize = Object.values(response).size();
	Mojo.Log.info("recordSize ----------------------- %i ",recordSize);
	// Pop Home scene in all cases
	Mojo.Controller.stageController.popScene();
	if(recordSize == 0) {
		Mojo.Controller.stageController.pushScene("language");
	} else {
		var screenName = response.screenName;
		
		if(screenName == "done") {
			checkTokenState();
			return;
		}
		
		Account = response.account;	
		
		// NOV-60451: Don't overwrite the value given by telephony
		//isActivated = response.isActivated;	
		
		// reset the locale at the ui level on reboot
		if(Account.language != "" && Account.country != "") {
			Mojo.Locale.set(Account.language + '_' + Account.country);
		}
		
		if((screenName != "language") && (simStatus == "siminvalid")) {
			Mojo.Controller.stageController.pushScene("invalidsim");
			return;
		}
		Mojo.Controller.stageController.pushScene(screenName);
		// This is needed if user reboots the device and continues from a screen past Terms and Conditions
		if(isActivated == true) {
			FirstUseUtil.initValues();
		}
		
		//If user reboots the device during First Use after getting past language selection
		//with a different sim, we need to show appropriate scene 
		if(screenName != "language") {
			if(simStatus == "pinrequired") {
				FirstUseUtil.displayPin1Lock();
				return;
			} 
			else if(simStatus == "pukrequired") {
				FirstUseUtil.displayPuk1Lock();
				return;
			}
		}
		
	}
}

function noCurrentState (response) {
Mojo.Log.info("---------------- no curre nts tate() --------------------");
	Mojo.Controller.stageController.popScene();
	Mojo.Controller.stageController.pushScene("language");
}

function activateDevice () {
Mojo.Log.info("---------------- activate device() --------------------");
	if(isDevice == false) {
		isActivated = true;
		checkDatabase();
	}
	Mojo.Log.info("activate Device = ",  isActivated, Account.platformType);
	if ((isActivated == false) || (Account.platformType == "")) {
		this.platformRequest = AppAssistant.accountService.getPlatformType(checkIfActivationNeeded, platformQueryError);
	}					
}
	
function checkIfActivationNeeded (response) {
	Mojo.Log.info("---------- checkIfActivationNeeded() ---------%j", response);
	if(response.returnValue == true) {
		Account.platformType = response.extended.platformType;
		Mojo.Log.info("Platform type = ",Account.platformType);
		if (Account.platformType.toLowerCase() == 'gsm') {
			isActivated = true;
			initGSM();
			checkIfSIMPresent();
		}
		else if (Account.platformType.toLowerCase() == 'cdma') {
			Mojo.Log.info("getProvisioningStatus = %s ",Account.platformType);
			getCDMAType();
		}
		else {
			platformQueryError(response);
		}							
	} else {
		platformQueryError(response);
	}
}

function initGSM () {
	AppAssistant.gsmService = new GsmService();
}

function isCDMAAlreadyActivated (response) {
	Mojo.Log.info("isCDMAAlreadyActivated = %o ", $H(response));
	if(this.statusRequest) {
		Mojo.Log.info("------------- Cancel provisioning status request ------------");
		this.statusRequest.cancel();
		delete this.statusRequest;
	}
	if(response.returnValue == true) {
		var status = response.extended;
		if(status.data == true && status.voice == true) {
			isActivated = true;
			simStatus="notApplicable";
			checkDatabase();
		}
		else {
			sessionStatus = 'none';
			previousSessionStatus = 'none';
			//Comment this if we do not want to show Network Unavailable error for provisioning 
			//getNetworkStatus();
			//getCDMAType();
			if(cdmaType === "omadm") {
				provisionCDMADevice();
			} else {
				checkDatabase();
			}
		}
	}
}

function getCDMAType() {
	this.cdmaTypeRequest = AppAssistant.accountService.getCDMAType(readCDMAType, errorCDMAType);
}

function readCDMAType(response) {
	Mojo.Log.info("------------ CDMA type ------------%j", response);
	if(response.otaspActivation) {
		cdmaType = "otasp";
		activationNumber = response.otaspActivation;
		prlUpdateNumber = response.otaspPRLUpdate;
		prlUpdateDone = false;
		simStatus="notApplicable";
	} else {
		cdmaType = "omadm";
		setRoamMode('homeonly');
	}
	this.statusRequest = AppAssistant.accountService.getProvisioningStatus(isCDMAAlreadyActivated, provisionStatusError);
}

function errorCDMAType(response) {
	Mojo.Log.error("------------ Error CDMA type ------------%j", response);
	//TODO Remove following line when all values are configured
	provisionCDMADevice();
}

function setRoamMode(roamMode) {
	if (!AppAssistant.omadmService) {
		AppAssistant.omadmService = new OmadmService();
	}	
	this.roamModeRequest = AppAssistant.omadmService.setRoamMode(roamMode, readRoamModeStatus, errorRoamModeStatus);
}

function readRoamModeStatus(response) {
	if(this.roamModeRequest) {
		this.roamModeRequest.cancel();
	}
}

function errorRoamModeStatus(response) {
	Mojo.Log.error("--------- Could not set roam mode -----------");
}

function getNetworkStatus () {
	Mojo.Log.info("--------------------------- Get network status ---------------------------");
	isCamped = false;
	this.networkStatusRequest = AppAssistant.accountService.getNetworkStatus(readNetworkStatus, errorNetworkStatus);
}

function readNetworkStatus(response) {
	Mojo.Log.info("--------------------------- readNetworkStatus ---------------------------%o", $H(response.extended));
	if(response.extended && response.extended.registration == "home") {
		isCamped = true;
		provisionCDMADevice();
		if(this.networkStatusRequest) {
			this.networkStatusRequest.cancel();
		}
	} else {
		checkDatabase();
	}
}

function errorNetworkStatus (response) {
	Mojo.Log.error("--------------------------- errorNetworkStatus ---------------------------%o", $H(response));
	// Show error
	isCamped=false;	
	checkDatabase();
}

function provisionStatusError (response) {
	Mojo.Log.info("Could not get provisioning status: %o", $H(response));
}

function provisionCDMADevice () {
	Mojo.Log.info("---------------- provision cdma device() --------------------");
	this.sessionStatusRequest = AppAssistant.accountService.getSessionStatus(
						ProvisionUtil.readSessionStatus.bind(this), 
						ProvisionUtil.provisionError.bind(this));
	simStatus="notApplicable";
	checkDatabase();
}
	
function platformQueryError (response) {
	Mojo.Log.error("Telephony error === %j ", response);
}

function checkIfSIMPresent() {
Mojo.Log.info("---------------- checkIfSIMPresent() --------------------");
	this.simStatusRequest = AppAssistant.accountService.getSIMStatus(
			readSIMStatus.bind(this), 
			simError.bind(this), false);	
}
	
function readSIMStatus(response) {
	Mojo.Log.info("SIM Status = %o", $H(response));
	if(response.returnValue == true) {
		if (response.extended.state != undefined) {
			simStatus = response.extended.state.toLowerCase();
			Mojo.Log.info("SIM Status = %s ", simStatus);
			// if (simStatus == "simnotfound") {
			// 	Mojo.Controller.stageController.pushScene("nosim");
			// 	return;
			// }
			checkDatabase();	
		} else {
			simError(response);
		}		
	}
}

function simError(response) {
	Mojo.Log.error("SIM error %o", $H(response));
}

AppAssistant.accountService	= new NovaAccountService();
AppAssistant.appCatalogService = new AppCatalogService();
AppAssistant.locationService = new LocationService();
AppAssistant.notifyService = new RestoreCompleteService();
AppAssistant.otaspService = new OtaspService();
AppAssistant.accountsLoginService = new AccountsLoginService();
