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

//Small controller class used to get password for the account
//figure out what to do with errordeviceid

var PasswordAssistant = Class.create({
	
	initialize: function(sceneAssistant, isTokenNeeded) {
		this.sceneAssistant = sceneAssistant; //make sceneassistant local
		this.controller = sceneAssistant.controller;	//pull out the controller out of scene assistant and make it local
		this.loginAttemptCount=0;
		this.usrpwd_password_hintText = $L("enter password...");
		this.myProfile = new Profile();
		this.myProfile.isTokenNeeded = isTokenNeeded;
	},
	
	setup : function(widget) {
		this.widget = widget; 
		this.acctPasswordAttr = {
			hintText: this.usrpwd_password_hintText,
			modelProperty: 'original',
			focus: true,
			className: ' ',
			focusMode: Mojo.Widget.focusSelectMode,
			maxLength: ProfileUtil.MAXPASSWORDLENGTH,
			changeOnKeyPress: true,
			requiresEnterKey: true
		};
		
		this.acctPasswordModel = {
			'original' : '',
		};

		this.acctPasswordAttr.charsAllow = ProfileUtil.filterSpace.bind(this);
		this.controller.setupWidget('acctPassword', this.acctPasswordAttr, this.acctPasswordModel); 
		this.controller.get('acctPassword').observe(Mojo.Event.propertyChange, this.passwordChanged.bind(this));
		
		
		this.buttonAttr = {									
			disabledProperty: 'disabled',					
			type: Mojo.Widget.activityButton
		};
		this.buttonModel = {								
			disabled: true,									
			buttonLabel : $L('Sign In'),					
			buttonClass: 'palm-button'						
		};
		
		this.controller.setupWidget('submitPassword', this.buttonAttr, this.buttonModel); 
		Mojo.listen(this.controller.get('submitPassword'), Mojo.Event.tap, this.isUserValid.bindAsEventListener(this));
		
		this.forgotButtonAttr = {
			disabledProperty: 'disabled'
		};
		
		this.forgotButtonModel = {
			disabled: false,
			buttonLabel : $L('Forgot password'),
			buttonClass: 'palm-button'
		};
		
		this.controller.setupWidget('forgotPasswordButton', this.forgotButtonAttr, this.forgotButtonModel);
		Mojo.listen(this.controller.get('forgotPasswordButton'), Mojo.Event.tap, this.forgotPassword.bindAsEventListener(this));
			
		this.passwordField = this.controller.get("acctPassword");
	},
	
	activate : function() {
		this.controller.get('acctPassword').mojo.focus.delay(0);
	},	
	
	toggleDisabled: function() { 
       if(this.acctPasswordModel.original.length >= ProfileUtil.MINPASSWORDLENGTH) {
			this.buttonModel.disabled = false;
			this.controller.modelChanged(this.buttonModel);
	   } else {
			this.buttonModel.disabled = true;
			this.controller.modelChanged(this.buttonModel);
	   }
    },
	
	passwordChanged: function (event) {
		this.toggleDisabled();
		
		// If the password field has focus and Enter is pressed then simulate tapping on "next"
			
		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.isUserValid();
				Event.stop(event);
			} else {
				this.passwordField.mojo.focus();
			}
		}
	},
	
	handleCommand: function(event) {	
		if (event.type == Mojo.Event.back) {
			Mojo.Log.info("------- Blocking back ----------");
			event.preventDefault();
			event.stopPropagation();
			this.widget.mojo.close();
		}
	},
	
	hideAllErrorMessages: function() {
		this.controller.get('passwordLengthError').hide();
		this.controller.get('passwordError').hide();
	},
	
	getAccountToken: function() {
		Mojo.Log.info("------------------- Get account token ------------------");
		AppAssistant.accountService.getAccountToken(this.readAccountToken.bind(this),
						this.accountTokenError.bind(this), this.controller);						
	},

	readAccountToken: function (response) {
		if (response.accountAlias != undefined) { //The trunk refers to the unnamed branch (version) of a file tree under revision control. The trunk is usually meant to be the base of a project on which development progresses. If developers are working exclusively on the trunk, it always contains the latest cutting-edge version of the project, but therefore may also be the most unstable version. Another approach is to split a branch off the trunk, implement changes in that branch and merge the changes back into the trunk when the branch has proven to be stable and working. Depending on development mode and commit policy the trunk may contain the most stable or the least stable or something-in-between version.
			this.myProfile.email = response.accountAlias;
			this.myProfile.state = response.accountState;
			this.myProfile.token = response.token;
			Mojo.Log.error("--------------- Authentication needed -----------------%j", this.myProfile.isTokenNeeded);
			if(this.myProfile.isTokenNeeded === true) {
			  	this.authenticateRequest = AppAssistant.accountService.authenticateAccount(
																				this.myProfile.email, this.myProfile.password,
																				this.authenticateSuccess.bind(this),
																				this.authenticateError.bind(this), this.controller
				);
			 }	
			this.deviceIdRequest = AppAssistant.accountService.getDeviceId(
										this.readDeviceId.bind(this), 
										this.errorDeviceId.bind(this), 
										this.controller);	
		} else {
			//TODO Handle missing account token case
		}	
	},
	
	authenticateSuccess: function (response) {
		Mojo.Log.info("--------------- Authentication successful -----------------%j", response);
	},
	
	authenticateError: function (response) {
		Mojo.Log.error("--------------- Authentication error -----------------%j", response);
	},

	accountTokenError: function(response) {
		Mojo.Log.info("No account token = %o", $H(response));	
	},
	
	isUserValid: function(event) {
		this.hideAllErrorMessages();
		this.loginAttemptCount++;
		this.myProfile.password = this.acctPasswordModel.original;
		
		 if ((this.myProfile.password.length < ProfileUtil.MINPASSWORDLENGTH) || (this.myProfile.password.length > ProfileUtil.MAXPASSWORDLENGTH)) {
			this.controller.get('passwordLengthError').show();
			return;
		}
		
		if (isConnectionAvailable === false) {
			ProfileUtil.showConnectionError(this.controller);
			return;
		}
		
		this.buttonModel.disabled = true;
		this.controller.modelChanged(this.buttonModel);
		
		this.showButtonSpinner();
		this.getAccountToken();	
	},
	
	readDeviceId: function (response) {
		Mojo.Log.info("Read device id %o", $H(response));
		if (response && response.deviceId) {
			AppAssistant.accountService.isUserValid(
								this.myProfile.email, this.myProfile.password, response.deviceId,  
								this.checkIfUserValid.bind(this), this.invalidUser.bind(this), this.controller);
		}
		else
		{
			//errorcase	
		}
					
	},
	
	errorDeviceId: function (response) {
		Mojo.Log.error("Could not get device id %o", $H(response));
		this.hideButtonSpinner();
	},
	
	checkIfUserValid: function (response) {
		Mojo.Log.info("\n\ncheckIfUserValid Response: " + $H(response).inspect());
		Mojo.Log.info("\nLogin attempt: "+this.loginAttemptCount + "\n\n");
		
		if(response.isValid === true) {
			//This is the temp token used for preferences
			this.myProfile.idToken = response.idToken;
			Mojo.Log.error("---------------------- this.isTokenNeeded ---------------", this.myProfile.isTokenNeeded);
			if(this.myProfile.isTokenNeeded === true) {
				// Authenticate user and close app
			}
			Mojo.Controller.stageController.swapScene("account", this.myProfile);
		} else {
			//Get security question for the account
			if (this.myProfile.questionId == "") {
				this.getUserLocale();
			}
			else {
				this.loginError();
				this.hideButtonSpinner();
			}	
		}
	},
	
	getUserLocale: function () {
		AppAssistant.accountService.getLocale(this.readLocale.bind(this), this.errorLocale.bind(this), this.controller);
	},
	
	readLocale: function (response) {
		if(response.locale) {
			this.currentLanguage = response.locale.languageCode.toLowerCase();
			this.countryCode = response.locale.countryCode.toLowerCase();
			this.getQuestionForAccount();
		} else {
			this.errorLocale(response);
		}
	},
	
	errorLocale: function (response) {
		this.currentLanguage = "en";
		this.countryCode = "us";
		this.getQuestionForAccount();
	},
	
	getQuestionForAccount: function (){
		AppAssistant.accountService.getAccountSecurityQuestions(this.myProfile.email, this.currentLanguage +"_"+ this.countryCode, 
						this.getAccountSecurityQuestion.bind(this), this.accountSecurityQuestionError.bind(this), this.controller);
	},
	
	showButtonSpinner: function() {
		// Disable the Sign In button
		this.buttonModel.disabled = true;
		this.buttonModel.buttonLabel = $L("Signing in...");
		this.controller.modelChanged(this.buttonModel);
		this.controller.get('submitPassword').mojo.activate();
	},
	
	hideButtonSpinner: function() {
		this.buttonModel.disabled = false;
		this.buttonModel.buttonLabel = $L("Sign in");
		this.controller.modelChanged(this.buttonModel);
		this.controller.get('submitPassword').mojo.deactivate();
	},
	
	loginError: function () {
			
		if (ProfileUtil.emailSent === true) {
			this.widget.mojo.close();		
			this.controller.showDialog({
				template: 'account/recover-email-dialog',
				assistant: new RecoverEmailAssistant(this, this.myProfile)
			});
			return;
		}
		else if(this.loginAttemptCount >= ProfileUtil.MAXLOGINATTEMPTS) {
			if (this.myProfile.questionId > 0) {
					this.forgotPassword();
			}
			else {
				this.sendPasswordResetEmail();
			}
			return;
		}
		Mojo.Log.info("Login attempt: ",this.loginAttemptCount);
		
		if (this.myProfile.questionId > 0) {
			this.controller.get('forgotPassword').show();
		}	
		this.controller.get('passwordError').show();
		
		this.hideButtonSpinner();
		this.buttonModel.disabled = true;
		this.controller.modelChanged(this.buttonModel);
		this.controller.get('acctPassword').mojo.focus();
	},
	
	getAccountSecurityQuestion: function (response) {
		if (response.id != undefined) {
			this.myProfile.questionId = response.id;
			this.myProfile.questionText = response.question;
		} else {
			this.myProfile.questionId = -1;
		}	
		this.loginError();
	},
	
	accountSecurityQuestionError: function(response) {
		Mojo.Log.error("Error in getting account security question = %o", $H(response));
		this.myProfile.questionId = -1;
		this.loginError();
	},	
		
	invalidUser: function(response) {
		Mojo.Log.info("\n\ninvalidUser Login error: "+$H(response).inspect() + "\n");
		if(response.errorCode && response.errorCode === "CONNECTION_ERROR") {
			this.widget.mojo.close();
			ProfileUtil.showConnectionError(this.controller);
		}
	},
	
	forgotPassword: function () {
		this.widget.mojo.close();
		this.controller.showDialog({
			template: 'account/security-question-dialog',
			assistant: new ForgotPasswordAssistant(this, this.myProfile)
		});
	},
	
	sendPasswordResetEmail: function() {
		AppAssistant.accountService.requestPasswordResetEmail(
						this.myProfile.email, 
						this.resetEmailSuccess.bind(this), 
						this.resetEmailError.bind(this), 
						this.controller);
	},
	
	resetEmailSuccess: function(response) {
		Mojo.Log.info("------------ resetEmailSuccess -----------------%o", $H(response));
		ProfileUtil.emailSent = true;
		this.widget.mojo.close();
		this.controller.showAlertDialog({
		    onChoose: function(value) {},
		    title: $L("Password reset"),
			message: $L("Check your email for a message from mypalmaccounts@palm.com. Follow the link in that email to reset your password. <br/><br/>If you need more help, please visit www.palm.com."),
		    choices:[
	        {label: $L('Done'), value:'done', type:'color'}    
		    ],
			allowHTMLMessage: true
	 	});	
	},
	
	resetEmailError: function(response) {
		Mojo.Log.error("could not send password reset email %o", $H(response));
	}
});
