var logServiceName   = null; // need to make sure service exists
var doingLogClear    = false; // used for clear to prevent issues caused by double-tap on buttons 

var isSimulator      = false;

// constants
//var filenamePattern = /[^a-zA-Z0-9_#-]/;
var NEW_SERVICE_NAME = "palm://com.palm.logctld";
var LOGCTLD_NOT_FOUND = $L("The \"logctld\" service wasn't found!<br><br>Please install and start-up this service.");
var DEVCOM_SERVICE_NAME = 'palm://com.palm.connectionmanager';


function MainAssistant() {
	/* this is the creator function for your scene assistant object. It will be passed all the 
	   additional parameters (after the scene name) that were passed to pushScene. The reference
	   to the scene controller (this.controller) has not be established yet, so any initialization
	   that needs the scene controller should be done in the setup function below. */
}

MainAssistant.prototype.setup = function() {
		//progress spinner
    this.spinnerAttrs = {
        property: 'spinningP'
    };
    
    this.spinnerModel = {
        spinningP: false
    };

	if (isSimulator == true) {logServiceName = NEW_SERVICE_NAME;}
   	this.controller.setupWidget('activity-spinner', this.spinnerAttrs, this.spinnerModel);
	
	this._ExitApp = this.exitApp.bindAsEventListener(this);
	
	this.mainMenuModel = {
		items: [
            {label: $L('Set GPS Fix Point...'), command: 'gpsFix'},
            {label: $L('Delete All Log Profiles...'), command: 'profilesDeleteAll'},
            {label: $L('Help...'), command: 'help'},
            {label: $L('Exit'), command: 'exit'}
		],
	};
	this.controller.setupWidget(Mojo.Menu.appMenu, {omitDefaultItems: true}, this.mainMenuModel);

	this.findService();
	
}

MainAssistant.prototype.setupButtonHandlers = function(){
	//Set up button handlers
	$('log_quick_button').observe(Mojo.Event.tap, this.quickLogFile.bindAsEventListener(this));
	$('log_create_button').observe(Mojo.Event.tap, this.createLogFile.bindAsEventListener(this));
	$('log_clear_button').observe(Mojo.Event.tap, this.clearLogs.bindAsEventListener(this));
	$('log_level_button').observe(Mojo.Event.tap, this.changeLogLevel.bindAsEventListener(this));
	if (PalmSystem.isMinimal === true) {
		$('exit_button').style.display = "block";
	}
	$('exit_button').observe(Mojo.Event.tap, this._ExitApp);
}

MainAssistant.prototype.infoDialog = function (text) {
	this.controller.showAlertDialog({
		onChoose: function(value){
		},
		title: $L("Information"),
		message: text,
		allowHTMLMessage: true,
		choices: [{label: $L('OK'),	value: 'ok', type: 'dismiss'}]
	});
}

////////////////////////////////////////////////////////////////////////
//   Handle command method, which currently just services the main menu
////////////////////////////////////////////////////////////////////////

MainAssistant.prototype.handleCommand = function(event) {
	var that = this;

	if (event.type == Mojo.Event.command) {
		if (event.command == 'gpsFix') {
			Mojo.Log.info("handleCommand(): gpsFix");
			this.setGpsFixPoint ();
		} else if (event.command == 'help') {
			Mojo.Log.info("handleCommand(): help");
			this.infoDialog("This application is used to collect logging information from Palm's software running on a webOS device into a single file that can be emailed to Palm's developers to analyze the reason for an issue.");
		} else if (event.command == 'exit') {
			Mojo.Log.info("handleCommand(): exit");
			this.exitApplication ();
		} else if (event.command == 'profilesDeleteAll') {
			Mojo.Log.info("handleCommand(): profilesDeleteAll");
			this.controller.showAlertDialog({
				title: $L("Confirmation"),
				message: $L("<b>Do you want to delete all logging profiles?</b> Including the current \"base profile\"?<br><br>This can't be undone, but default profiles will be recreated when you tap \"Change Logging Levels\"."),
				allowHTMLMessage: true,
				choices: [{
					label: $L('OK'),
					value: 'ok',
					type: 'affirmative'
				}, {
					label: $L('Cancel'),
					value: 'cancel',
					type: 'negative'
				}],
				onChoose: function(value){
					if (value == 'ok') {
						profileStore.deleteAllProfiles(function(){
							that.infoDialog("All saved profiles deleted!");
						}, function(result){ // onfailure
							that.infoDialog("Error deleting profiles: " +
							result.errorText);
						});
					}
				}
			});
		} else { 
			Mojo.Log.info("handleCommand():  Command [" + event.command +  "] ignored!");
		}
	}
}

MainAssistant.prototype.exitApp = function () {
	this.controller.window.close();
}

MainAssistant.prototype.exitApplication = function(){
	Mojo.Log.info ("exitApplication():");
	try {
		$('progress_label').innerHTML = $L("Exiting application...");
		this.spinOn();
		var findServiceRequest = this.controller.serviceRequest("luna://com.palm.applicationManager", {
			method: 'running',
			parameters: {},
			onSuccess: function(result){
				this.controller.cancelServiceRequest(findServiceRequest);
				var pid = null;
				if (result.running) {
					for (var i = 0 ; i < result.running.length && pid == null ; i++) {
						if (result.running[i].id && result.running[i].id == "com.palm.app.collectlogs") { // found
							pid = result.running[i].processid;
						}
					}
				}
				if (pid == null) {
					Mojo.Log.info ("exitApplication(): Couldn't find process: " +  Object.toJSON(result));
					this.showDialogBox(null, "Sorry, couldn't find CollectLogs in list of running applications!");
					this.spinOff();
					$('progress_label').innerHTML = "";
				} else { // issue close
					Mojo.Log.info ("exitApplication(): process found with pid: " + pid);
					this.controller.serviceRequest("luna://com.palm.applicationManager", {
						method: 'close',
						parameters: {processId:pid},
						onSuccess: function(response){
							this.spinOff();
							$('progress_label').innerHTML = "";
							Mojo.Log.info ("exitApplication(): Success! ");
						}.bind(this),
						onFailure: function(response) {
							this.spinOff();
							$('progress_label').innerHTML = "";
							Mojo.Log.error ("exitApplication(): Couldn't force app exit: " + Object.toJSON(response));
							this.showDialogBox($L('Error'), "Attempt to force exit of application failed, sorry");
						}.bind(this),
					});
				}
			}.bind(this),
			onFailure: function(result){
				this.controller.cancelServiceRequest(findServiceRequest);
				this.spinOff();
				$('progress_label').innerHTML = "";
				Mojo.Log.error ("exitApplication(): Couldn't get list of processes: " + Object.toJSON(result));
				this.showDialogBox($L('Error'), "Attempt to exit application failed");
			}.bind(this)
			
		});
	} catch (e) {
		Mojo.Log.error ("exitApplication(): e:" + e);
		this.spinOff();
		$('progress_label').innerHTML = "";
		this.showDialogBox($L('Error'), "Attempt to exit application failed<br><br>" + e);
	}
}

MainAssistant.prototype.findService = function(){
	// used to initially setup service
	var that = this;
	if (null != logServiceName) { // already setup
		this.setupButtonHandlers();
		Mojo.Log.info("findService():  About to call profileStore.setup()");
		profileStore.setup();
		Mojo.Log.info("findService():  Completed call to profileStore.setup()");
		return;
	}
	$('progress_label').innerHTML = $L("Checking for service...");
	this.spinOn();
	var findServiceRequest = this.controller.serviceRequest(NEW_SERVICE_NAME + "/private", {
		method: 'ping',
		parameters: {
		},
		onSuccess: function (result) {
			that.controller.cancelServiceRequest(findServiceRequest);
			that.spinOff();
			if (result.returnValue && result.returnValue === "true") 
				logServiceName = NEW_SERVICE_NAME; // found!
			$('progress_label').innerHTML = "";
			that.setupButtonHandlers();
			profileStore.setup();
		},
		onFailure: function(result) {
			that.controller.cancelServiceRequest(findServiceRequest);
			that.spinOff();
			console.log("failed");
			$('progress_label').innerHTML = "";
			that.setupButtonHandlers();
			that.showDialogBox($L('Error'), LOGCTLD_NOT_FOUND);
		}

	});
	
}

MainAssistant.prototype.isSuccess = function(result) {
	if (!result) return "false";
	return (result.success ? result.success	: (result.returnValue ? result.returnValue: "false"));
}

MainAssistant.prototype.clearLogs = function(event){
	var that = this;
	if (doingLogCreation == true) return;
	this.controller.showAlertDialog({
		title: $L("Are you sure?"),
		message: $L("<b>Do you want to delete all logs on the device?</b><br><br>This can't be undone."),
		allowHTMLMessage: true,
		choices: [{
			label: $L('OK'),
			value: 'ok',
			type: 'affirmative'
		},
		{
			label: $L('Cancel'),
			value: 'cancel',
			type: 'negative'
		}],
		onChoose: function(value) {
			if (value === 'ok') {
				doingLogClear = true;
				$('progress_label').update($L("Clearing logs ..."));
				var saveServiceRequest = that.controller.serviceRequest(logServiceName, {
					method: 'clearall',
					onSuccess: function(value){
						that.controller.cancelServiceRequest(saveServiceRequest);
						$('progress_label').innerHTML = "";
						that.spinOff();
						that.handleClearLogsOK(value);
					},
					onFailure: function(value){
						that.controller.cancelServiceRequest(saveServiceRequest);
						$('progress_label').innerHTML = "";
						that.spinOff();
						that.handleClearLogsError(value);
					}
				});
				this.spinOn();
			}
		}
	});	

}

MainAssistant.prototype.handleClearLogsOK = function(result)
{
	var value;
	doingLogClear = false;
	if (this.isSuccess(result) === "true") {
		//LogAssistant.clearLastLogName(); 
		//$('log_email_button').style.visibility = 'hidden';
		this.controller.showAlertDialog({
			onChoose: function(value){
			},
			title: $L("Success"),
			message: $L("Cleared logs"),
			allowHTMLMessage: true,
			choices: [{
				label: $L('OK'),
				value: 'ok',
				type: 'dismiss'
			}]
		});
	}
	else {
		this.handleClearLogsError(result);
	}
}

MainAssistant.prototype.handleClearLogsError = function(result)
{
	doingLogCreation = false;
	this.controller.showAlertDialog({
		onChoose: function(value){
		},
		title: $L("Failure"),
		message: $L("<b>Failed to clear the logs</b><br><br>") + (!result.errorText ? "" : result.errorText),
		allowHTMLMessage: true,
		choices: [{
			label: $L('OK'),
			value: 'ok',
			type: 'color'
		}]
	});
}


MainAssistant.prototype.spinOn = function(){
	Mojo.Log.info ("spinOn(): ");
    this.spinnerModel.spinningP = true;
    this.controller.modelChanged(this.spinnerModel);
}

MainAssistant.prototype.spinOff = function(){
	Mojo.Log.info ("spinOff(): ");
     this.spinnerModel.spinningP = false;
    this.controller.modelChanged(this.spinnerModel);
}

MainAssistant.prototype.changeLogLevel = function(event)
{
	console.log("about to display log levels form");
	if (isSimulator == true) {
		Mojo.Controller.stageController.pushScene('level');
	} else {
		var that = this;
		$('progress_label').innerHTML = $L("Checking for service...");
		this.spinOn();
		var findServiceRequest = this.controller.serviceRequest(NEW_SERVICE_NAME + "/private", {
			method: 'ping',
			parameters: {},
			onSuccess: function(result){
				that.controller.cancelServiceRequest(findServiceRequest);
				that.spinOff();
				$('progress_label').innerHTML = "";
				Mojo.Controller.stageController.pushScene('level');
			},
			onFailure: function(result){
				that.controller.cancelServiceRequest(findServiceRequest);
				that.spinOff();
				console.log("failed");
				$('progress_label').innerHTML = "";
				that.showDialogBox($L('Error'), LOGCTLD_NOT_FOUND);
			}
		});
	}

}

MainAssistant.prototype.setGpsFixPoint = function(event)
{
	console.log("about to display GPS Fix form");
	Mojo.Controller.stageController.pushScene('gpsfix');
}

MainAssistant.prototype.createLogFile = function(event){
	console.log("about to display log form");
	if (isSimulator == true) {
		Mojo.Controller.stageController.pushScene('log', null);
	}
	else {
		var that = this;
		$('progress_label').innerHTML = $L("Checking for service...");
		this.spinOn();
		var findServiceRequest = this.controller.serviceRequest(NEW_SERVICE_NAME + "/private", {
			method: 'ping',
			parameters: {},
			onSuccess: function(result){
				that.controller.cancelServiceRequest(findServiceRequest);
				that.spinOff();
				$('progress_label').innerHTML = "";
				Mojo.Controller.stageController.pushScene('log', null);
			},
			onFailure: function(result){
				that.controller.cancelServiceRequest(findServiceRequest);
				that.spinOff();
				console.log("failed");
				$('progress_label').innerHTML = "";
				that.showDialogBox($L('Error'), LOGCTLD_NOT_FOUND);
			}
		});
	}
	
}

MainAssistant.prototype.quickLogFile = function(event)
{
	console.log("about to display log form");
	if (isSimulator == true) {
		Mojo.Controller.stageController.pushScene('log', 'quick');
	} else {
		var that = this;
		$('progress_label').innerHTML = $L("Checking for service...");
		this.spinOn();
		var findServiceRequest = this.controller.serviceRequest(NEW_SERVICE_NAME + "/private", {
			method: 'ping',
			parameters: {},
			onSuccess: function(result){
				that.controller.cancelServiceRequest(findServiceRequest);
				that.spinOff();
				$('progress_label').innerHTML = "";
				Mojo.Controller.stageController.pushScene('log', 'quick');
			},
			onFailure: function(result){
				that.controller.cancelServiceRequest(findServiceRequest);
				that.spinOff();
				console.log("failed");
				$('progress_label').innerHTML = "";
				that.showDialogBox($L('Error'), LOGCTLD_NOT_FOUND);
			}
		});
	}

}


MainAssistant.prototype.notYetImplemented = function(desc){
	this.showDialogBox ($L("Not Yet Implemented"), (!desc ? ' ' : '\"' + desc + '\"'))
}

MainAssistant.prototype.showDialogBox = function (title, message) {
	this.controller.showAlertDialog({
		onChoose: function(value){
		},
		title: (title && title.length > 0 ? title : $L("Information")),
		message: (message ? message : ''),
		allowHTMLMessage: true,
		choices: [{label: $L('OK'),	value: 'ok', type: 'dismiss'}]
	});
	
}

MainAssistant.prototype.activate = function(event) {
	/* put in event handlers here that should only be in effect when this scene is active. For
	   example, key handlers that are observing the document */
}


MainAssistant.prototype.deactivate = function(event) {
	/* remove any event handlers you added in activate and do any other cleanup that should happen before
	   this scene is popped or another scene is pushed on top */
}

MainAssistant.prototype.cleanup = function(event) {
	/* this function should do any cleanup needed before the scene is destroyed as 
	   a result of being popped off the scene stack */
}

MainAssistant.prototype.getSimulatorMode = function() {
	return isSimulator;
}

