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

var AccountAssistant = Class.create({
	spinner: 'activity-spinner',
	spinning: false,
	spinnerAttrs: {
		spinnerSize: Mojo.Widget.spinnerLarge
	},
	
	initialize: function(myProfile){
		ProfileUtil.emailSent = false;
		this.myProfile = myProfile;
		if(this.myProfile.email === "" || this.myProfile.state == "") {
			this.myProfile.state="NoToken";	
		}
		Mojo.Log.info("\ninitialize(): Account State: " + this.myProfile.state + "\n");
	},
	
	setup: function() {
		
		this.loadedEmail = false;
		this.loadedQuestions = false;
		
		this.firstNameAttributes = {
			modelProperty: 'firstName',
			multiline: false,
			maxLength: 50, 
			textReplacement: true
		};
		this.firstNameModel = {
			'firstName' :  '',
			disabled: false
		};

		this.controller.setupWidget('firstName', this.firstNameAttributes, this.firstNameModel);
		
		this.lastNameAttributes = {
			modelProperty: 'lastName',
			multiline: false,
			textReplacement: true,
			enterSubmits:false,
			maxLength: 50
		};
		this.lastNameModel = {
			'lastName' : '',
			disabled: false
		};

		this.controller.setupWidget('lastName', this.lastNameAttributes, this.lastNameModel);
		$('firstName').observe(Mojo.Event.propertyChange, this.firstNameChanged.bind(this));
		$('lastName').observe(Mojo.Event.propertyChange, this.lastNameChanged.bind(this));
		
		this.emailAttributes = {
			modelProperty: 'emailAddress',
			multiline: false,
			maxLength: 100, 
			textReplacement: false,
			focusMode: Mojo.Widget.focusInsertMode
		};
		this.emailModel = {
			'emailAddress' : '',
			disabled: false
		};
		
		this.controller.setupWidget('emailAddress', this.emailAttributes, this.emailModel);
		$('emailAddress').observe(Mojo.Event.propertyChange, this.emailChanged.bind(this));
		
		this.getAccountInfo();
		this.securityQuestions = [{"label":$L("Select a question"), "value":"-1"}];
				
		this.questionsModel = {selectedQuestion: this.securityQuestions[0].label, choices: this.securityQuestions};
		this.controller.setupWidget('questionSelector', {modelProperty: 'selectedQuestion'}, this.questionsModel);	
		$('questionSelector').observe(Mojo.Event.propertyChange, this.questionChanged.bindAsEventListener(this));
		this.initializeQuestions();
		
		this.answerAttributes = {
			modelProperty: 'answer',
			multiline: false,
			maxLength: 50, 
			textReplacement: false,
			changeOnKeyPress: true,
			requiresEnterKey: true
		};
		this.answerModel = {
			'answer' : '',
			disabled: false
		};
		
		this.controller.setupWidget('answer', this.answerAttributes, this.answerModel);
		
		this.buttonAttr = {
			disabledProperty: 'disabled'
		};
		this.buttonModel = {
			disabled: false,
			buttonLabel : $L('Change Password'),
			buttonClass: 'palm-button'
		}; 		
		
		this.controller.setupWidget('changePassword', this.buttonAttr, this.buttonModel);
		
		$('answer').observe(Mojo.Event.propertyChange, this.answerAdded.bind(this));
		$('changePassword').observe(Mojo.Event.tap, this.changePassword.bindAsEventListener(this));
		$('resendEmail').observe(Mojo.Event.tap, this.resendVerificationEmail.bindAsEventListener(this));
		$('answer').observe(Mojo.Event.tap, this.answerChanged.bindAsEventListener(this));
		
		this.appMenuModel = {
            visible: true,
            items: [Mojo.Menu.editItem, Mojo.Menu.helpItem]
        };
	
		$('accountState').hide(); //hide DIV with account activation warning and resend button
	
		this.controller.setupWidget(Mojo.Menu.appMenu, {omitDefaultItems: true}, this.appMenuModel);
		Mojo.Log.info("start spinner now ");		
		this.controller.setupWidget(this.spinner, this.spinnerAttrs, {});	
		
	},
	
	handleLoseFocus: function() {
		//this.saveAccount();		//NOT saving and going back to backup screen on card view
	},
	
	activate: function() {		
		this.spinning = true;
		$(this.spinner).mojo.start();
		this.controller.get('scrim').show();
		
		this.controller.document.addEventListener(Mojo.Event.stageDeactivate, this.handleLoseFocus.bind(this), false)
	},	
	
	firstNameChanged: function(event) {
	 	this.firstNameModel.firstName = event.value[0].capitalize() + event.value.substring(1);
		this.controller.modelChanged(this.firstNameModel, this);
		$('firstNameError').hide();
	},
	
	lastNameChanged: function(event) {
		this.lastNameModel.lastName = event.value[0].capitalize() + event.value.substring(1);
		this.controller.modelChanged(this.lastNameModel, this);
		$('lastNameError').hide();
	},
	
	emailChanged: function(event) {
		$('emailError').hide();
	 	this.emailModel.emailAddress = event.value;
		$('emailEmptyError').hide();
	},
	
	answerAdded: function(event) {
	 	this.answerModel.answer = event.value;	
		this.newAnswer = true;
		if (event && Mojo.Char.isEnterKey(event.originalEvent.keyCode)) {
			Event.stop(event); 
		}
	},
	
	handleCommand: function(event) {	
		if (event.type == Mojo.Event.back) {
			Mojo.Log.info("------- Blocking back ----------");
			event.preventDefault();
			event.stopPropagation();
			
			this.saveAccount();
		}
		else if (event.type == Mojo.Event.command && event.command == Mojo.Menu.helpCmd)  {
            Mojo.Log.info("------------------ Launch Help -------------------------");
			this.launchHelp();
        }
        else if (event.type == Mojo.Event.commandEnable && event.command == Mojo.Menu.helpCmd)  {
            event.stopPropagation();
        }
	},
	
	areAllFieldsFilled: function () {
		if(this.firstNameModel.firstName.empty()) {
			$('firstNameError').show();
			return false;
		}
		
		if(this.lastNameModel.lastName.empty()) {
			$('lastNameError').show();
			return false;
		}
		
		if(this.emailModel.emailAddress.empty()) {
			$('emailEmptyError').show();
			return false;
		}
		
		if((this.selectedQuestionId != -1) && (this.answerModel.answer.empty())) {
			$('answerError').show();
			return false;
		}
		return true;
	},
	
	showEmailError: function () {
		$('emailError').show();
		this.controller.showAlertDialog({
	    	onChoose: function(value) {
				if("cancel" == value) {
					Mojo.Controller.stageController.popScene();
					Mojo.Controller.stageController.pushScene("backup");
				} else {
					
				}
			},
		    title: $L("Invalid email address"),
		    message: $L("You must use a valid email address format."),
		    choices:[
	        	{label:$L('Edit Address'), value:"edit"},  
	        	{label:$L("Don't Update"), value:"cancel"}    
		    ]
	  });
	},
	
	launchHelp: function(){
		var openParams = {  scene: 'page', url: "http://help.palm.com/palm_acct/index.html"};
		return new Mojo.Service.Request('palm://com.palm.applicationManager', {
        				method: 'open',
		      			parameters: { id: 'com.palm.app.browser',
						              params: openParams }
   		 });
	},
		
	resendVerificationEmail: function () {
		AppAssistant.accountService.resendVerificationEmail(
							this.successResendEmail.bind(this), 
							this.errorResendEmail.bind(this), 
							this.controller);
	},
	
	successResendEmail: function(response) {
		var confirmText = $L("A verification email was sent to #{email}.").interpolate({
					email: this.myProfile.email
		});
		this.controller.showAlertDialog({
			onChoose: function(value){
			
			},
			title: $L('Email Sent'),
			message: confirmText,
			choices: [{
				label: $L('Done'),
				value: 'next',
				type: 'color'
			}]
		});
	},
	
	errorResendEmail: function(response) {
		
		if(response && response.errorCode === "PAMS1114") {
			$('accountState').hide();
			return;
		}
		if (response.errorText && response.errorText === "No response") {
			this.controller.showAlertDialog({
				onChoose: function(value){
					if("help" == value) {
						ProfileUtil.launchHelp();
					}
				},
				title: $L('No Internet Connection'),
				message: $L('We will send your confirmation email as soon as you have an internet connection.'),
				choices: [{
					 choices:[
						{label:$L('Help'), value:"help", type: 'color'},
			        	{label:$L('OK'), value:"ok", type: 'color'} 
				    ]
				}]
			});
		}		
	},
		
	initializeQuestions: function() {
		Mojo.Log.info("Get questions");
		Mojo.Log.info("this.controller = ",this.controller);
		this.questionId = "";
		this.getUserLocale();
		
	},
		
	getUserLocale: function () {
		AppAssistant.accountService.getLocale(this.readLocale.bind(this), this.errorLocale.bind(this), this.controller);
	},
	
	readLocale: function (response) {
		if(response.locale) {
			this.myProfile.languageCode = response.locale.languageCode.toLowerCase();
			this.myProfile.countryCode = response.locale.countryCode.toLowerCase();
		} else {
			this.errorLocale(response);
		}
		AppAssistant.accountService.getAllSecurityQuestions(this.myProfile.languageCode +"_"+ this.myProfile.countryCode,
							this.getSecurityQuestions.bind(this), 
							this.errorSecurityQuestions.bind(this), this.controller);
	},
	
	errorLocale: function (response) {
		this.myProfile.languageCode = "en";
		this.myProfile.countryCode = "us";
		this.getQuestionForAccount();
	},
	
	getSecurityQuestions: function(response){		
		Mojo.Log.info("Challenge Qs = ",response.challengeQuestions);
		this.myProfile.securityQuestions = response.challengeQuestions;
		Mojo.Log.info("this.controller = ",this.controller);
		this.getQuestionForAccount();
	},
	
	errorSecurityQuestions: function(response) {
		Mojo.Log.error("error in getting sec questions %o", $H(response));
		AppAssistant.accountService.getAllSecurityQuestions(
							this.getSecurityQuestions.bind(this), 
							this.errorSecurityQuestions.bind(this), this.controller);
	},
	
	getQuestionForAccount: function (){
		AppAssistant.accountService.getAccountSecurityQuestions(this.myProfile.email, this.myProfile.languageCode +"_"+ this.myProfile.countryCode, 
						this.getAccountSecurityQuestion.bind(this), this.accountSecurityQuestionError.bind(this), this.controller);
	},
	
	getAccountSecurityQuestion: function (response) {
		//Mojo.Log.info("Account sec question = %o", $H(response.id));
	
		if (response.id) {
			this.myProfile.questionId = response.id;
			Mojo.Log.info("Account sec question = " , response.id);
			this.myProfile.questionText = response.question;
		}	
		Mojo.Log.info("this.myProfile.questionId = ",this.myProfile.questionId);
		if (this.myProfile.questionId != "") {
			this.answerModel.answer = "*******";
			this.controller.modelChanged(this.answerModel, this); 
		}	
		this.setSecurityQuestions();
	},
	
	setSecurityQuestions: function(response) {
		var questions = [];
		var i=0;
		var index = -1;
		
		questions[0] = {
			label: $L("Select a question"),
			value: -1
		};
		Mojo.Log.info("Questions Model= ",this.questionsModel.choices);
		
		if (this.myProfile.securityQuestions == undefined) {
			Mojo.Log.info("no security questions");
		} else {
			var that=this;	//for inline function's scoping problem with this.myProfile
			this.myProfile.securityQuestions.each(function(question){	
				if (that.myProfile.questionId != undefined) {
					if (that.myProfile.questionId == question.id) {
						index = i;
					} 
				}	
				questions[i++] = {
					label: question.question,
					value: question.id
				};	
			});
		}
				
		this.securityQuestions = questions;
		this.selectedIndex = index;
		Mojo.Log.info("Selected index = ", this.selectedIndex);
				
		if (this.selectedIndex == -1) {
			this.selectedQuestionId = -1;
		} else {
			this.selectedQuestionId = this.securityQuestions[this.selectedIndex].value;
			this.questionsModel.selectedQuestion = this.securityQuestions[this.selectedIndex].value;
		}	
		this.questionsModel.choices = this.securityQuestions;
		this.myProfile.selectedQuestionId = this.selectedQuestionId;
		this.controller.modelChanged(this.questionsModel, this);
		this.loadWatcher("loadedQuestions");
	},
	
	questionChanged: function(event) {
		var newId = this.questionsModel.selectedQuestion;
		if(newId != this.selectedQuestionId) {
			Mojo.Log.info("Question is changed");
			this.selectedQuestionId = newId;
			this.answerModel.answer = "";
			this.controller.modelChanged(this.answerModel, this);
		}
	},
	
	answerChanged: function(event) {
		if(this.selectedQuestionId == -1) {
			this.controller.showAlertDialog({
				onChoose: function(value){
				
				},
				title: $L("Error"),
				message: $L("Please select a security question"),
				choices: [{
					label: $L('Done'),
					value: 'next',
					type: 'color'
				}]
			});
			return;
		}
		this.answerModel.answer = "";
		this.controller.modelChanged(this.answerModel, this);
		
		this.newAnswer = true;
	},
	
	accountSecurityQuestionError: function(response) {
		Mojo.Log.info("Error in getting account security question = %o", $H(response));
	},
		
	getAccountInfo: function() {
		AppAssistant.accountService.getAccountInfo(
							this.readAccountInfo.bind(this), 
							this.accountInfoError.bind(this), 
							this.controller);
	},
	
	readAccountInfo: function (response) {
		this.firstNameModel.firstName = response.firstName;
		this.controller.modelChanged(this.firstNameModel, this);
		
		this.lastNameModel.lastName = response.lastName;;
		this.controller.modelChanged(this.lastNameModel, this);
		
		this.emailModel.emailAddress = response.email;
		this.controller.modelChanged(this.emailModel, this);
								
		this.myProfile.firstName =  response.firstName;
		this.myProfile.lastName =  response.lastName;
		this.myProfile.email = response.email;
		
		if(response.accountState == 'B'){ 
			$("accountState").hide();
		}else {
			$("accountState").show();
		}
		
		this.loadWatcher("loadedEmail");
	},
	
	 accountInfoError: function (response) {
		Mojo.Log.error("error occured: %j", response);
	 },
	
	changePassword: function() {
		Mojo.Log.info("change password");
		this.controller.showDialog({
			template: 'account/change-password-dialog',
			assistant: new ChangePasswordAssistant(this, this.myProfile)});
		
	},
	
	cleanup: function() {
		Mojo.Log.info("&&&&&&&&&&&&&&&&&&&&&& clean up called");
	},
		
	saveAccount: function() {
		Mojo.Log.info("------- areAllFieldsFilled ----------");
		if(!(this.areAllFieldsFilled())) {
			return;
		}
		Mojo.Log.info("------- validateEmail ----------");
		if (!this.validateEmail()) {
			this.showEmailError();
			return;
		}
		Mojo.Log.info("------- saveAccount ----------");
		
		this.previousEmail = this.myProfile.email;
		Mojo.Log.info("saving ---------------");
		Mojo.Log.info("saving ---------------------- isConnectionAvailable", (isConnectionAvailable===false));
		
		if (isConnectionAvailable === false) {
			Mojo.Log.info("show connection error ---------------");
			ProfileUtil.showConnectionError(this.controller);
			return;
		}	
		this.lockEditMode();
		
		this.fieldsChanged = ( this.checkNameChange() || this.checkEmailChange() || this.checkSecurityChange() );
		
		if (this.checkNameChange())
		{
			Mojo.Log.info("Name changed - call update info");	
			this.myProfile.firstName =this.firstNameModel.firstName;
			this.myProfile.lastName = this.lastNameModel.lastName;
			//this.myProfile.email = this.emailModel.emailAddress;
			AppAssistant.accountService.updateAccountInfo(
							this.myProfile,
							this.successNameChange.bind(this), 
							this.errorNameChange.bind(this), 
							this.controller);
			
		}
		
		if (this.checkSecurityChange()) {
			if (this.myProfile.idToken != undefined) {
				Mojo.Log.info("answer value ---------------- ", this.answerModel.answer.empty());
				if (this.answerModel.answer.empty()) {
					//TODO Do we remind the user to set answer?
					return;
				}
				AppAssistant.accountService.changePassword(
					this.myProfile.password,
					this.selectedQuestionId,
					this.answerModel.answer,
					this.myProfile.idToken,
					false,
					this.successSecurityChange.bind(this),
					this.errorSecurityChange.bind(this),
					this.controller);
			}
			else {
				Mojo.Log.info("No id token ");
			//TODO Authenticate user again
			}
		}
		
		if(this.checkEmailChange())
		{
			Mojo.Log.info("Email changed - change email to " + this.myProfile.email);	
			
			this.previousEmail = this.myProfile.email;
			this.myProfile.email = this.emailModel.emailAddress;
			
			Mojo.Log.info("Email changed - change email to " + this.myProfile.email);
			AppAssistant.accountService.changeEmail(
							this.myProfile.email,
							this.successEmailChange.bind(this), 
							this.errorEmailChange.bind(this), 
							this.controller);
		}
		
		else //if email not changed, no banner, can go straight to backup scene
		//other scenario in successEmailChange
		{
			this.backToAccountScreen();
		}	
				
	},
	
	backToAccountScreen : function()
	{
		if (this.fieldsChanged)
		{
			this.controller.showBanner({
				icon: "images/tap-info.png",
				messageText: ProfileUtil.label_account_saved_message
				}, 
				{}, 
				'pubsubbanner');
		}
		/*
		else //the "No changes made" banner pops up in case profile screen is exited with no changes
		{
			this.controller.showBanner({
				icon: "images/warning_small.png",
				messageText: ProfileUtil.label_account_unchanged_message
				}, 
				{},
				'pubsubbanner');
		}
		*/
		
		Mojo.Controller.stageController.swapScene("backup");
	},
		
	lockEditMode: function() {
        $$('#editProfile input:focus').each(function(element){
            element.blur();
        });
    },
	
	checkNameChange: function() { //Function only checks for changes in name fields, returns bool
		Mojo.Log.info("check name change");
		if((this.myProfile.firstName != this.firstNameModel.firstName) ||
			(this.myProfile.lastName != this.lastNameModel.lastName))	{
			return true;
		}
		return false;
	},
	
	successNameChange: function(response) {
		Mojo.Log.info("Name change success: %o", $H(response));
	},
	
	errorNameChange: function(response) {
		Mojo.Log.error("Name change error: %o", $H(response));
	},
	
	validateEmail: function ( ) {
		var emailRegEx = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
		
		if(this.emailModel.emailAddress == "" || this.emailModel.emailAddress == undefined) {
			return false;
		} else {
			return (this.emailModel.emailAddress.search(emailRegEx) != -1);
		} 
	},
	
	/*validateSecurityAnswer: function ( ) {
		var securityAnswerRegEx = /^[A-Z0-9._\s%+-]$/i;
		
		if(this.answerModel.answer == "" || this.emailModel.emailAddress == undefined) {
			return false;
		} else {
			return (this.emailModel.emailAddress.search(securityAnswerRegEx) != -1);
		} 
	},*/
	
	checkEmailChange: function() {	//Function only checks for changes in e-mail field, returns bool
		if(this.myProfile.email != this.emailModel.emailAddress)	{
			return true;	
		} 
		return false;
	},
	
	successEmailChange: function(response) {
		Mojo.Log.info("Email change success: %o", $H(response));
		var confirmText = $L("Please respond to the verification email sent to #{email} from Palm_Inc@email.palmnewsletters.com. The new email address will not be updated until it has been verified.").interpolate({
					email: this.myProfile.email
		});
		
		this.controller.showAlertDialog({
		    title: $L("Verify new email"),
		    message: confirmText,
		    choices:[
	        	{label:$L('OK'), value:"ok", type: 'color'}    
		    ],
			onChoose: function(value) {
				if("ok" == value) {
					this.backToAccountScreen();
				}
			},
	  });
	},
	
	errorEmailChange: function(response) {
		Mojo.Log.error("Email change error: %o", $H(response));
	},
	
	checkSecurityChange: function() { //Function only checks for changes in security question+answer, returns bool
		
		if((this.selectedQuestionId != -1) && 
			((this.myProfile.selectedQuestionId != this.selectedQuestionId) || (this.newAnswer == true))) {
			return true;				
		}
		return false;
	}, 

	successSecurityChange: function(response) {
		Mojo.Log.info("successSecurityChange: %o", $H(response));
	},
	
	errorSecurityChange: function(response) {
		Mojo.Log.error("errorSecurityChange: %o", $H(response));
	},
	
	       
    hideScrim: function() {
	    this.spinning = false;
		$(this.spinner).mojo.stop();
		this.controller.get('scrim').hide();     
    },	
	
	loadWatcher: function (caller) {
		if (caller == 'loadedEmail')
		{
			this.loadedEmail = true;
		}
		else if (caller == 'loadedQuestions')
		{
			this.loadedQuestions = true;
		}
		if ((this.loadedEmail == true) && (this.loadedQuestions == true))
		{
			this.loadedEmail = false;
			this.loadedQuestions = false;
			this.hideScrim();	
		}
	}
});