Ext.namespace('Zarafa.hierarchy.ui');

/**
 * @class Zarafa.hierarchy.ui.ContextMenu
 * @extends Zarafa.core.ui.menu.ConditionalMenu
 * @xtype zarafa.hierarchycontextmenu
 */
Zarafa.hierarchy.ui.ContextMenu = Ext.extend(Zarafa.core.ui.menu.ConditionalMenu, {

	/**
	 * @cfg contextNode Holds {@link Zarafa.hierarchy.ui.FolderNode foldernode} on which 'contextmenu' event has occured
	 */
	contextNode : undefined,

	/**
	 * The tree to which the {@link #contextNode} belongs to. On this tree the actual contextmenu was requested.
	 * @property
	 * @type Zarafa.hierarchy.ui.Tree
	 */
	contextTree : undefined,

	/**
	 * @constructor
	 * @param {Object} config Configuration object
	 */
	constructor : function(config)
	{
		config = config || {};

		if (config.contextNode) {
			config.contextTree = config.contextNode.getOwnerTree();
		}

		Ext.applyIf(config, {
			items : [
				this.createContextMenuItems(config)
			],
			defaults : {
				xtype: 'zarafa.conditionalitem',
				scope : this
			}
		});

		Zarafa.hierarchy.ui.ContextMenu.superclass.constructor.call(this, config);
	},

	/**
	 * Create the Action context menu items.
	 * @param {Object} config Configuration object for the {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * @return {Zarafa.core.ui.menu.ConditionalItem[]} The list of Action context menu items
	 * @private
	 *
	 * Note: All handlers are called within the scope of {@link Zarafa.hierarchy.ui.ContextMenu HierarchyContextMenu}
	 */
	createContextMenuItems : function(config)
	{
		return [{
			text : _('Open'),
			iconCls : 'icon_open',
			handler : this.onContextItemOpen,
			beforeShow : function(item, record) {
				var access = record.get('access') & Zarafa.core.mapi.Access.ACCESS_READ;
				if (!access || (record.isIPMSubTree() && !record.getMAPIStore().isDefaultStore())) {
					item.setDisabled(true);
				} else {
					item.setDisabled(false);
				}
			}
		}, {
			xtype: 'menuseparator'
		}, {
			text : _('Copy/Move Folder'),
			iconCls : 'icon_copy',
			handler : this.onContextCopyMoveFolder,
			beforeShow : function(item, record) {
				var access = record.get('access') & Zarafa.core.mapi.Access.ACCESS_READ;
				if (
                    !access ||
                    record.isIPMSubTree() ||
                    record.isTodoListFolder() ||
                    record.isRSSFolder() ||
                    record.isDefaultFolder()
                ) {
					item.setDisabled(true);
				} else {
					item.setDisabled(false);
				}
			}
		}, {
			text : _('Rename Folder'),
			iconCls : 'icon_folder_rename',
			handler : this.onContextItemRenameFolder,
			beforeShow : function(item, record) {
				var access = record.get('access') & Zarafa.core.mapi.Access.ACCESS_MODIFY;
				if (
                    !access ||
                    record.isIPMSubTree() ||
                    record.isTodoListFolder() ||
                    record.isRSSFolder() ||
                    record.isDefaultFolder() ||
                    !this.contextTree ||
                    !this.contextNode
                ) {
					item.setDisabled(true);
				} else {
					item.setDisabled(false);
				}
			}
		}, {
			text : _('New Folder'),
			iconCls : 'icon_createFolderColor',
			handler : this.onContextItemNewFolder,
			beforeShow : function(item, record) {
				var access = record.get('access') & Zarafa.core.mapi.Access.ACCESS_CREATE_HIERARCHY;
				if (!access || record.getMAPIStore().isArchiveStore() || record.isTodoListFolder()) {
					item.setDisabled(true);
				} else {
					item.setDisabled(false);
				}
			}
		}, {
			xtype: 'menuseparator'
		}, {
			text : _('Mark All Messages Read'),
			iconCls : 'icon_mark_all_read',
			handler : this.onContextItemReadFlags,
			beforeShow : function(item, record) {
				// We're not modifying the folder, but the contents. Hence we request the READ access
				var access = record.get('access') & Zarafa.core.mapi.Access.ACCESS_READ;
				if (!access || record.isIPMSubTree() ||record.isTodoListFolder()) {
					item.setDisabled(true);
				} else {
					item.setDisabled(false);
				}
			}
		}, {
			xtype: 'menuseparator'
		}, {
			text : _('Delete Folder'),
			iconCls : 'icon_folder_delete',
			handler : this.onContextItemDeleteFolder,
			beforeShow : function(item, record) {
				var access = record.get('access') & Zarafa.core.mapi.Access.ACCESS_DELETE;
				if (
                    !access ||
                    record.isIPMSubTree() ||
                    record.isDefaultFolder() ||
                    record.isTodoListFolder() ||
                    record.isRSSFolder() ||
                    record.getMAPIStore().isArchiveStore()) {
					item.setDisabled(true);
				} else {
					item.setDisabled(false);
				}
			}
		}, {
			text : _('Empty folder'),
			iconCls : 'icon_empty_trash',
			handler : this.onContextItemEmptyFolder,
			beforeShow : function(item, record) {
				// We're not modifying the folder, but the contents. Hence we request the READ access
				var access = record.get('access') & Zarafa.core.mapi.Access.ACCESS_READ;
				if (access && record.isSpecialFolder('wastebasket') || record.isSpecialFolder('junk')) {
					item.setDisabled(false);
				} else {
					item.setDisabled(true);
				}
			}
		}, {
			xtype: 'menuseparator'
		}, {
			text : _('Close store'),
			iconCls : 'icon_store_close',
			handler : this.onContextItemCloseStore,
			scope : this,
			beforeShow : function(item, record) {
				if (record.isIPMSubTree() && record.getMAPIStore().isSharedStore()) {
					item.setDisabled(false);
				} else {
					item.setDisabled(true);
				}
			}
		}, {
			text : _('Close folder'),
			iconCls : 'icon_folder_close',
			handler : this.onContextItemCloseFolder,
			scope : this,
			beforeShow : function(item, record) {
				if (!record.isIPMSubTree() && record.isSharedFolder()) {
					item.setDisabled(false);
				} else {
					item.setDisabled(true);
				}
			}
		}, {
			xtype: 'menuseparator'
		}, {
			text : _('Reload'),
			iconCls : 'icon_refresh',
			handler : this.onContextItemReload,
			scope : this,
			beforeShow : function(item, record) {
				if (record.isOwnRoot()) {
					item.setDisabled(false);
				} else {
					item.setDisabled(true);
				}
			}
		}, {
			text : _('Restore items'),
			handler : this.onContextItemRestore,
			iconCls: 'icon_restore',
			beforeShow : function(item, record) {
				if (!record.get('access') || record.isTodoListFolder()) {
					item.setDisabled(true);
				} else {
					item.setDisabled(false);
				}
			}
		}, {
			text : _('Select color'),
			iconCls : 'icon-select-color',
			beforeShow : function(item, record) {
				var folderEntryId = this.contextNode.id;
				var contextModel = this.contextTree.model;

				// Allow user to choose calendar color from every calendar node wether it belongs to
				// MultiSelectHierarchyTree or simple HierarchyTree
				if (record.isCalendarFolder()) {
					item.setDisabled(false);

					// Store the color of the chosen color scheme, so we can use it later
					// to build a icon (more precisely just a div with a background color)
					// in the context menu
					var colorScheme = contextModel.getColorScheme(folderEntryId);
					item.iconBG = colorScheme.base;
				} else {
					item.setDisabled(true);
				}
			},
			menu : this.createSelectColorSubmenu(config)
		},{
			text : _('Add to Favorites'),
			iconCls : 'icon_folder_favorites',
			hidden : true,
			beforeShow : function(item, record) {
				if(!record.isInDeletedItems()) {
					var isVisible = record.existsInFavorites();
					if(!isVisible && record.isIPMSubTree()) {
						isVisible = !record.isOwnRoot();
					}
					item.setDisabled(isVisible || record.isTodoListFolder());
				}
			},
			handler : this.onContextItemFavorites
		},{
			text : _('Remove From Favorites'),
			hidden : true,
			iconCls : 'icon_remove_favorites',
			beforeShow : function(item, record) {
				if(record.existsInFavorites()) {
					item.setDisabled(false);
				}
			},
			handler : this.onContextItemFavoritesRemove
		},{
			text : _('Properties'),
			handler : this.onContextItemProperties,
			iconCls : 'icon_openMessageOptions',
			beforeShow : function(item, record) {
				if (!record.get('access') || record.isTodoListFolder()) {
					item.setDisabled(true);
				} else {
					item.setDisabled(false);
				}
			}
		}];
	},

	/**
	 * Creates the submenu for the color select menu item
	 * Because this function is called before the parent constructor
	 * is called, the configuration properties are not yet set and
	 * we must get them from the passed configuration object
	 *
	 * @param {Object} config Configuration object for the {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * @return {Object[]} An array with configuration objects for
	 * {@link Zarafa.core.ui.menu.ConditionalItem menu items}
	 * @private
	 */
	createSelectColorSubmenu : function(config)
	{
		var items = [];
		var contextModel = config.contextTree.model;
		if ( !contextModel ){
			return items;
		}
		var colorSchemes = contextModel.colorScheme;
		var folderNodeColorTheme = config.contextNode.getFolder().colorTheme;
		Ext.each(colorSchemes, function(colorScheme){
			items.push({
				xtype: 'zarafa.conditionalitem',
				text : colorScheme.displayName,
				ctCls : folderNodeColorTheme===colorScheme.name ? 'x-menu-item-selected':'',
				iconCls : 'icon-select-color color-'+colorScheme.name,
				colorSchemeName : colorScheme.name,
				handler : this.onContextItemSelectColor.createDelegate(this),
				iconBG : colorScheme.header
			});
		}, this);

		return items;
	},

	/**
	 * Fires on selecting 'Open' menu option from {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * @private
	 */
	onContextItemOpen : function()
	{
		// Select node within tree
		if (this.contextTree) {
			this.contextTree.selectFolderInTree(this.records);
		}
		Zarafa.hierarchy.Actions.openFolder(this.records);
	},

	/**
	 * Fires on selecting 'Copy/Move Folder' menu option from {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * Opens {@link Zarafa.common.dialogs.CopyMoveContent CopyMoveContent} which copies or moves the folder in the Hierarchy
	 * @private
	 */
	onContextCopyMoveFolder : function()
	{
		Zarafa.common.Actions.openCopyMoveContent(this.records);
	},

	/**
	 * Fires on selecting 'Rename' menu option from {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * Opens editor in tree to rename node.
	 * @private
	 */
	onContextItemRenameFolder : function()
	{
		this.contextTree.startEditingNode(this.contextNode);
	},

	/**
	 * Fires on selecting 'New Folder' menu option from {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * Opens {@link Zarafa.common.dialogs.CreateFolderContent CreateFolderContent} which adds new folder to Hierarchy
	 * @private
	 */
	onContextItemNewFolder : function()
	{
		Zarafa.hierarchy.Actions.openCreateFolderContent(this.records);
	},

	/**
	 * Fires on selecting 'Delete Folder' menu option from {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * Asks user to confirm deletion of folder and if true then calls {@link Zarafa.hierarchy.data.HierarchyStore HierarchyStore}
	 * to delete folder.
	 * @private
	 */
	onContextItemDeleteFolder : function()
	{
		var isFolderDeleted = this.records.isInDeletedItems() || this.records.getMAPIStore().isPublicStore();
		var msg;

		if (isFolderDeleted) {
			msg = String.format(_('Are you sure you want to permanently delete all the items and subfolders in the "{0}" folder?'), Ext.util.Format.htmlEncode(this.records.getDisplayName()));
		} else {
			msg = String.format(_('Are you sure you want to delete the folder "{0}" and move all of its contents into the Deleted Items folder?'), Ext.util.Format.htmlEncode(this.records.getDisplayName()));
		}

		Ext.MessageBox.confirm(
			_('Kopano WebApp'),
			msg,
			function (buttonClicked) {
				if (buttonClicked == 'yes') {
					var record = this.records;

					/**
					 * If folder is exist in favorites list then remove favorites folder from favorites store.
					 */
					if (record.existsInFavorites()) {
						var favoriteRecord = record.getFavoritesFolder();
						favoriteRecord.getStore().remove(favoriteRecord);
					}

					var store = record.getStore();

					if (isFolderDeleted) {
						store.remove(record);
					} else {
						record.moveTo(container.getHierarchyStore().getDefaultFolder('wastebasket'));
					}

					store.save(record);
				}
			},
			this);
	},

	/**
	 * Fires on selecting 'Emtpy Folder' menu option from {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * Asks user to confirm deletion of all contents of selected folder and if true then calls {@link Zarafa.hierarchy.data.HierarchyStore HierarchyStore}
	 * to empty that folder.
	 * @private
	 */
	onContextItemEmptyFolder : function()
	{
		Ext.MessageBox.confirm(
			_('Kopano WebApp'),
			String.format(_('Are you sure you want to empty {0}?'), Ext.util.Format.htmlEncode(this.records.getDisplayName())),
			function (buttonClicked) {
				if (buttonClicked == 'yes') {
					this.records.emptyFolder();
					this.records.save();
				}
			},
			this);
	},

	/**
	 * Fires on selecting 'Mark All msgs as read' menu option from {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * Asks {@link Zarafa.hierarchy.data.HierarchyStore HierarchyStore} to mark all messages on the selected folder as read.
	 * @private
	 */
	onContextItemReadFlags : function()
	{
		this.records.seadReadFlags();
		this.records.save();
	},

	/**
	 * Fires when a color is selected from the {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * Saves the new color to the settings and calls doLayout on the context to re-render.
	 *
	 * @param {Zarafa.core.ui.menu.ConditionalItem} item The menu item that was clicked on
	 */
	onContextItemSelectColor : function(item)
	{
		var contextModel = this.contextTree.model;
		var folder = item.getRecords();
		var store = contextModel.getStore();

		// Find the color scheme of the chosen color
		var colorSchemeName = item.colorSchemeName;
		var colorScheme = Zarafa.core.ColorSchemes.getColorScheme(colorSchemeName);

		// And set the color scheme for this folder
		contextModel.setColorScheme(folder.get('entryid'), colorScheme);

		// Update the colors of svg icon in hierarchy tree
		var treeNodeui = this.contextNode.getUI();
		var svgIcon = treeNodeui.getEl().querySelector('svg');
		if ( svgIcon ) {
			Ext.get(svgIcon).setStyle('color', colorScheme.base);
		}

		// Now let's repaint the calendar view by sending a 'fake' load event for the store.
		if (store && store.lastOptions && !store.isExecuting('list')) {
			store.fireEvent('load', store, store.getRange(), store.lastOptions);
		}

		// Update the color of svg-icon of same folder belongs to another available HierarchyTrees
		// and favorites folder if exist
		this.updateOtherHierarchyTreeNodes(folder.get('entryid'), colorScheme.base);
	},

	/**
	 * Fires on selecting 'Properties' menu option from {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * Opens {@link Zarafa.hierarchy.dialogs.FolderPropertiesContent FolderPropertiesContent}
	 * @private
	 */
	onContextItemProperties : function()
	{
		Zarafa.hierarchy.Actions.openFolderPropertiesContent(this.records, {
			modal: true,
			showModalWithoutParent: true
		});
	},

	/**
	 * Fires on selecting "Close Store" menu option from the contextmenu. This
	 * will remove the shared store from the settings and closes the store on the server.
	 * @private
	 */
	onContextItemCloseStore : function()
	{
		var store = container.getHierarchyStore();
		var mapistore = this.records.getMAPIStore();

		store.remove(mapistore);
		store.save(mapistore);
	},

	/**
	 * Fires on selecting "Close Folder" menu option from the contextmenu. This
	 * will remove the shared folder from the settings and closes the folder on the server.
	 * @private
	 */
	onContextItemCloseFolder : function()
	{
		var mapistore = this.records.getMAPIStore();
		var folderstore = mapistore.getFolderStore();

		folderstore.remove(this.records);
		folderstore.save(this.records);
	},

	/**
	 * Fires on selecting 'Reload' menu option from {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * Reloads {@link Zarafa.hierarchy.data.HierarchyStore HierarchyStore} and populates new data in {@link Zarafa.hierarchy.ui.Tree Tree}.
	 * @private
	 */
	onContextItemReload : function()
	{
		container.getHierarchyStore().reload();
	},

	/**
	 * Open Restore dialog for restoring previously deleted items.
	 * @private
	 */
	onContextItemRestore : function()
	{
		Zarafa.common.Actions.openRestoreContent(this.records);
	},

	/**
	 * Event handler triggers when 'Add to Favorites' menu option from {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * Add to Favorites mark as Favorites to selected {@link Zarafa.hierarchy.data.MAPIFolderRecord folder}.
	 */
	onContextItemFavorites : function()
	{
		// Fixme : Rather to create copy of record, create phantom link message and use it.
		var copyRecord = this.records.copy();
		var shadowStore = container.getShadowStore();
		copyRecord.phantom = true;
		shadowStore.add(copyRecord);
		copyRecord.addToFavorites();
		shadowStore.save(copyRecord);
		copyRecord.phantom = false;
		shadowStore.remove(copyRecord, true);
	},

	/**
	 * Event handler triggers when 'Remove From Favorites' menu option from {@link Zarafa.hierarchy.ui.ContextMenu ContextMenu}
	 * Remove From Favorites menu option unmark selected {@link Zarafa.hierarchy.data.MAPIFolderRecord folder} from Favorite list .
	 */
	onContextItemFavoritesRemove : function()
	{
		var record = this.records;
		if(record.existsInFavorites()) {
			record = record.getFavoritesFolder();
			var store = record.getStore();
			store.remove(record);
			record.removeFromFavorites();
			store.save(record);
		}
	},

	/**
	 * Helper function to get all the available {@link Zarafa.hierarchy.ui.Tree tree} and update
	 * icon of respective folder with newly selected color.
	 * @param {String} folderEntryid The entryid of the selected folder
	 * @param {String} colorSchemeBase The chosen color
	 * @private
	 */
	updateOtherHierarchyTreeNodes : function(folderEntryid, colorSchemeBase)
	{
		var navigationBar = container.getNavigationBar();
		var centerPanel = navigationBar.centerPanel;
		var allFoldersPanel = centerPanel.allFoldersPanel;
		var multiSelectTree = centerPanel.multiSelectHierarchyTree;
		var allFoldersTree = allFoldersPanel.allFoldersHierarchyTree;

		this.setSvgIconColor(this.contextTree, "favorites-" + folderEntryid, colorSchemeBase);
		this.setSvgIconColor(allFoldersTree, folderEntryid, colorSchemeBase);
		this.setSvgIconColor(allFoldersTree, "favorites-" + folderEntryid, colorSchemeBase);
		this.setSvgIconColor(multiSelectTree, folderEntryid, colorSchemeBase);
	},

	/**
	 * Helper function to find node based on supplied entryid from {@link Zarafa.hierarchy.ui.Tree tree}
	 * and set the style of particular node with supplied color.
	 * @param {Zarafa.hierarchy.ui.Tree} hierarchyTree The tree in which node needs to be searched
	 * @param {String} folderEntryid The entryid of the selected folder
	 * @param {String} colorSchemeBase The chosen color
	 * @private
	 */
	setSvgIconColor : function(hierarchyTree, folderEntryid, colorSchemeBase)
	{
		var respectiveNode = hierarchyTree.getNodeById(folderEntryid);
		if (respectiveNode) {
			var respectiveNodeSvg = respectiveNode.getUI().iconNode;
			Ext.get(respectiveNodeSvg).setStyle('color', colorSchemeBase);
		}
	}
});

Ext.reg('zarafa.hierarchycontextmenu', Zarafa.hierarchy.ui.ContextMenu);