/**
 * Plugin for adding a close context menu to tabs. Note that the menu respects
 * the closable configuration on the tab. As such, commands like remove others
 * and remove all will not remove items that are not closable.
 */
Ext.define("Ext.ux.TabCloseMenu", {
	extend: "Ext.plugin.Abstract",

	alias: "plugin.tabclosemenu",

	mixins: {
		observable: "Ext.util.Observable"
	},

	/**
	 * @cfg {String} closeTabText
	 * The text for closing the current tab.
	 */
	closeTabText: "Close Tab",

	/**
	 * @cfg {Boolean} showCloseOthers
	 * Indicates whether to show the "Close Others" option.
	 */
	showCloseOthers: true,

	/**
	 * @cfg {String} closeOthersTabsText
	 * The text for closing all tabs except the current one.
	 */
	closeOthersTabsText: "Close Other Tabs",

	/**
	 * @cfg {Boolean} showCloseAll
	 * Indicates whether to show the "Close All" option.
	 */
	showCloseAll: true,

	/**
	 * @cfg {String} closeAllTabsText
	 * The text for closing all tabs.
	 */
	closeAllTabsText: "Close All Tabs",

	/**
	 * @cfg {Array} extraItemsHead
	 * An array of additional context menu items to add to the front of the context menu.
	 */
	extraItemsHead: null,

	/**
	 * @cfg {Array} extraItemsTail
	 * An array of additional context menu items to add to the end of the context menu.
	 */
	extraItemsTail: null,

	//public
	constructor: function (config) {
		this.callParent([config]);
		this.mixins.observable.constructor.call(this, config);
	},

	init: function(tabpanel) {
		this.tabPanel = tabpanel;
		this.tabBar = tabpanel.down("tabbar");

		this.mon(this.tabPanel, {
			scope: this,
			afterlayout: this.onAfterLayout,
			single: true
		});
	},

	onAfterLayout: function() {
		this.mon(this.tabBar.el, {
			scope: this,
			contextmenu: this.onContextMenu,
			delegate: ".x-tab"
		});
	},

	destroy: function() {
		this.callParent();
		Ext.destroy(this.menu);
	},

	// private
	onContextMenu : function(event, target) {
		var me = this,
			menu = me.createMenu(),
			disableAll = true,
			disableOthers = true,
			tab = me.tabBar.getChildByElement(target),
			index = me.tabBar.items.indexOf(tab);

		me.item = me.tabPanel.getComponent(index);
		menu.child("#close").setDisabled(!me.item.closable);

		if (me.showCloseAll || me.showCloseOthers) {
			me.tabPanel.items.each(function(item) {
				if (item.closable) {
					disableAll = false;
					if (item !== me.item) {
						disableOthers = false;
						return false;
					}
				}
				return true;
			});

			if (me.showCloseAll) {
				menu.child("#closeAll").setDisabled(disableAll);
			}

			if (me.showCloseOthers) {
				menu.child("#closeOthers").setDisabled(disableOthers);
			}

			if (me.tabBar.items.length == 1) {
				menu.child("#compare").setDisabled(true);
			}
			else {
				menu.child("#compare").setDisabled(false);
			}
		}

		event.preventDefault();
		me.fireEvent("beforemenu", menu, me.item, me);

		menu.showAt(event.getXY());
	},

	createMenu: function() {
		var me = this;

		if (!me.menu) {

			var items = [{
				itemId: "close",
				text: me.closeTabText,
				scope: me,
				handler: me.onClose
			}];

			items.push({
				itemId: "toWindow",
				text: "To window",
				scope: me,
				handler: me.toWindow
			});

			items.push({
				xtype: "menuitem",
				itemId: "compare",
				text: "Compare",
				scope: me,
				menu: {
					listeners: {
						beforeshow: {
							fn: function(i_menu) {

								i_menu.removeAll(true);

								var a_tabs = me.tabPanel.items.getRange();

								var a_items = [];

								Ext.Array.each(a_tabs, function(i_tab) {


									if (i_tab != me.item) {

										var s_title = i_tab.title;

										var o_item = {
											xtype: "menuitem",
											text: s_title,
											tab: i_tab,
											handler: function (i_item) {
												Portfolio.app.fireEvent("compare", me.item, i_tab);
											}
										};

										a_items.push(o_item);
									}
								});

								i_menu.add(a_items);
							}
						}
					}
				}
			});

			if (me.showCloseAll || me.showCloseOthers) {
				items.push("-");
			}

			if (me.showCloseOthers) {
				items.push({
					itemId: "closeOthers",
					text: me.closeOthersTabsText,
					scope: me,
					handler: me.onCloseOthers
				});
			}

			if (me.showCloseAll) {
				items.push({
					itemId: "closeAll",
					text: me.closeAllTabsText,
					scope: me,
					handler: me.onCloseAll
				});
			}

			if (me.extraItemsHead) {
				items = me.extraItemsHead.concat(items);
			}

			if (me.extraItemsTail) {
				items = items.concat(me.extraItemsTail);
			}

			me.menu = Ext.create("Ext.menu.Menu", {
				items: items,
				listeners: {
					hide: me.onHideMenu,
					scope: me
				}
			});
		}

		return me.menu;
	},

	onHideMenu: function () {
		var me = this;
		me.fireEvent("aftermenu", me.menu, me);
	},

	onClose: function() {
		this.tabPanel.remove(this.item);
	},

	onCloseOthers: function() {
		this.doClose(true);
	},

	onCloseAll: function() {
		this.doClose(false);
	},

	doClose: function(excludeActive) {
		var items = [];

		this.tabPanel.items.each(function(item) {
			if (item.closable) {
				if (!excludeActive || item !== this.item) {
					items.push(item);
				}
			}
		}, this);

		Ext.suspendLayouts();
		Ext.Array.each(items, function(item) {
			this.tabPanel.remove(item);
		}, this);
		Ext.resumeLayouts(true);
	},

	toWindow: function () {

		var i_self = this;
		var i_item = i_self.item;

		Portfolio.app.fireEvent("toWindow", i_item);
	}
});
