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

var AccountmanagerAssistant = Class.create({
	initialize: function() {
		this.accountsRequest = null;
		this.accountList = {};
		this.defaultAccountList = [];
		this.currentDefaultAccount = null;
	},

	activate: function() {
		this.delayActivate = false;
		// Clear the notification filters so user will get notified when any email comes in
		var notificationAssistant = Mojo.Controller.getAppController().assistant.notificationAssistant;
		notificationAssistant.setFilter();
		this.enableAddAccount();
		if (this.pushWizardSceneOnActivate === true) {
			this.pushWizardSceneOnActivate = false;
			this.controller.stageController.pushScene('wizard',{
					edit: false,
					type: "email",
					aboutToActivateCallback: this.needToDelay
				});
		}
	},

	aboutToActivate: function(callback) {
		if (this.delayActivate === true) {
			this.readyToActivateCallback = callback;
		} else {
			callback();
		}
	},

	needToDelay: function(delay) {
		this.delayActivate = delay
	},

	setup: function() {
		this.delayActivate = true;
		this.accountsListElement = this.controller.get('accounts_list');
		this.defaultAccountElement = this.controller.get('account-manager-default-account');
		this.mainElement = this.controller.get('main');
		this.accountsErrorCount = 0;
		this.accountsRequest = EmailAccount.subscribeAccounts(this.renderAccounts.bind(this), this.accountsError.bind(this));
		this.accountModel = {
			listTitle: $L('Accounts'),
			items: []
		};
		
		this.smartFolderPrefs = {
			allinboxes: { id: -1, value: false },
			allflagged: { id: -1, value: false },
			allunread:  { id: -1, value: false }
		}

		var smartFolderAttributes = {
			modelProperty: "value",
			trueValue: true,
			falseValue: false
		};
		this.controller.setupWidget('prefs-show-allinboxes-toggle', smartFolderAttributes, this.smartFolderPrefs.allinboxes);
		this.controller.setupWidget('prefs-show-allflagged-toggle', smartFolderAttributes, this.smartFolderPrefs.allflagged);
		this.controller.listen('prefs-show-allinboxes-toggle', Mojo.Event.propertyChange, this.toggleAddFavoriteFolder.bind(this));
		this.controller.listen('prefs-show-allflagged-toggle', Mojo.Event.propertyChange, this.toggleAddFavoriteFolder.bind(this));

		Folder.getSmartFolders(this.controller, this.smartFolders.bind(this), this.smartFoldersError.bind(this));

		this.addButtonModel = {
			buttonLabel:$L('Add an account'),
			disabled:false
		};
		this.controller.setupWidget('add-account-button', {}, this.addButtonModel );
		
		//Spinner for Default Account.    
		this.spinnerLAttrs = {
			spinnerSize: Mojo.Widget.spinnerSmall
		};
		this.spinnerModel = {
			spinning: false
		};		
		this.controller.setupWidget('account-manager-default-account-spinner', this.spinnerLAttrs, this.spinnerModel);
		
		/* TODO MK Uncomment this when preview text preference is brought back... */
		// var previewTextToggle = {
		// 	modelProperty: 'show-preview-toggle',
		// 	choices: [
		// 		{label: $L('Yes'), value: true},
		// 		{label: $L('No'), value: false}
		// 	]
		// }
		// 
		// this.controller.setupWidget('accountmanager-show-preview-toggle', previewTextToggle, {'show-preview-toggle': true});
		
		// Setup empty accounts
		this.accountList = {
			reorderable: true,
			uniquenessProperty: 'id',
			itemTemplate: 'accountmanager/account-item',
			listTemplate: 'accountmanager/group-container'
		};

		var controller = this.controller;
		controller.setupWidget('accounts-list', this.accountList, this.accountModel);	
		controller.listen('accounts-list', Mojo.Event.listTap, this.handleSelection.bind(this));
		controller.listen('accounts-list', Mojo.Event.listReorder, this.handleReorder.bind(this));
		controller.listen('account-manager-default-account', Mojo.Event.tap, this.handleSelectDefaultAccount.bind(this));
		controller.listen('add-account-button', Mojo.Event.tap, this.handleAddAccount.bind(this));
	},
	
	handleSelectDefaultAccount: function(event) {
		
		//Do not show the pop up menu while we are waiting for the response from the service.
		if(this.spinnerModel.spinning)
			return;
			
		this.controller.popupSubmenu({ 
			placeNear:event.target, 
			items:this.defaultAccountList, 
			onChoose:this.defaultAccountChanged.bind(this)
		});
	},
	
	defaultAccountChanged: function(id) {
		// Don't do anything if this is already the default account
		if (id === undefined || this.currentDefaultAccount.id === id)
			return;

		Mojo.Log.info("====== defaultAccountChanged = " + id);
		
		var previousDefault = this.currentDefaultAccount.id;
			
		// It is going to take a while to make these service calls and get the update, so update the screen now
		this.currentDefaultAccount = this.viewableAccounts.find(function(e) { return e.id == id});
		// Render the default account		
	  	var content = Mojo.View.render({template: 'accountmanager/default-account', object: this.currentDefaultAccount});
		this.defaultAccountElement.update(content);
		
		//Show the Spinner while we are waiting for the response from the service.
		this.spinnerModel.spinning = true;
		this.controller.modelChanged(this.spinnerModel);		

		// Since we're subscribed to changes, each save will cause an updated list of accounts to be sent.
		// to make the UI behave as best as possible, first set the new default and then clear the old.
		// This way the selection won't bounce around as the two changes come back
		EmailAccount.saveAccountPreferences(this.controller, {account: id, defaultAccountFlag: true});
		EmailAccount.saveAccountPreferences(this.controller, {account: previousDefault, defaultAccountFlag: false});
	},

	cleanup: function() {
		this.accountsRequest.cancel();
		this.accountsRequest = null;
		this.accountsListElement = "";
	},

	handleSelection: function(event) {
		Mojo.Log.info("in handleSelection...");
		var id = this.getEventRowId(event);
		this.controller.stageController.pushScene('accountpreferences', { edit: true, id:id, type: "email" });
		
	},
	
	handleReorder: function(event) {
		Mojo.Log.info("moving account from ", event.fromIndex, " to ", event.toIndex);
		var list = this.accountModel.items;
		list.splice(list.indexOf(event.item), 1);
		list.splice(event.toIndex, 0, event.item);

		var accountsList = [];
		list.each(function(account) {
			accountsList.push(account.id);
		});
		EmailAccount.setAccountsOrder(this.controller, accountsList);
	},

	handleCommand: function(event) {
		if (event.type == Mojo.Event.command) {
			switch (event.command) {
				case Mojo.Menu.helpCmd:
					MenuController.showHelp();
					break;
			}
		}
		// Enable help menu item
		else if (event.type == Mojo.Event.commandEnable) {
			if (event.command === Mojo.Menu.helpCmd) {
				event.stopPropagation();
			}
		}
	},

	getEventRowId: function(event) {
		Mojo.Log.info("in getEventRowId...");
		var target = event.originalEvent.target;

		while (target && !target.hasClassName('palm-row')) {
			target = target.up();
		}

		if (target && target.hasClassName('palm-row')) {
			var idx = target.id.indexOf('_');
			if (idx && (idx > 0)) {
				var id = target.id.substring(idx + 1);
				Mojo.Log.info("Selected row with ID: " + id);
				return id;
			} else {
				target = target.up();
				Mojo.Log.warn("Failed to find row: ", target.inspect());
			}
		}
		return undefined;
	},

	smartFolders: function(resp) {
		this.smartFolderRequest = undefined; //release the reference to the request now that the response is arrived
		// All Inboxes
		this.smartFolderPrefs.allinboxes.id = resp.allinboxes.id;
		this.smartFolderPrefs.allinboxes.value = (resp.allinboxes.flags == 1);
		this.controller.modelChanged(this.smartFolderPrefs.allinboxes);
		// All Flagged
		this.smartFolderPrefs.allflagged.id = resp.allflagged.id;
		this.smartFolderPrefs.allflagged.value = (resp.allflagged.flags == 1);
		this.controller.modelChanged(this.smartFolderPrefs.allflagged);
	},

	toggleAddFavoriteFolder: function(event) {
		Folder.setFavorite(event.model.id, event.model.value)
	},

	enableAddAccount: function() {
		// Only enable the "add account" button if there are less than 16 accounts
		this.addButtonModel.disabled = (this.accountModel.items.length >= 16);
		this.controller.modelChanged(this.addButtonModel);
	},

	handleAddAccount: function() {
		if (this.accountModel.items.length < 16) {
			this.controller.stageController.pushScene('wizard', { edit: false, type: "email", aboutToActivateCallback:this.needToDelay });
		}
	},

	renderAccounts: function (accountsList) {
		// subscription succeeded so reset the failure count
		this.accountsErrorCount = 0;

		var list = accountsList.list;	  	
		// The local account should always be present
		if (accountsList.count == 0) {
			// fixed NOV-62073: push to wizard scene only when account manager
			// scene is active.  If not, set'pushWizardSceneOnActivate' to true
			// and let the wizard scene to be pushed on activate() function.
			var activeScene = this.controller.stageController.activeScene();
			if (activeScene)
				Mojo.Log.info('AccountmanagerAssistant: active scene name=%s', activeScene.sceneName);
			
			if (activeScene && activeScene.sceneName === 'accountmanager') {
				Mojo.Log.info('AccountmanagerAssistant: no accounts found, so push to wizard scene')
				this.controller.stageController.pushScene('wizard', {
					edit: false,
					type: "email",
					aboutToActivateCallback: this.needToDelay
				});
			} else {
				Mojo.Log.info('AccountmanagerAssistant: no accounts found, but wait for accountmanager to become activated in order to push wizard scene')
				this.pushWizardSceneOnActivate = true;
			}
			return;
		}

		// Remove the "All Mail" entry since it is our custom 'account'
		this.viewableAccounts = [];
		list.each(function (a) {
			//only add if it isn't already in the list
			if (EmailAccount.isNotSmartFolders(a)) {
				a.name = EmailAccount.localizeAccountName(a.name);
				//console.log("pushing "+a.name);
				this.viewableAccounts.push(a);
			}
		}.bind(this));

		if (this.viewableAccounts.length == 0) {
			Mojo.Log.error("ERROR: renderAccounts zero viewable accounts");
			return;
		}

		// Create the list of accounts from which to select the default account
		this.currentDefaultAccount = null;
		this.defaultAccountList.clear();
		for (var i = 0; i < this.viewableAccounts.length; i++) {
			this.defaultAccountList.push({
				label: this.viewableAccounts[i].name, // already localized
				secondaryIcon: 'default-account-list account-icon '+this.viewableAccounts[i].accountDomain,
				command: this.viewableAccounts[i].id,
				chosen: (this.viewableAccounts[i].defaultAccountFlag > 0 && !this.currentDefaultAccount)
			});
			// Mark the first (ond only the first) defaultAccount as being the default
			if (!this.currentDefaultAccount && this.viewableAccounts[i].defaultAccountFlag > 0)
				this.currentDefaultAccount = this.viewableAccounts[i];
		}
		
		// If none of the accounts are set as default then show the first one as being the default
		if (!this.currentDefaultAccount) {
			this.currentDefaultAccount = this.viewableAccounts[0];
			this.defaultAccountList[0].chosen = true;
		}

		// Render the default account
	  	var content = Mojo.View.render({template: 'accountmanager/default-account', object: this.currentDefaultAccount});
		this.defaultAccountElement.update(content);
		
		//Remove the Spinner now that we got the response from the service.
		this.spinnerModel.spinning = false;
		this.controller.modelChanged(this.spinnerModel);	

		this.accountModel.items = this.viewableAccounts;
		this.enableAddAccount();

		this.controller.modelChanged(this.accountModel);

		if (this.viewableAccounts.length > 1) {
			this.controller.get('account-manager-default-account-group').show();
		} else {
			this.controller.get('account-manager-default-account-group').hide();
		}

		if (this.delayActivate === true) {
			this.delayActivate = false;
			if (this.readyToActivateCallback !== undefined) {
				this.readyToActivateCallback.defer();
			}
		}
	}, 

	smartFoldersError: function(err) {
		// Nothing to do for now.
		Mojo.Log.warn("accountmanager smartFoldersError " + $H(err).inspect());
		this.smartFolderRequest = undefined; //release the reference to the request now that the response is arrived
	},

	accountsError: function(err) {
		// Try relaunching the mail service 3 times before giving up
		this.accountsErrorCount++;
		if (this.accountsErrorCount < 3) {
			Mojo.Log.warn("accountmanager accountsErrorCount=" + this.accountsErrorCount + " detail=" + $H(err).inspect());
			this.accountsRequest.cancel();
			this.accountsRequest = EmailAccount.subscribeAccounts(this.renderAccounts.bind(this), this.accountsError.bind(this));
		} else {
			Mojo.Log.error("This Is Bad: accountmanager cannot maintain accountList subscription after 3 retries " + $H(err).inspect());
		}
	}

});

