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

var AccountloginAssistant = Class.create({
	initialize: function(acctId, acctLogin, acctTypeId, acctIcon, acctName, sceneToReturnTo,domain){
		this.acctId = acctId;
		// If the acctId exist, let's just look up the icon from the calendars manager.
		if (this.acctId != 0) {
			// NOTE: If the account was just added, and hasn't been fully synced, getCalAccountIcon
			// will return undefined.
			this.acctIcon = getCalendarsManager().getCalAccountIcon(this.acctId);
		} 
		if (this.acctIcon == undefined) {
			this.acctIcon = acctIcon;
		}
		this.acctLogin = acctLogin;
		this.acctTypeId = acctTypeId;
		this.acctName = acctName;
		this.sceneToReturnTo = sceneToReturnTo;
		this.domain=domain;
	},
	
	setupDeleteButton: function(){
		this.deleteButtonModel = {
			buttonLabel:$L("Remove Account"),
			disabled:false,
			buttonClass: "negative"
		}
		this.controller.setupWidget("RemoveButton", {type: Mojo.Widget.activityButton}, this.deleteButtonModel )
		this.deleteButton = this.controller.get("RemoveButton");
		this.deleteButton.show();
		this.deleteButton.observe(Mojo.Event.tap, this.deleteAccount.bind(this));
	},
	
	deleteAccount:function(){
		this.showPurgeCalendarsConfirmation();
	},
	clearDummyPassword: function(event) {
		// Only clear the contents of the field if we detect that
		// this is the first time the user has changed the password.
		if (!this.passwordChanged) {
			event.target.value = "";
			// Stop listening to the taps in the Password field, since we have cleared
			// the dummy password, and the user is editing the field
			this.passwordTapHandlerStopped = true;
			this.controller.stopListening("Password", Mojo.Event.tap, this.passwordTapHandler);
		}
		this.passwordChanged = true;
	},
	
	setup: function(){
	
		this.accountModel = {
			username:"",
			password:"",
			usernameDisabled: false
		};
		
		var usernameDefaultFocus = false;
		var	passwordDefaultFocus = false;
		
		// Hide the error
		this.controller.get('login_error').hide();
		
		this.buttonAttributes = {
			type: Mojo.Widget.activityButton,
		};
		this.buttonModel = {
			buttonLabel : $L("Sign in"),
			buttonClass: 'primary',
			disabled: false
		};
		this.controller.setupWidget("LoginButton", this.buttonAttributes, this.buttonModel);
		this.loginBtn = this.controller.get("LoginButton");
		//Mojo.Log.info("**************setup the login button");
		if (this.acctId == 0) {
			// Add New Account
			this.title = $L("Add an account");
			// Put focus in Username field by default
			usernameDefaultFocus = true;
		} else {
			// Edit Account
			this.title = $L("Change Login Settings");
			// Put the login name in the Username field
			this.accountModel.username = this.acctLogin;
			// Populate the Password field with 6 bullets
			this.accountModel.password = "xxxxxx";
			this.passwordChanged = false;
			// Disable the Username field in Edit case
			this.accountModel.usernameDisabled = true;
			// Put focus in Password field by default
			passwordDefaultFocus = true;
		}
		
		// Set up the Username and Password TextField widgets
		this.controller.setupWidget("Username", {modelProperty: "username", disabledProperty:'usernameDisabled', focus:usernameDefaultFocus, textReplacement:false}, this.accountModel);
		
		// If we are editing an account, the Password field should have focus, and
		// all of the Password should be selected so the user can change it upon
		// the first key
		this.controller.setupWidget("Password", {modelProperty: "password", requiresEnterKey: true, focus:passwordDefaultFocus, focusMode: Mojo.Widget.focusSelectMode}, this.accountModel);
		
		// Render the header
		var headerObj = {};
		headerObj.serviceIcon = this.acctIcon;
		headerObj.title = this.title;
		var headerHtml = Mojo.View.render({object: headerObj, template:'accountlogin/accountlogin-header'});
		this.controller.get('login_header_div').update(headerHtml);
		
		// Render the domain name in the title of the group box
		this.controller.get('login_domain_name').update(this.acctName);
		
		if (this.acctId != 0) {
			// Only assign these listeners if Editing account
			this.passwordPropertyChangeHandler = this.handlePasswordPropertyChange.bindAsEventListener(this);
			this.controller.listen("Password", Mojo.Event.propertyChange, this.passwordPropertyChangeHandler);
			
			this.passwordTapHandler = this.clearDummyPassword.bindAsEventListener(this);
			this.controller.listen("Password", Mojo.Event.tap, this.passwordTapHandler);
			this.setupDeleteButton();
		}else
			this.controller.get('RemoveButton').remove();
		
		this.passwordField = this.controller.get("Password");
		this.usernameField = this.controller.get("Username");
		
	},
	
	handleLoginButtonTap: function(event) {
		this.loginHandler();
	},
	
	handleKeyUp: function(event) {
		// If the password field has focus and Enter is pressed then simulate tapping on "Sign In"
		if (event && Mojo.Char.isEnterKey(event.originalEvent.keyCode)) {
			// If the submit button is enabled then create the account
			if (this.buttonModel.disabled == false) {
				this.passwordField.blur();
				this.loginHandler();
				Event.stop(event);
			} else {
				this.usernameField.mojo.focus();
			}
		}
	},
	
	handlePasswordPropertyChange: function() {
		//Mojo.Log.info("*** handlePasswordPropertyChange ***")
		if (this.passwordChanged == false) {
				this.passwordPropertyChangeHandlerStopped = true;
				this.controller.stopListening("Password", Mojo.Event.tap, this.passwordTapHandler);
			}
		this.passwordChanged = true;
	},
	
	activate: function() {
		if (this.acctId == 0) {
			// Add New Account
			this.loginHandler = this.createAccount.bind(this);
		} else {
			// Edit Account
			this.loginHandler = this.updateAccount.bind(this);
		}
		
		this.loginButtonHandler = this.handleLoginButtonTap.bindAsEventListener(this);
		this.loginBtn.observe(Mojo.Event.tap, this.loginButtonHandler);
		this.keyUpHandler = this.handleKeyUp.bindAsEventListener(this);
		Mojo.Event.listen(this.controller.sceneElement, Mojo.Event.keyup, this.keyUpHandler, true);
	},
	
	deactivate: function() {
		this.loginBtn.stopObserving(Mojo.Event.tap, this.loginButtonHandler);
		Mojo.Event.stopListening(this.controller.sceneElement, Mojo.Event.keyup, this.keyUpHandler, true);
	},
	
	cleanup: function() {
		if (this.acctId != 0) {
			if (this.passwordPropertyChangeHandlerStopped == undefined) {
				this.controller.stopListening("Password", Mojo.Event.propertyChange, this.passwordPropertyChangeHandler);
			}
		
			if (this.passwordTapHandlerStopped == undefined) {
				this.controller.stopListening("Password", Mojo.Event.tap, this.passwordTapHandler);
			}
		}
	},
	
	loginCallback: function(response) {
		Mojo.Log.info("accountlogin-assistant: loginCallback");
		var sController = this.controller.stageController;
		
		// The request has already been executed
		this.request = undefined;
		this.hideSpinner();
		
		if (response.success == true) {
			Form.disable(this.controller.get("AccountLoginForm"));
			
			if (this.sceneToReturnTo) {
				sController.popScenesTo(this.sceneToReturnTo);
				var sceneStack = sController.getScenes();
				var sceneExists = undefined;
				if (sceneStack) {
					for (var index = 0; index < sceneStack.size(); index++) {
						scene = sceneStack[index];
						if (scene.sceneName == this.sceneToReturnTo) {
							sceneExists = scene;
							break;
						}
					}
				}
				if (!sceneExists) {
					sController.pushScene(this.sceneToReturnTo);
				}
			} else {
				sController.popScene();
			}
			
		} else {
			
			// Login failed so we need to display the error message
			var msgStrs = {
				"AcctMgr_Network_Error" : $L("Network error."),
				"AcctMgr_Bad_Username": $L("Bad username."),
				"AcctMgr_Bad_Password": $L("Bad password."),
				"AcctMgr_Bad_Authentication": $L("The email address or password is incorrect. Try again."),
				"AcctMgr_Generic_Error": $L("Generic error."),
				"AcctMgr_Account_Locked": $L("Account locked."),
				"AcctMgr_Acct_Already_Exists": $L("Account already exists."),
				"AcctMgr_Acct_Not_Created": $L("Account not created."),
				"AcctMgr_No_Setup_Service": $L("No setup service.")    
	   		};
			
			var errorMsg = $L('Login failed.');
			
			if(response.errorMessage && msgStrs[response.errorMessage])
				errorMsg = msgStrs[response.errorMessage];
				
			//if the error is network error then first check if there is a connection
			
			if (response.errorMessage == "AcctMgr_Network_Error") {
			
				this.controller.serviceRequest("palm://com.palm.connectionmanager", {
					method: "getstatus",
					onSuccess: this.connectionManagerResponse.bind(this)

				});
			
			}
			else {
				//this is for all other errors
				
				this.showErrorMessage(errorMsg);
				
				if (response.errorMessage == "AcctMgr_Bad_Username") {
					// If the username was bad, add error class to Username label
					this.controller.get("UsernameLabel").addClassName("error");
					this.controller.get("PasswordLabel").removeClassName("error");
				}
				else 
					if (response.errorMessage == "AcctMgr_Bad_Password") {
						// If the password was bad, add error class to Password label
						// Change the label to the button
						this.controller.get("PasswordLabel").addClassName("error");
						this.controller.get("UsernameLabel").removeClassName("error");
					}
			}
		}
	},
	connectionManagerResponse:function(resp){
		
		if (resp.isInternetConnectionAvailable) {
			//this is the case when we do have  a connection
			
			this.showErrorMessage($L("Unable to connect.  Try again."));
		}
		else {
			//we know for sure there is no network
			//so show the system connection widget
			var params = {
                        type: "data",
                        onSuccess: this.handleSuccessCallBack.bind(this)
                     }
					 
        	ConnectionWidget.connect(params, this.controller);
			
		}
					
		
	},
	
	
	handleSuccessCallBack:function(resp)
	{
		
		//check if the user cancelled the dialog
		//if not he agreed to enable wifi, so dont put up any
		//error message
		
    	if (resp == "WiFi-UserCancelled") {
            this.showErrorMessage($L("No Internet Connection"));
        }
	
	},	
	hideSpinner: function() {
		this.buttonModel.disabled = false;
		this.buttonModel.buttonLabel = $L("Sign in");
		this.controller.modelChanged(this.buttonModel);
		this.loginBtn.mojo.deactivate();
	},
	
	showSpinner: function() {
		// Disable the Sign In button
		this.buttonModel.disabled = true;
		this.buttonModel.buttonLabel = $L("Signing in...");
		this.controller.modelChanged(this.buttonModel);
		this.loginBtn.mojo.activate();
	},
	
	createAccount: function(){
		//Mojo.Log.info("********* CREATE ACCOUNT ********* ");
		// Reset the error message
		this.hideErrorMessage();
		
		this.showSpinner();
		this.request = getPimSyncService().createAccount(this.controller, this.accountModel.username, this.accountModel.password, this.acctTypeId, this.loginCallback.bind(this));
	},
	
	updateAccount: function() {
		// Reset the error message
		this.hideErrorMessage();
		
		if (!this.passwordChanged) {
			// The password didn't change so we don't need to do anything
			// Call the callback which will pop this scene
			this.loginCallback({success:true});
			return;
		}
		
		if(!this.validateEntry()){
			this.hideSpinner();
			return;
		};
		
		this.showSpinner();
		
		if (this.domain == 'eas') {
			var cb = this.loginCallbackEas.bind(this);
			this.request = this.controller.serviceRequest('palm://com.palm.mail', {
				method: 'setEasCredentials',
				parameters: { account: this.acctId, login: this.accountModel.username, password: this.accountModel.password },
				onSuccess: cb,
				onFailure: cb
			});
		} else {
			this.request =  getPimSyncService().updateAccountCredentials(	this.controller, 
																										this.acctId, 
																										this.accountModel.username, 
																										this.accountModel.password, 
																										this.loginCallback.bind(this));
		}
		
	},
	
	loginCallbackEas:function(response){
		console.info("n loginc allback eas");
		// normalize the mail/setEasCredentials response into what pimsync/updateAccountCredentials returns
		var normalized = {};
		if (response.returnValue == true) {
			normalized.success = true;
		} else {
			normalized.success = false;
			normalized.errorMessage = response.errorCode;
		}
		this.loginCallback(normalized);
	
	},
	
	showErrorMessage: function(msg) {
		var msgObj = {errorMsg: msg};
		var html = Mojo.View.render({object: msgObj, template:'accountlogin/accountlogin-error-msg'});
		var login_error_div = this.controller.get('login_error');
		login_error_div.update(html);
		login_error_div.show();
	},
	
	hideErrorMessage: function(msg) {
		var login_error_div = this.controller.get('login_error');
		login_error_div.hide();
	},
	
	validateEntry: function(){
    this.controller.get("UsernameLabel").removeClassName("error");
    this.controller.get("PasswordLabel").removeClassName("error");
    var username = this.accountModel.username;
    var password = this.accountModel.password;
    if(!username || !password)
    {
			if (!username && !password)
      	this.showErrorMessage($L("Please enter a username and password"));
			else if (!username) {
				this.showErrorMessage($L("Please enter a username"));
			} else if (!password) {
				this.showErrorMessage($L("Please enter a password"));
			}
			
      if (!username) {
        // If the username was bad, add error class to Username label
        this.controller.get("UsernameLabel").addClassName("error");

      }
      if(!password){
        // If the password was bad, add error class to Password label
        // Change the label to the button
        this.controller.get("PasswordLabel").addClassName("error");
      }     
      return false;
    }
		return true;
	},

	// *** WIDGET ATTRS AND MODELS ***
	spinnerAttrs: {
		spinnerSize: 'small'
	},

	spinnerModel: {
		spinning: false
	},
	
	showPurgeCalendarsConfirmation: function(){
		//Mojo.Log.info("prefs-acct-assistant: showPurgeCalendarsConfirmation");
		this.controller.showDialog({
			template: 'shared/confirm-purgeaccount',
			assistant: new PurgeAccountConfirmDialogAssistant(this),
		});
	},
	
		yesToPurgeAccountConfirm: function() {
		
		// Go ahead and purge those calendars
		// Call service to delete calendars from this account
		
		this.deleteButton.mojo.activate();
		//this.deleteButtonModel.buttonLabel = $L("Removing Account...");
		this.deleteButtonModel.disabled = true;
		this.controller.modelChanged(this.deleteButtonModel);
		
		this.loginBtn.disabled=true;
		this.controller.modelChanged(this.buttonModel);
		//stop observing list taps	
		//this.controller.get('pav_calendars_list').stopObserving(Mojo.Event.listTap, this.acctsListSelectionHandler);

		//stop observing the edit login button tap

		//this.controller.get('pav_edit_login_btn').stopObserving(Mojo.Event.tap, this.editLoginBtnTapHandler);
		
		getAccountsService().removeService(this.controller, this.acctId, this.removeServiceCallback.bind(this));
		
	},
	removeServiceCallback:function(){
		this.controller.stageController.popScene();
	},
	
	noToPurgeAccountConfirm: function() {
//		Mojo.Log.info("prefs-acct-assistant: noToPurgeAccountConfirm");
		// Don't do anything if the user wants to keep his calendars
		
		// Remove the spinner from the Remove Account button since we are not removing
		// the account
		this.deleteButton.mojo.deactivate();
	},
})

