
Ext.define("Ext.ux.toolbar.ExtendedPaging", {

	extend: "Ext.toolbar.Paging",

	alias: "widget.extendedpagingtoolbar",

	mixins: {
		componentController: "Ext.ux.util.ComponentController"
	},

	refs: [
		{
			ref: "searchField",
			selector: "#searchfield"
		},
		{
			ref: "searchButton",
			selector: "#searchbutton"
		},
		{
			ref: "pagesizeCombo",
			selector: "#pagesizecombo"
		},
		{
			ref: "refreshButton",
			selector: "#refresh"
		},
		{
			ref: "pagePrev",
			selector: "#prev"
		},
		{
			ref: "pageNext",
			selector: "#next"
		},
		{
			ref: "pageFirst",
			selector: "#first"
		},
		{
			ref: "pageLast",
			selector: "#last"
		}
	],

	/**
	 * @cfg {Boolean} [pageSizeEdit=true]
	 */
	pageSizeEdit: true,
	/**
	 * @cfg {Boolean} [pageSearch=true]
	 */
	pageSearch: true,
	/**
	 * @cfg {Boolean} [inputItemTrigger=true]
	 */
	inputItemTrigger: true,
	/**
	 * @cfg {Number} [pageSearchWidth=100]
	 */
	pageSearchWidth: 100,
	/**
	 * @cfg {String/Object} [pageSearchEmptyText="i18n"]
	 */
	pageSearchEmptyText: "",
	/**
	 * @cfg {String} [pageSearchParam="query"]
	 */
	pageSearchParam: "query",

	onBeforeRefresh: null,
	onAfterRefresh: null,
	onPageRefresh: null,

	/**
	     * @cfg {Boolean} displayInfo
	     * true to display the displayMsg
	     */

	/**
	     * @cfg {Boolean} prependButtons
	     * true to insert any configured items _before_ the paging buttons.
	     */

	/**
	     * @cfg {String} displayMsg
	     * The paging status message to display. Note that this string is
	     * formatted using the braced numbers {0}-{2} as tokens that are replaced by the values for start, end and total
	     * respectively. These tokens should be preserved when overriding this string if showing those values is desired.
	     */

	/**
	     * @cfg {String} emptyMsg
	     * The message to display when no records are found.
	     */

	/**
	     * @cfg {String} beforePageText
	     * The text displayed before the input item.
	     */

	/**
	     * @cfg {String} afterPageText
	     * Customizable piece of the default paging text. Note that this string is formatted using
	     * {0} as a token that is replaced by the number of total pages. This token should be preserved when overriding this
	     * string if showing the total page count is desired.
	     */

	/**
	     * @cfg {String} firstText
	     * The quicktip text displayed for the first page button.
	     * **Note**: quick tips must be initialized for the quicktip to show.
	     */

	/**
	     * @cfg {String} prevText
	     * The quicktip text displayed for the previous page button.
	     * **Note**: quick tips must be initialized for the quicktip to show.
	     */

	/**
	     * @cfg {String} nextText
	     * The quicktip text displayed for the next page button.
	     * **Note**: quick tips must be initialized for the quicktip to show.
	     */

	/**
	     * @cfg {String} lastText
	     * The quicktip text displayed for the last page button.
	     * **Note**: quick tips must be initialized for the quicktip to show.
	     */

	/**
	     * @cfg {String} refreshText
	     * The quicktip text displayed for the Refresh button.
	     * **Note**: quick tips must be initialized for the quicktip to show.
	     */

	/**
	     * @cfg {Number} inputItemWidth
	     * The width in pixels of the input field used to display and change the current page number.
	     */

	/**
	 * @private
	 */
	_currentPage: 1,

	_storeInitialized: false,

	/**
	 * Gets the standard paging items in the toolbar
	 * @private
	 */
	getPagingItems: function() {

		var i_cmp = this;
		var i_store = i_cmp.store;
		var a_items = [];
		var o_initial = i_cmp.initialConfig;
		var b_pageSizeEdit = o_initial.pageSizeEdit || i_cmp.pageSizeEdit;
		var b_pageSearch = o_initial.pageSearch || i_cmp.pageSearch;

		Ext.apply(i_cmp, {
			pageSearchEmptyText: o_initial.pageSearchEmptyText || ip2.i18n({
				da: "Søg...",
				en: "Search..."
			})
		});

		// Back, first etc..
		a_items.push(
			{
				xtype: "button",
				itemId: "first",
				iconCls: "pf-previous",
				tooltip: i_cmp.firstText,
				overflowText: i_cmp.firstText,
				disabled: true,
				handler: i_cmp.moveFirst,
				scope: i_cmp
			},
			{
				xtype: "button",
				itemId: "prev",
				iconCls: "pf-arrow-left",
				tooltip: i_cmp.prevText,
				overflowText: i_cmp.prevText,
				disabled: true,
				handler: i_cmp.movePrevious,
				scope: i_cmp
			},
			{
				xtype: "tbspacer",
				itemId: "firstSpacer"
			},
			{
				xtype: "tbtext",
				itemId: "beforeTextItem",
				text: i_cmp.beforePageText
			},
			{
				xtype: "numberfield",
				itemId: "inputItem",
				name: "inputItem",
				allowDecimals: false,
				minValue: 1,
				hideTrigger: !i_cmp.inputItemTrigger,
				enableKeyEvents: true,
				selectOnFocus: true,
				submitValue: false,
				width: i_cmp.inputItemTrigger ? i_cmp.inputItemWidth + 15 : i_cmp.inputItemWidth,
				margins: "-1 2 3 2",
				isFormField: false,
				listeners: {
					scope: i_cmp,
					keydown: i_cmp.onPagingKeyDown,
					change: i_cmp.onPagingTrigger,
					blur: i_cmp.onPagingBlur
				}
			},
			{
				xtype: "tbtext",
				itemId: "afterTextItem",
				text: Ext.String.format(i_cmp.afterPageText, 1)
			},
			{
				xtype: "tbspacer",
				itemId: "lastSpacer"
			},
			{
				xtype: "button",
				itemId: "next",
				iconCls: "pf-arrow-right",
				tooltip: i_cmp.nextText,
				overflowText: i_cmp.nextText,
				handler: i_cmp.moveNext,
				scope: i_cmp
			},
			{
				xtype: "button",
				itemId: "last",
				iconCls: "pf-next",
				tooltip: i_cmp.lastText,
				overflowText: i_cmp.lastText,
				handler: i_cmp.moveLast,
				scope: i_cmp
			}
		);

		// Unless pageLimitEdit is configured to false add combo
		if (b_pageSizeEdit) {

			var a_values = [10, 20, 30, 40, 50, 100];

			if (Ext.Array.indexOf(a_values, i_store.pageSize) == -1) {
				a_values.push(i_store.pageSize);
				Ext.Array.sort(a_values, function (a, b) {
					return a > b;
				});
			}

			a_items.push(
				{
					xtype: "tbspacer",
					hidden: !b_pageSizeEdit
				},
				{
					xtype: "tbtext",
					itemId: "pagesizecombolabel",
					hidden: !b_pageSizeEdit,
					text: ip2.i18n({
						da: "Vis",
						en: "Show"
					})
				},
				{
					xtype: "combobox",
					itemId: "pagesizecombo",
					hidden: !b_pageSizeEdit,
					maskRe: /[0-9]/g,
					isFormField: false,
					size: 5,
					value: i_store.pageSize,
					store: a_values,
					scope: i_cmp
				}
			);
		}

		if (b_pageSearch) {
			// Add the search field and search button
			a_items.push([
				"-",
				{
					xtype: "textfield",
					itemId: "searchfield",
					enableKeyEvents: true,
					isFormField: false,
					emptyText: i_cmp.pageSearchEmptyText,
					width: i_cmp.pageSearchWidth
				},
				{
					xtype: "button",
					itemId: "searchbutton",
					disabled: true,
					iconCls: "pf-magnifying_glass"
				}
			]);
		}

		// Add the refresh button
		a_items = Ext.Array.merge(a_items, [
			{
				xtype: "tbspacer",
				itemId: "refreshSpacer"
			},
			{
				xtype: "button",
				itemId: "refresh",
				iconCls: "pf-refresh",
				text: o_initial.refreshText || i_cmp.refreshText,
				tooltip: o_initial.refreshText || i_cmp.refreshText,
				overflowText: o_initial.refreshText || i_cmp.refreshText,
				preventDefault: true,
				handler: i_cmp.onRefreshButton,
				scope: i_cmp
			}
		]);

		return a_items;
	},

	initComponent: function () {

		var i_cmp = this;

		i_cmp.callParent(arguments);

		i_cmp.initComponentController();

		i_cmp.addControls();

		return i_cmp;
	},

	addControls: function () {

		var i_cmp = this;

		i_cmp.on({
			afterrender: {
				fn: function () {

					var i_store = i_cmp.getStore();
					var n_count = i_store.getCount();
					var n_total = i_store.getTotalCount();

					var a_paginationArrows = [
						i_cmp.down("#first"),
						i_cmp.down("#prev"),
						i_cmp.down("#next"),
						i_cmp.down("#last"),
						i_cmp.down("#firstSpacer"),
						i_cmp.down("#lastSpacer"),
						i_cmp.down("#refreshSpacer")
					];

					var a_paginationInput = [
						i_cmp.down("#beforeTextItem"),
						i_cmp.down("#afterTextItem"),
						i_cmp.down("#inputItem")
					];

					var n_width = i_cmp.getWidth();
					var n_min = 380;

					// If we only have 1 page to show for - no pagination
					if (n_total <= n_count) {

						n_min = 250;

						ip2.each(a_paginationInput, function (i_item) {
							i_item.hide();
						});
						ip2.each(a_paginationArrows, function (i_item) {
							i_item.hide();
						});
					}

					// pagination needed
					else {

						ip2.each(a_paginationArrows, function (i_item) {
							i_item.show();
						});

						// Will only show pagination numberfield if over 600px
						if (n_width - 220 > n_min) {
							ip2.each(a_paginationInput, function (i_item) {
								i_item.show();
							});
						}
						else {
							ip2.each(a_paginationInput, function (i_item) {
								i_item.hide();
							});
						}
					};
				},
				buffer: 100
			}
		});

		i_cmp.control({
			searchField: {
				keyup: i_cmp.onTextSearch,
				scope: i_cmp
			},
			searchButton: {
				click: i_cmp.onButtonSearch,
				scope: i_cmp
			},
			pagesizeCombo: {
				change: i_cmp.onPageSizeChange,
				scope: i_cmp
			},
			pagePrev: {
				click: i_cmp.onPageRefresh,
				scope: i_cmp
			},
			pageNext: {
				click: i_cmp.onPageRefresh,
				scope: i_cmp
			},
			pageFirst: {
				click: i_cmp.onPageRefresh,
				scope: i_cmp
			},
			pageLast: {
				click: i_cmp.onPageRefresh,
				scope: i_cmp
			}
		});

		return i_cmp;
	},

	getStore: function () {

		return this.store;
	},

	onPagingTrigger: function () {

		var i_cmp = this;
		var o_data = i_cmp.getPageData();
		var n_page = i_cmp.readPageFromInput(o_data);

		if (n_page != false) {
			n_page = Math.min(Math.max(1, n_page), o_data.pageCount);
			if (n_page != o_data.currentPage) {
				if (i_cmp.fireEvent("beforechange", i_cmp, n_page) !== false) {
					if (Ext.isNumber(n_page)) {
						i_cmp.store.loadPage(n_page);
					}
				}
			}
		}
	},

	performSearch: function (value) {

		var i_cmp = this;
		var s_queryParam = i_cmp.pageSearchParam;
		var i_field = i_cmp.getSearchField();
		var s_query = value || i_field.getValue();
		var i_store = i_cmp.store;
		var o_data = i_cmp.getPageData();

		i_cmp._currentPage = i_cmp.readPageFromInput(o_data);

		if (s_query) {
			i_store.proxy.extraParams[s_queryParam] = s_query;
		}
		else {
			delete i_store.proxy.extraParams[s_queryParam];
		}

		i_cmp.doRefresh();

		return i_cmp;
	},

	onButtonSearch: function () {

		var i_cmp = this;

		i_cmp.performSearch();

		i_cmp.store.loadPage(1);

		return i_cmp;
	},
	onTextSearch: function (i_self, event) {

		var i_cmp = this;
		var s_queryParam = i_cmp.pageSearchParam;
		var i_button = i_cmp.getSearchButton();
		var i_field = i_cmp.getSearchField();
		var s_value = i_field.getValue();
		var i_store = i_cmp.store;
		var s_query = i_store.proxy.extraParams[s_queryParam];

		if (!s_value) {
			i_button.disable();
			if (s_query) {
				delete i_store.proxy.extraParams[s_queryParam];
				i_cmp.store.loadPage(i_cmp._currentPage);
			}
		}
		else {

			if (event.browserEvent.keyIdentifier == "Enter") {
				i_cmp.onButtonSearch();
			}

			i_button.enable();
		}

		return i_cmp;
	},

	onPageSizeChange: function (i_self, n_value) {
		var i_cmp = this,
			i_store = i_cmp.store;

		i_store.pageSize = n_value;
		i_store.proxy.extraParams.limit = n_value;

		i_cmp.store.loadPage(1);
	},
	onPageRefresh: function () {

		var i_cmp = this;
		var i_store = i_cmp.getStore();

		i_store.on({
			load: {
				fn: function () {
					i_cmp.fireEvent("afterfresh", i_cmp);
					i_cmp.onAfterRefresh && i_cmp.onAfterRefresh(i_cmp);
				},
				single: true
			}
		});

		i_cmp.fireEvent("beforerefresh", i_cmp);
		i_cmp.onBeforeRefresh && i_cmp.onBeforeRefresh(i_cmp);

		i_cmp.fireEvent("refresh", i_cmp);
	},
	doRefresh: function() {

		var i_cmp = this;
		var i_store = i_cmp.store;
		var n_current = i_store.currentPage;

		i_cmp.onPageRefresh();

		if (i_cmp.fireEvent("beforechange", i_cmp, n_current) !== false) {
			i_cmp.store.loadPage(n_current);
		}
	},
	onRefreshButton: function () {

		var i_cmp = this;
		var i_searchField = i_cmp.getSearchField();
		var i_searchButton = i_cmp.getSearchButton();

		if (i_searchField && i_searchField.getValue()) {
			i_cmp.performSearch();
		}
		else {
			i_cmp.doRefresh();
		}
	}
});
