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

var AccountpreferencesAssistant = Class.create({

	initialize: function(params) {
		this.accountDetails = new EmailAccount();
		this.accountDetails.id = params.id;
		this.fetchAccountDetails = false;
		this.delayActivate = true;
		this.isAccountDeleted = false;
		
		this.showNotificationChaneHandler = this.showNotificationChanged.bind(this);
		this.playSoundChangeHandler = this.playSoundOptionChanged.bind(this);
		this.chooseNotificationRingtone = this.chooseNotificationRingtone.bind(this);
	},

	setup: function() {
		this.imapServerSent = this.controller.get('imap-sent');
		this.imapServerDrafts = this.controller.get('imap-drafts');
		this.imapServerTrash = this.controller.get('imap-trash');
		

		// Want to use the rich text edit menu for the signature field
		this.controller.setupWidget(Mojo.Menu.appMenu, {richTextEditMenu: true}, {});

		EmailAccount.getAccountPreferences(this.controller, this.accountDetails.id, this.renderAccountDetails.bind(this));

		this.controller.setupWidget('account-name', this.accountNameAttributes, this.accountDetails);
		this.controller.setupWidget('edit-mail-type-selector', this.mailTypes, this.accountDetails);
		this.controller.setupWidget('edit-account-sync-lookback-selector', this.lookbacks, this.accountDetails);
		this.controller.setupWidget('edit-account-sync-fetch-selector', this.fetchOptions, this.accountDetails);
		//this.controller.setupWidget('edit-account-mail-format-selector', this.mailFormats, this.accountDetails);
		this.controller.setupWidget('edit-account-show-notification-toggle', this.notificationOptions, this.accountDetails);
		this.controller.setupWidget('sync-deleted-toggle', this.syncDeletedOptions, this.accountDetails);
		this.controller.setupWidget('sync-server-deleted-toggle', this.syncServerDeletedOptions, this.accountDetails);
		
		this.controller.setupWidget('signature', {}, this.accountDetails);
		this.controller.setupWidget('reply-to', this.replyToAttributes, this.accountDetails);
		this.controller.setupWidget('full-name', this.displayNameAttributes, this.accountDetails);

		this.deleteButtonModel = {
			buttonLabel:$L("Remove account"),
			disabled:false,
			buttonClass: "negative"
		}
		this.controller.setupWidget('delete-account-button', {type: Mojo.Widget.activityButton}, this.deleteButtonModel);

		this.controller.listen('delete-account-button', Mojo.Event.tap, this.handleDeleteAccount.bind(this));
		this.controller.listen('edit-account-button', Mojo.Event.tap, this.handleEditAccountDetails.bind(this));
		this.controller.listen('ringtone-row', Mojo.Event.tap, this.chooseNotificationRingtone);
		this.controller.listen('edit-account-show-notification-toggle', Mojo.Event.propertyChange, this.showNotificationChaneHandler);

		// Listen for taps on the IMAP Server folders
		this.controller.listen('edit-account-imap-sent', Mojo.Event.tap, this.handleChangeServerFolder.bind(this, "sent"));
		this.controller.listen('edit-account-imap-drafts', Mojo.Event.tap, this.handleChangeServerFolder.bind(this, "drafts"));
		this.controller.listen('edit-account-imap-trash', Mojo.Event.tap, this.handleChangeServerFolder.bind(this, "trash"));
	},

	activate: function() {
		var notificationAssistant = Mojo.Controller.getAppController().assistant.notificationAssistant;
		if (notificationAssistant) {
			notificationAssistant.setFilter();
		}
	},

	aboutToActivate: function(callback) {
		// Fetch account details again after returning from selecting server folders
		if (this.fetchAccountDetails) {
			this.fetchAccountDetails = false;
			EmailAccount.getAccountPreferences(this.controller, this.accountDetails.id, this.renderAccountDetails.bind(this));
			this.readyToActivateCallback = callback;
		}
		else {
			if (this.delayActivate === true) {
				this.delayActivate = false;
				this.readyToActivateCallback = callback;
			}
			else {
				callback();
			}
		}
	},

	deactivate: function() {
		if (!this.isAccountDeleted)
			this.handleSaveAccount();
	},

	handleEditAccountDetails: function() {
		this.controller.stageController.pushScene('create', { edit:true, type: "email", id:this.accountDetails.id });
	},
	
	handleChangeServerFolder: function(folder) {
		Mojo.Log.info("handleChangeServerFolder: folder =" + folder);
		
		// Do not push Select Folder scene if the folder selection is disabled
		if (this.controller.get('edit-account-imap-' + folder).hasClassName('disabled'))
			return;

		// Fetch the account details when this scene is activated again
		this.fetchAccountDetails = true;
		this.controller.stageController.pushScene('selectfolder', {folder:folder, id:this.accountDetails.id });
	},

	handleDeleteAccount: function() {
		this.controller.showAlertDialog({
			onChoose: function(value) { this.handleDeleteConfirmation(value); },
			title: $L("Remove account"),
			preventCancel: true,
			message: $L("Are you sure you want to remove this email account and all associated data from your device?"),
			choices: [
				{label: $L("Remove Email Account"), value: true,  type: 'negative'},
				{label: $L("Keep Email Account"),   value: false, type: 'color'}
			]
		});
	},

	handleDeleteConfirmation: function(value) {
		if (value !== true) {
			this.controller.get('delete-account-button').mojo.deactivate();
		} else {
			Mojo.Log.info("Account removal confirmed, continuing with request...");
			// Start the delete animation and tell the AccountsService to delete the account 
			this.controller.get('delete-account-button').mojo.activate();
			this.deleteButtonModel.buttonLabel = $L("Removing account...");
			this.deleteButtonModel.disabled = true;
			this.controller.modelChanged(this.deleteButtonModel);
			var f = function() {
				Mojo.Log.info("pop scene back to 'accountmanager' after email account is deleted");
				this.controller.stageController.popScene(); 
			}.bind(this);
			EmailAccount.deleteAccount(this.controller, this.accountDetails.id, f, f);
			this.isAccountDeleted = true;
			this.broadcastAccountDeleted(this.accountDetails.id);
		}
	},

	broadcastAccountDeleted: function(accountId) {
		var notificationAssistant = Mojo.Controller.getAppController().assistant.notificationAssistant;
		notificationAssistant.clear(accountId);

		var sceneStack = this.controller.stageController.getScenes();
		if (sceneStack) {
			var stackSize = sceneStack.size();
			for (var stackIndex = 0; stackIndex < stackSize; stackIndex++) {
				var scene = sceneStack[stackIndex];
				if (scene.assistant.accountDeletedNotification !== undefined) {
					scene.assistant.accountDeletedNotification(accountId);
				}
			}
		}
	},

	handleSaveAccount: function() {
		// If the user turned off UI notifications for this account, clear any that is currently displayed 
		if (this.accountDetails.notify === false) {
			Mojo.Controller.getAppController().assistant.notificationAssistant.clearAccount(this.accountDetails.id);
		}

		// richtextedit doesn't use data model so manually copy the signature
		var signature = this.controller.get('signature').innerHTML;
		if (signature === ServiceStrings.stringsNeededByService.defaultSignature) {
			// default signature should never be saved to the database. Different
			// for each device. 
			this.accountDetails.signature = signature = "";
		}
		if (signature.length > 0) {
			var strippedSig = signature.stripTags();
			strippedSig = strippedSig.stripScripts();
			if (strippedSig.blank()) {
				this.accountDetails.signature = AccountpreferencesAssistant.kNoSignatureByUserIndicator;
			} else if (strippedSig !== AccountpreferencesAssistant.kNoSignatureByUserIndicator) {
				this.accountDetails.signature = EmailAccount.addStylingToSig(signature);
			}
		}

		// Before saving, ensure any html in the account name is escaped so it isn't interpreted.
		if (this.accountDetails.name) {
			this.accountDetails.name = this.accountDetails.name.escapeHTML();
		}
		//TODO better error handling
		var errCallback = function(resp) { Mojo.Log.error("EmailAccount.saveAccountDetails", $H(resp).inspect()); }
		EmailAccount.saveAccountPreferences(this.controller, this.accountDetails, this.saveSuccess.bind(this), errCallback);
		// Need to restore the name back to its unescaped self after saving
		if (this.accountDetails.name) {
			this.accountDetails.name = this.accountDetails.name.unescapeHTML();
		}
	},

	handleReceiveAccountDetails: function(resp) {
		this.accountDetails.clone(resp);
		
		// Since the text field for displaying account name only does plain text, unescape the name (since we escape it before saving)
		if (this.accountDetails.name) {
			this.accountDetails.name = this.accountDetails.name.unescapeHTML();
		}
		this.accountDetails.showRingtoneButton = this.accountDetails.playSound == AccountpreferencesAssistant.kNotifyTypeRingtone;
	},
	
	showNotificationChanged: function() {
		var rowElem = this.controller.get("show_notification-row");
		if (this.accountDetails.notify) {
			rowElem.removeClassName("last");
		} else {
			rowElem.addClassName("last");
		}
		this.playSoundOptionChanged();
	},

	playSoundOptionChanged: function() {
		var rowElem = this.controller.get("sound-selector-row");
		if (this.accountDetails.playSound == AccountpreferencesAssistant.kNotifyTypeRingtone) {
			this.accountDetails.showRingtoneButton = true;
			rowElem.removeClassName("last");
			
			if (this.accountDetails.ringtoneName != undefined || !this.accountDetails.ringtoneName.blank()) {
				this.controller.get('current-ringtone').update(this.accountDetails.ringtoneName);
			}
		} else {
			this.accountDetails.showRingtoneButton = false;
			rowElem.addClassName("last");
		}

		// Update the model to show or hide the drawer
        this.controller.modelChanged(this.accountDetails);
	},
    
	chooseNotificationRingtone: function() {
    	var params = {
			actionType: "attach",
            defaultKind: 'ringtone',
			kinds: ["ringtone"],
			filePath: this.accountDetails.ringtonePath,
			actionName: $L("Done"),
	        onSelect: this.handleRingtoneSelect.bind(this)
	    };
	    Mojo.FilePicker.pickFile(params,this.controller.stageController);
	},

	handleRingtoneSelect: function(file) {
		Mojo.Log.info("AccountpreferencesAssistant.handleRingtoneSelect():  file=%j", file);
		this.accountDetails.ringtoneName = file.name;
		this.accountDetails.ringtonePath = file.fullPath;
		this.controller.get('current-ringtone').update(file.name);
	},

	saveSuccess: function() {
//		var message = $L("Preferences updated");
//		Mojo.Controller.getAppController().assistant.notificationAssistant.handleNotification({ type:"general", message:message });
	},

	handleCommand: function(event) {
		if (event.type == Mojo.Event.command) {
			Mojo.Log.info("Got command: " + event.command);
			switch (event.command) {
				case 'delete':
					this.handleDeleteAccount();
					break;

				case 'save':
					this.handleSaveAccount();
					break;

				case 'forecolor':
					MenuController.handleTextColorMenu(this);
					break;

				case Mojo.Menu.helpCmd:
					MenuController.showHelp();
					break;
			}
		}
		// Enable prefs & help menu items
		else if (event.type == Mojo.Event.commandEnable) {
			if (event.command === Mojo.Menu.helpCmd) {
				event.stopPropagation();
			} else if (event.command === 'forecolor') {
				var focusNode = this.controller.window.document.querySelector(':focus');
				if(!(focusNode && Mojo.View.isRichTextField(focusNode))) {
					event.preventDefault();
				}
				event.stopPropagation();
			}
		}
	},

	renderAccountDetails: function(resp) {
		Mojo.Log.info("renderAccountDetails: resp =" + Object.toJSON(resp));
		this.handleReceiveAccountDetails(resp);
		
		// Set the form title
		this.controller.get('page-title').update(this.accountDetails.originalLogin);
		
		// Set the title icon
		this.controller.get('title-icon').addClassName(this.accountDetails.accountDomain);
		
		// Is this a POP account?
		if (this.accountDetails.type === "POP3") {
			// Add/remove the "as items arrive" popup option. POP3 since that doesn't support
			// pushing items so remove for it and add for the others
			if (this.fetchOptions.choices[0] == this.fetchOptionsPushLabel) {
				// Remove the "as items arrive" options since pop doesn't support pushing items
				this.fetchOptions.choices.shift();
				if (this.accountDetails.syncFrequencyMins === 0)
					this.accountDetails.syncFrequencyMins = this.fetchOptions.choices[0].value;
			}

			// POP3 should never be 0 frequency (i.e., push). If it is, then set it to the default of 30 minutes.
			if (this.accountDetails.syncFrequencyMins === 0) {
				Mojo.Log.warn("POP3 account had syncFrequencyMins==0, setting to 30");
				this.accountDetails.syncFrequencyMins = 30;
			}

			// Hide the IMAP server folders
			this.controller.get('edit-account-imap-folders').hide();
		}
		else {
			// Add the "as items arrive" option
			if (this.fetchOptions.choices[0] != this.fetchOptionsPushLabel) {
				// Add the "as items arrive" options since imap & eas support pushing items
				this.fetchOptions.choices.unshift(this.fetchOptionsPushLabel);
			}
			
			// Hide the POP sync fields
			this.controller.get('edit-account-sync-pop').hide();
			
			// Is this an EAS account?
			if (this.accountDetails.type === "EAS") {
				// Hide the reply-to field
				this.controller.get('edit-account-reply-to').hide();
				// Hide the "Full Name" field
				this.controller.get('edit-account-full-name').hide();
				// Hide the IMAP server folders
				this.controller.get('edit-account-imap-folders').hide();
			}
			else {
				// Display the IMAP server folders if they exist
				this.controller.get('folders-available').hide();
				if (resp.folderListAvailable) {
					// Hide the "Not yet available" message and show the folders
					this.controller.get('folders-not-available').hide();
					this.controller.get('folders-available').show();

					if (resp.sent) {
						// Show as disabled if the account domain is gmail or aol as we can't choose 
						// sent folder for these domains. I am using the same logic that is defined in the ImapAccountDefinition.java 
						// to find out whether it allows to change the sent folder.
						this.imapServerSent.update(resp.sent);
						if (resp.accountDomain && (resp.accountDomain.toLowerCase() === 'gmail' || resp.accountDomain.toLowerCase() === 'aol'))
							this.controller.get('edit-account-imap-sent').addClassName('disabled');
					}
					if (resp.drafts) 
						this.imapServerDrafts.update(resp.drafts);
					if (resp.trash) 
						this.imapServerTrash.update(resp.trash);
						
				}
				else
				{
					// Show the "Not yet available" message and hide the folders
					this.controller.get('folders-available').hide();
					this.controller.get('folders-not-available').show();
				}
			}
		}
		
		this.accountDetails.name = EmailAccount.localizeAccountName(this.accountDetails.name);

		// Need to manually insert the signature since it doesn't use model like other widgets
		var signatureElem = this.controller.get('signature');
		var defaultSignature = ServiceStrings.stringsNeededByService.defaultSignature;
		// default signature is different for each device. Will be stubbed in if stored sig is blank
		var defaultSigStub = ServiceStrings.stringsNeededByService.defaultSignatureStub;
		if (this.accountDetails.signature && this.accountDetails.signature.length > 0) {
			var signature = this.accountDetails.signature; 
			var modelIndex = signature.indexOf(Mojo.Environment.DeviceInfo);
			var sigStubIndex = signature.indexOf(defaultSigStub);
			
			if (sigStubIndex > -1 && modelIndex < 0) {
				// takes care of case where wrong model defined
				signature = defaultSignature;
			} else if (signature.match(AccountpreferencesAssistant.kPreModelName)) {
				signature = signature.gsub(AccountpreferencesAssistant.kPreModelName, AccountpreferencesAssistant.kPreModelNameAscii);
			}
			signatureElem.innerHTML = signature;
		} else {
			signatureElem.innerHTML = defaultSignature;
		} 
		// Set and clear the "focused" class so appropriate styling can be displayed to make it look like
		// the other text widgets
		Mojo.Event.listen(signatureElem, 'focus', function() { signatureElem.addClassName('focused'); }, true);
		Mojo.Event.listen(signatureElem, 'blur', function() { signatureElem.removeClassName('focused'); }, true);

		// Setup the drawer here so that it doesn't animate once the scene is rendered
		this.controller.setupWidget('sound-toggle-drawer', {unstyled:true, property:'notify'}, this.accountDetails);
		this.controller.setupWidget('sound-selector', this.soundOptions, this.accountDetails);
		this.controller.setupWidget('ringtone-drawer', {unstyled:true, property:'showRingtoneButton'}, this.accountDetails);
		this.controller.instantiateChildWidgets(this.controller.get('drawer-container'));
		
		// Setup listeners for the property change 
		this.controller.listen('sound-selector', Mojo.Event.propertyChange, this.playSoundChangeHandler);

		// Update the UI now (this calls modelChanged)
		this.showNotificationChanged();
		
		if (this.readyToActivateCallback) {
			this.readyToActivateCallback();
			this.readyToActivateCallback = null;
		}
	},

	//
	// Attributes for all of the Mojo widgets
	//
	accountNameAttributes: {
		modelProperty: 'name',
		acceptBack: true
	},

	displayNameAttributes: {
		modelProperty: 'realName',
		hintText: $L("Enter your name"),
		acceptBack: true,
		autoCapitalization: true,
	},

	replyToAttributes: {
		modelProperty: 'replyTo',
		textReplacement: false,
		acceptBack: true
	},

	//mailFormats:  {
	//	modelProperty: 'useHTML',
	//	label: $L("Mail format"),
	//	choices: [
	//		{label: $L('HTML'), value: 1},
	//		{label: $L('Plain text'), value: 0}
	//	]
	//},
	
	notificationOptions: {
		modelProperty: "notify",
		trueValue: true,
		falseValue: false
	},
	
	lookbacks: {
        multiline: true,
		modelProperty: 'syncLookback',
		label: $L("Show email"),
		choices: [
			{label: $L('1 day'), value: 1},
			{label: $L('3 days'), value: 3},
			{label: $L('7 days'), value: 7},
			{label: $L('2 weeks'), value: 14},
			{label: $L('1 month'), value: 30},
			{label: $L('All'), value: 0}
		]
	},
	
	soundOptions: {
		multiline: true,
		modelProperty: 'playSound',
		label: $L("Alert"),
		choices: [
			{label: $L("Vibrate"), value: 2},
			{label: $L("System Sound"), value: 1},
			{label: $L("Ringtone"), value: 3},
			{label: $L("Mute"), value: 0}
		]
	},

	syncDeletedOptions: {
		modelProperty: "deleteFromServer",
		trueValue: true,
		falseValue: false
	},
	
	syncServerDeletedOptions: {
		modelProperty: "deleteAfterSync",
		trueValue: true,
		falseValue: false
	},
	
	fetchOptionsPushLabel: { label: $L('As items arrive'), value: 0, disabled: false },
	fetchOptions: {
		modelProperty: 'syncFrequencyMins',
		label: $L("Get email"),
		multiline: true, 
		choices: [
			{label: $L('5 minutes'), value: 5},
			{label: $L('10 minutes'), value: 10},
			{label: $L('15 minutes'), value: 15},
			{label: $L('30 minutes'), value: 30},
			{label: $L('1 hour'), value: 60},
			{label: $L('6 hours'), value: 360},
			{label: $L('12 hours'), value: 720},
			{label: $L('24 hours'), value: 1440},
			{label: $L('Manual'), value: 1000000}
		]
	}
});

AccountpreferencesAssistant.kNotifyTypeMute = 0;
AccountpreferencesAssistant.kNotifyTypeSystem = 1;
AccountpreferencesAssistant.kNotifyTypeVibrate = 2;
AccountpreferencesAssistant.kNotifyTypeRingtone = 3;

AccountpreferencesAssistant.kNoSignatureByUserIndicator = '<div id="no_signature" style="overflow:hidden;"></div>';
AccountpreferencesAssistant.kPreModelName = / Prē/;
AccountpreferencesAssistant.kPreModelNameAscii = " Pre";
