Ext.PagingToolbarNames = Ext.extend(Ext.Toolbar, {
    pageSize: 20,
    displayMsg : 'Select Page:',
    displayOnePageMsg : 'No more pages',
    emptyMsg : 'No data to display',
    refreshText : "Refresh",
    
    paramNames : {start: 'start', limit: 'limit'},

    initComponent : function(){
        Ext.PagingToolbarNames.superclass.initComponent.call(this);
        this.cursor = 0;
        this.bind(this.store);
    },

    // private
    onRender : function(ct, position){
        Ext.PagingToolbarNames.superclass.onRender.call(this, ct, position);
        this.combo=new Ext.form.ComboBox({
			mode: 'local',
			typeAhead: false,
			lazyInit: false,
			triggerAction: 'all',
			lazyRender:true,
			forceSelection:true,
			grow: true,
			listClass: 'x-combo-list-small',
			editable: false,
			displayField:'name',
			minListWidth: 10,
			store: this.pager_store,
			listeners: {
	        	select: {
	        		fn: function (t, r, v) {
//	        			t.collapse();
		        		this.doLoad(this.pageSize*v);
	        		},
		        	scope: this
	        	}
	        }
		});
        this.label = new Ext.form.Label({
        	text: this.displayMsg
        });
        this.addField(this.label);
        this.addField(this.combo);
        //this.field.on("keydown", this.onPagingKeydown, this);
        this.addSeparator();
        this.loading = this.addButton({
            tooltip: this.refreshText,
            iconCls: "x-tbar-loading",
            handler: this.onClick.createDelegate(this, ["refresh"])
        });

        if (this.addButtons) {
        	for (var b = 0; b < this.addButtons.length; b++) {
        		this.addButton(this.addButtons[b]);
        	}
        }

        if(this.dsLoaded){
            this.onLoad.apply(this, this.dsLoaded);
        }
    },

    // private
    updateInfo : function(){
        if(this.displayEl){
            var count = this.store.getCount();
            var msg = count == 0 ?
                this.emptyMsg :
                String.format(
                    this.displayMsg,
                    this.cursor+1, this.cursor+count, this.store.getTotalCount()
                );
            this.displayEl.update(msg);
        }
    },

    // private
    onLoad : function(store, r, o){
		if(!this.rendered){
			this.dsLoaded = [store, r, o];
			return;
		}
		this.cursor = o.params ? o.params[this.paramNames.start] : 0;
		var d = this.getPageData(), ap = d.activePage, ps = d.pages;

		if (this.pager_store.data.length>0) {
		    var id=this.cursor/this.pageSize;
		    if(this.pager_store.data.items[0].json.title){
		    	id++; // page's titles start from 1 not from 0
		    	// Numbers pager
		    	//console.log(id,this.pager_store);
		    	for(var ind=0, t=this.pager_store.data.items.length; ind<t; ind++){
		    		if(parseInt(this.pager_store.data.items[ind].json.title)==id){
		    			id = ind;
		    			//console.log(id,this.pager_store.data.items[id].data.name);
		    			break;
		    		}
		    	}
		    }
		    if (typeof(this.pager_store.data.items[id]) == 'undefined') {
                id = this.pager_store.data.items.length - 1;
                if (id < 0) {
                    id = 0;
                }
		    }
			this.combo.setValue(this.pager_store.data.items[id].data.name);
		} else {
		    this.combo.clearValue();
		}
		this.combo.collapse();
		if (this.combo.store.getCount() > 0) {
	        var tm = Ext.util.TextMetrics.createInstance(this.combo.el);
	        var maxListWidth = 0;
	        for (var i = 0, len = this.combo.store.getCount(); i < len; i++){
	            var r = this.combo.store.getAt(i);
	            var displayText = r.data[this.combo.displayField];
	            var displayWidth = tm.getWidth(displayText);
	            if (displayWidth > maxListWidth) maxListWidth = displayWidth;
	        }
			this.combo.show();
			this.label.setText(this.displayMsg);
	        this.combo.setWidth(maxListWidth + 25);
		} else {
			this.combo.hide();
			this.label.setText(this.displayOnePageMsg);
		}
		this.loading.enable();
    },

    // private
    getPageData : function(){
        var total = this.store.getTotalCount();
        var activePage = Math.ceil((this.cursor+this.pageSize)/this.pageSize);
        var pages = (total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)) ;
        if (activePage > pages) {
            activePage = pages
        }
        return {
            total : total,
            activePage : activePage,
            pages : pages
        };
    },

    // private
    onLoadError : function(){
        if(!this.rendered){
            return;
        }
        this.loading.enable();
    },

    readPage : function(d){
        var v = this.field.dom.value, pageNum;
        if (!v || isNaN(pageNum = parseInt(v, 10))) {
            this.field.dom.value = d.activePage;
            return false;
        }
        return pageNum;
    },

    // private
    onPagingKeydown : function(e){
        var k = e.getKey(), d = this.getPageData(), pageNum;
        if (k == e.RETURN) {
            e.stopEvent();
            if(pageNum = this.readPage(d)){
                pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
                this.doLoad(pageNum * this.pageSize);
            }
        }else if (k == e.HOME || k == e.END){
            e.stopEvent();
            pageNum = k == e.HOME ? 1 : d.pages;
            this.field.dom.value = pageNum;
        }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
            e.stopEvent();
            if(pageNum = this.readPage(d)){
                var increment = e.shiftKey ? 10 : 1;
                if(k == e.DOWN || k == e.PAGEDOWN){
                    increment *= -1;
                }
                pageNum += increment;
                if(pageNum >= 1 & pageNum <= d.pages){
                    this.field.dom.value = pageNum;
                }
            }
        }
    },

    // private
    beforeLoad : function(){
        if(this.rendered && this.loading){
            this.loading.disable();
        }
    },

    doLoad : function(start){
        var o = {}, pn = this.paramNames,ind;
        /* */
        ind = this.combo.selectedIndex;
        ind = (ind>0)?ind:0;
        if(this.pager_store.data.items.length > 0 && this.pager_store.data.items[ind]){
        	if(this.pager_store.data.items[ind].json.blank){
        		// find diapason center
        		start = parseInt(this.pager_store.data.items[ind-1].json.title);
        		start += parseInt(this.pager_store.data.items[ind+1].json.title);
        		start = (Math.floor(start/2)-1)*this.pageSize;
        	}
        	if(this.pager_store.data.items[ind].json.title){
        		// Numbers pager
	        	start = parseInt(this.pager_store.data.items[ind].json.title);
	        	start = isNaN(start)? 0 : (start-1)*this.pageSize;
        	}
        }/* */
        
        o[pn.start] = start;
        o[pn.limit] = this.pageSize;
        this.store.load({params:o});
    },

    // private
    onClick : function(which){
        var store = this.store;
        switch(which){
            case "first":
                this.doLoad(0);
            break;
            case "prev":
                this.doLoad(Math.max(0, this.cursor-this.pageSize));
            break;
            case "next":
                this.doLoad(this.cursor+this.pageSize);
            break;
            case "last":
                var total = store.getTotalCount();
                var extra = total % this.pageSize;
                var lastStart = extra ? (total - extra) : total-this.pageSize;
                this.doLoad(lastStart);
            break;
            case "refresh":
                this.doLoad(this.cursor);
            break;
        }
    },

    /**
     * Unbinds the paging toolbar from the specified {@link Ext.data.Store}
     * @param {Ext.data.Store} store The data store to unbind
     */
    unbind : function(store){
        store = Ext.StoreMgr.lookup(store);
        store.un("beforeload", this.beforeLoad, this);
        store.un("load", this.onLoad, this);
        store.un("loadexception", this.onLoadError, this);
        this.store = undefined;
    },

    /**
     * Binds the paging toolbar to the specified {@link Ext.data.Store}
     * @param {Ext.data.Store} store The data store to bind
     */
    bind : function(store){
        store = Ext.StoreMgr.lookup(store);
        store.on("beforeload", this.beforeLoad, this);
        store.on("load", this.onLoad, this);
        store.on("loadexception", this.onLoadError, this);
        this.store = store;
    }
});
Ext.onReady(function(){
    Ext.reg('paging', Ext.PagingToolbarNames);
});
