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

var RestoreAssistant = Class.create({
	
	spinner: 'activity-spinner',
	
	spinning: false,
	
	spinnerAttrs: {
		spinnerSize: Mojo.Widget.spinnerLarge
	},
	
	initialize: function(deviceId, action, packageURLArray, accountToken){
		Mojo.Log.info("init restore asst");
		Account.action = "restore";
		FirstUseUtil.addDashboardSmall($('target'));
		saveCurrentState("wait");
		this.initValues (deviceId, action, packageURLArray, accountToken);
	},
		
	initValues: function (deviceId, action, packageURLArray, accountToken) {
		this.action = action;
		this.deviceId = deviceId;
		this.packageURLArray = [];
		if(Object.isString(packageURLArray) == true) {
			this.packageURLArray[0] = packageURLArray;
		} else if (Object.isArray(packageURLArray) == true) {
			this.packageURLArray = packageURLArray;
		} 
		
		this.accountToken = accountToken;
		if(this.packageURLArray!=undefined && this.packageURLArray.size() > 0) {
			this.chunkSize = 300;
			this.partitionSize = 1/3;
		} else {
			this.chunkSize = 200; 
			this.partitionSize = 1/2;
		}
		
		this.initProgress = false;
		Mojo.Log.info("*********************** chunk size ********************* %i", this.chunkSize);
		$('backupErrorButton').observe(Mojo.Event.tap, this.goToLogin.bindAsEventListener(this));
	},
	
	hideAllDivs: function() {
		Mojo.Log.info("--------------- Hide all divs -------------------");
		$('account-restore').hide();
		$('connectionDiv').hide();
		$('connection-error').hide();
		$('restoreDiv').hide();
		$('progressBar').hide();
		$('connectionErrorDiv').hide();
		$('backup-error').hide();
		Mojo.Log.info("--------------- End Hide all divs -------------------");
	},
	
	setup: function() {
		Mojo.Log.info("--------------- setup -------------------");
		$('target').addEventListener(Mojo.Event.tap, FirstUseUtil.tapHandler.bindAsEventListener(this));
				
		// Listen to ## key presses
		this.controller.listen(this.controller.sceneElement, Mojo.Event.keydown, FirstUseUtil.handleKeyPressEvent.bind(this));
Mojo.Log.info("--------------- doAction -------------------");
		this.doAction();
		this.setupProgressBar();
		this.controller.setupWidget(this.spinner, this.spinnerAttrs, {});
	},
	
	handleCommand: function(event) {
		if (event.type == Mojo.Event.back) {
			Mojo.Log.info("------- Blocking back ----------");
			event.preventDefault();
			event.stopPropagation();
		}	
	},	
	
	goToLogin: function () {
		if(Account.isInvalidToken == true) {
			Account.action="invalid-token";
			Mojo.Controller.stageController.swapScene('invalid-token');
			return;
		}
		Account.action="login";
		Mojo.Controller.stageController.swapScene('login');
	},
	
	doAction: function() {
		if(this.action == "backupError") {
			$('backup-error').show();
			return;
		}	
		//setup a window timeout with an interval
		this.progress = 0;
		
		$('account-restore').show();
		$('restoreDiv').show();
		$('progressBar').show();
		
		if(RoamUtil.enableRoaming() === true) {
			Account.action = "restore";
			RoamGuardDialog.turnOffRoamguard({
				"sceneController": this.controller,
				"method": this.doNextAction.bind(this)
			});
			return;
		}
		
		Mojo.Log.info("------------------------ this.action ------------------------------", this.action);
		this.doNextAction();	
	},
	
	doNextAction: function () {
		if (this.action == "migrate") {
			Mojo.Log.info("------------ START - Migrate Data ---------------------", new Date().getTime( ));
			this.migrateRequest = AppAssistant.accountService.migrateData(this.deviceId, this.restoreData.bind(this), this.restoreDataFailure.bind(this), this.controller);
		} else if (this.action == "restore") {
			Mojo.Log.info("------------ START - Restore Data ---------------------", new Date().getTime( ));
			this.restoreRequest = AppAssistant.accountService.restoreData(this.restoreData.bind(this), this.restoreDataFailure.bind(this), this.controller);
		} else {
			this.installApps();
		}
	},
	
	setupProgressBar: function() {
		this.attr = {
			cancellable: true,
			modelProperty: 'progress'
		};
		this.model = {
			progress: 0
		};
		this.controller.setupWidget('progressBar', this.attr, this.model);
	},
		
	reset: function() {
		$('progressBar').mojo.reset();
	},
	
	updateProgress: function() {
		this.model.progress = this.progress;
		Mojo.Log.info("Progress to show ----------------------------------- %i", this.progress);
		this.controller.modelChanged(this.model);
	},
	
	cleanup: function() {
		
	},
		
	showProgressForDataImport: function() {
		if(this.status == 'Complete') {
			return;
		}
		Mojo.Log.info("What is the percent here during data import? %i", this.progress);
		this.updateProgress();
	},
	
	restoreData: function(response) {
				
		if(response.STATUS == 'Suspend') {
			return;
		}
		
		Mojo.Log.info("------------------------ Migrate data status ---------------------", this.status);
		if (this.spinning == true || this.status == "Abort" || this.status == "Failed") {
			this.stopSpinner();
			$('account-restore').show();
			$('restoreDiv').show();
			$('progressBar').show();
			this.controller.showWidgetContainer($('progressBar'));
		}
		
		this.status = response.STATUS;
									
		switch (this.status) {
		
			case 'migrationComplete':
				break;
		
			case 'DataImportInProgress':
				Mojo.Log.info("What is the percent here in DataImportInProgress? %i", response.percent);
				this.progress = this.partitionSize + (response.percent / this.chunkSize);
				this.updateProgress();
				break;
				
			case 'InProgress':
				this.progress = response.percent / this.chunkSize;
				Mojo.Log.info("What is the percent here InProgress? %i", response.percent);
				this.updateProgress();
				break;
				
			case 'Complete':
				// No apps to install
				Mojo.Log.info("this.packageURLArray.size()? %i", this.packageURLArray.size());
				if (this.packageURLArray.size() == 0) {
					this.progress = 1;
					this.updateProgress();
					this.progressReseter = window.setInterval(this.showRestoreComplete.bind(this), 500);
				}
				else {
					this.installApps();
				}
				break;
				
			case 'Failed':
				this.reset();	
				$('account-restore').hide();
				
				//TODO Check with Jiji if he retries automatically in this case
				if (response.error && (response.error == "400" || response.error == "408") && (isConnected == false)) {
					Mojo.Log.info("----------------------- Get connection status to resume automatically --------------------");
					$('connectionErrorDiv').show();
					this.resumeRestore = false;
					this.statusRequest = AppAssistant.accountService.getConnectionStatusForScene(this.continueRestore.bind(this), 
							this.errorConnectionStatus.bind(this), this.controller);
				}
				else {
					$('backup-error').show();
				}	
				break;
								
			case 'Abort':
				$('restoreDiv').hide();
				$('progressBar').hide();
				$('connectionDiv').show();
				$('connection-error').show();
				this.startSpinner();
				// Time out after 2 minutes
				this.timeOutMethod = setTimeout(this.timeOutSpinner.bind(this), 2*60*1000);
				break;
				
		}
		
	},
	
	getDevices: function (){
		if(RoamUtil.enableRoaming() === true) {
			Account.action = "restore";
			RoamGuardDialog.turnOffRoamguard({
				"sceneController": this.controller,
				"method": this.isDataAvailable.bind(this)
			});
			return;
		}
		this.isDataAvailable();
	},
	
	isDataAvailable: function () {
		AppAssistant.accountService.isDataAvailable(this.checkIfDataAvailable.bind(this), this.getDevicesFailure.bind(this), this.controller);		
	},
	
	checkIfDataAvailable: function (response) {
		
		Mojo.Log.info("------------ END - Check if data is available to restore ---------------------", ((new Date().getTime()) - this.startDateCheck));
		
		Mojo.Log.info("response from back up server ------ %o", $H(response));
		
		var devices = response.allDevices;
		var _deviceId = "";
		//TODO What to do if there is more than one device
		if(Object.isArray(devices) == true) {
			devices.each(function (item) {
				Mojo.Log.info("item ======="+item);
				if(item.length > 0) {
					var tmp = item;
					var devId = tmp.substring(0, tmp.indexOf("-"));
					var dataSize =  tmp.substring(tmp.indexOf("-")+1, tmp.length);
					Mojo.Log.info("data size == "+dataSize);
					if(dataSize > 0) {
						_deviceId = devId;
					}
				}
			});
		} else {
			//deviceId = devices;
			var tmp = devices;
			Mojo.Log.info("Devices that have backed up data: ------ ", tmp);
			
			if (tmp) {
			
				var devId = tmp.substring(0, tmp.indexOf("-"));
				var dataSize = tmp.substring(tmp.indexOf("-") + 1, tmp.length);
				Mojo.Log.info("data size == " + dataSize);
				if (dataSize > 0) {
					_deviceId = devId;
				}
				else {
					Mojo.Log.info("no data available to restore");
				}
			}	
		}
		Mojo.Log.info("deviceId ====== %s",_deviceId);
		
		if(_deviceId != "" && Account.deviceId == _deviceId) {
			this.action = "restore";
		} else {
			this.action = "migrate";
		}
		this.doAction();	
	},
	
	getDevicesFailure: function (response) {
		Mojo.Log.error("Why did getDevices fail? %j", response);
		this.hideAllDivs();
		$('backup-error').show();
	},
	
	continueRestore: function(response) {
		Mojo.Log.info("-------------------resumeRestore -----------------------%o ", $H(response));
		if(response && response.isInternetConnectionAvailable == true) {
			if(this.statusRequest) {
				this.statusRequest.cancel();
			}
			if(this.resumeRestore == false) {
				this.resumeRestore = true;
				// We need to continue restore
				this.getDevices();
			}
		}
	},
	
	errorConnectionStatus: function (response) {
		Mojo.Log.error("-------------------errorConnectionStatus -----------------------%o ", $H(response));
		if(this.statusRequest) {
			this.statusRequest.cancel();
		}
		this.hideAllDivs();
		$('backup-error').show();
	},
	
	installApps: function() {
		Mojo.Log.info("OnSuccessCallback.getInstalledAppsList OutGetUserInstalledApps.packageURLs length", this.packageURLArray.size());
		
		this.appsCount = this.packageURLArray.size();
		this.appArray = this.packageURLArray;
		
		Mojo.Log.info("OnSuccessCallback.getInstalledAppsList count= %i", this.appsCount, "appArray=%o ", $H(this.appArray));
		if(this.appsCount > 0) {
			this.installAllApps();
		} else {
			this.progressReseter = window.setInterval(this.showRestoreComplete.bind(this), 500);
		}
	},	
 	
	restoreDataFailure: function(response) {
		Mojo.Log.error("what is the failure? %o", $H(response));
		this.hideAllDivs();
		this.reset();
		$('backup-error').show();
	},
	
	installAllApps: function () {
		Mojo.Log.info("installAllApp appsCount= %i", this.appsCount, "this.appArray", this.appArray);
		// Skipping roam check here
		if (this.appsCount > 0) {
			this.currentAppIndex = 0;
			this.installAppRequest = AppAssistant.appCatalogService.installApp(this.appArray[this.currentAppIndex], this.accountToken, 
						Account.deviceId, this.installAppResponse.bind(this));	
		}
	},
	
	installAppResponse: function(response) {
		Mojo.Log.info("installAppResponse= %j", response);
		var fProceed = false;
		if (response.returnValue === true || response.errorCode) {
			Mojo.Log.info("Installing %s", this.appArray[this.currentAppIndex], ", response=%j", response);
			fProceed = true;
			if (this.action == "installApps") {
				this.progress = this.progress + (1 / this.appsCount);
			}
			else {
				this.progress = this.progress + (0.33 / this.appsCount);
			}	
			this.updateProgress();
		} 

		if (fProceed == true) {
			//TODO: SHOW PROGRESS CALL HERE TO SHOW ONE FILE IS COMPLETED
			this.currentAppIndex = this.currentAppIndex + 1;
			if (this.currentAppIndex < this.appsCount) {
				this.installAppRequest = AppAssistant.appCatalogService.installApp(this.appArray[this.currentAppIndex], this.accountToken, 
											Account.deviceId, this.installAppResponse.bind(this));
			}
			else {
				Mojo.Log.info("onSuccessCallback.installApp DONE - looped thru All Apps");
				this.progress = 1;
				this.updateProgress();
				this.progressReseter = window.setInterval(this.showRestoreComplete.bind(this), 500);	
			}
		}
	},
	
	showRestoreComplete: function () {
		if(this.progressReseter != undefined) {
			clearTimeout(this.progressReseter);
		}
		this.reset();
		this.getAccounts();
	},
	
	getAccounts: function () {
		this.accountsRequest = AppAssistant.accountsLoginService.listAccountsByCredentials(
					this.readAccounts.bind(this), this.errorAccounts.bind(this), this.controller);
	},
	
	readAccounts: function (response) {
		if(response.count && response.count > 0) {
			Mojo.Controller.stageController.popScenesTo();
			Mojo.Controller.stageController.swapScene('accounts-login', response);
		} else {
			Mojo.Controller.stageController.swapScene('restorecomplete');
		}
	},
		
	errorAccounts: function (response) {
		Mojo.Log.error("-------Error in getting list of accounts to login ------------%j", response);
		Mojo.Controller.stageController.swapScene('restorecomplete');
	},		
	
	startSpinner: function () {
		this.spinning = true;
		$(this.spinner).mojo.start();
	},	
	
	stopSpinner: function () {
		Mojo.Log.info("----------------------- stop spinner --------------------------------");
		//TODO Optimize this
		this.hideAllDivs();
		if (this.spinning == true) {
			$(this.spinner).mojo.stop();
			this.spinning = false;
		}
	},
	
	timeOutSpinner: function() {
		clearTimeout(this.timeOutMethod);
		Mojo.Log.info("---------------------- Timeout Spinner --------------------------------", this.status);
		if (this.status == "Abort") {
			this.stopSpinner();
			
			if (isConnected == false) {
				$('connectionErrorDiv').show();
			}
			else {
				$('backup-error').show();
			}
		}		
	},
	
	deactivate: function() {
		clearTimeout(this.timeOutMethod);
		this.stopSpinner();
	}
	
});	
