if (typeof com == 'undefined') var com = {};
if (typeof com.ahliu == 'undefined') com.ahliu = {};

com.ahliu.paginator = function(cfg) {
    this.init(cfg);
};
com.ahliu.paginator.prototype.init = function(cfg) {
    this.pageNum = (typeof cfg.pageNum == 'undefined') ? 1 : cfg.pageNum;
    this.rowPerPage = (typeof cfg.rowPerPage == 'undefined') ? 20 : cfg.rowPerPage;
    this.rppSlt = (typeof cfg.rppSlt == 'undefined') ? [1,2,3,4,10,20,30,40,50] : cfg.rppSlt;
    this.sortedBy = (typeof cfg.sortedBy == 'undefined') ? '#id' : cfg.sortedBy;
    this.sortOrder = (typeof cfg.sortOrder == 'undefined') ? 'ASC' : cfg.sortOrder;
    this.totalNum = (typeof cfg.totalNum == 'undefined') ? 0 : cfg.totalNum;
    this.pageSpan = (typeof cfg.pageSpan == 'undefined') ? 10 : cfg.pageSpan;
    this.action = (typeof cfg.action == 'undefined') ? 'javascript:void(0)' : cfg.action;
    this.lblPageNum = cfg.lblPageNum;
    this.lblNext = cfg.lblNext;
    this.lblPrev = cfg.lblPrev;
    this.lblRpp = cfg.lblRpp;
    this.pageBarStyle = (typeof cfg.pageBarStyle == 'undefined') ? '' : cfg.pageBarStyle;
    this.rppStyle = (typeof cfg.rppStyle == 'undefined') ? '' : cfg.rppStyle;
    this.sortCtn = cfg.sortCtn;
    this.sorterCls = cfg.sorterCls;
    this.scope = cfg.scope;
    this.callback = cfg.callback;
    this.callback = this.callback.createDelegate(this.scope);
    
    // Rectify
    this.rowPerPage = this.rowPerPage <= 0 ? 20 : this.rowPerPage;
    
    if (typeof cfg.applyTo != 'undefined') {
        if (typeof cfg.applyTo == 'object') {
            this.applyTo = cfg.applyTo;
        } else if (typeof cfg.applyTo == 'string') {
            this.applyTo = $(cfg.applyTo);
        }
    }
};
com.ahliu.paginator.prototype.getTotalPageNum = function() {
    try {
        return Math.ceil(this.totalNum/this.rowPerPage);
    } catch (e) { // Division by 0 ?
        return 0;
    }
};
com.ahliu.paginator.prototype.getStartIndex = function() {
    return Math.max(1, this.pageNum - this.pageSpan);
};
com.ahliu.paginator.prototype.getEndIndex = function() {
    return Math.min(this.getTotalPageNum(), this.pageNum + this.pageSpan);
};
com.ahliu.paginator.prototype.render = function() {
    var dh = Ext.DomHelper;
    this.renderPageIndex(dh);
    this.renderRowPerPageSelector(dh);
    
    if (this.sortCtn != null && this.sorterCls != null) {
        this.prepareSorters();
    }
    
    this.prepareGotoPage();
    this.prepareRowPerPage();
};
com.ahliu.paginator.prototype.prepareSorters = function() {
    var sorters = Ext.get(this.sortCtn).query('a.'+this.sorterCls);
    var len = sorters.length;
    for (var i = 0; i < len; i++) {
        Ext.get(sorters[i]).on('click', function (e) {
            var sortName = e.getTarget().name;
            if (sortName == this.sortedBy) {
                this.sortOrder = this.sortOrder == "ASC" ? "DESC" : "ASC";
            } else {
                this.sortedBy = sortName;
                this.sortOrder = e.getTarget().type == "desc" ? "DESC" : "ASC";
            }
            this.callback(this);
        }, this);
    }
};
com.ahliu.paginator.prototype.prepareGotoPage = function() {
    var a = this.getAllIndexLinks();
    var len = a.length;
    for (var i=0;i<len;i++) {
        Ext.get(a[i]).on('click', function(e) {
        	this.pageNum = e.getTarget().innerHTML;
        	this.callback(this);
        }, this);
    }
};
com.ahliu.paginator.prototype.prepareRowPerPage = function() {
	var a = this.getAllRppLinks();
	var len = a.length;
	for (var i=0;i<len;i++) {
		Ext.get(a[i]).on('click', function(e) {
			this.rowPerPage = e.getTarget().innerHTML;
			this.pageNum = 1;
			this.callback(this);
		}, this);
	}
	
	var a = this.getPrevLink();
	if (a != null) {
		Ext.get(a).on('click', function(e) {
			this.pageNum -= 1;
			this.callback(this);
		}, this);
	}
	
	var a = this.getNextLink();
    if (a != null) {
        Ext.get(a).on('click', function(e) {
            this.pageNum += 1;
            this.callback(this);
        }, this);
    }
};
com.ahliu.paginator.prototype.renderRowPerPageSelector = function(dh) {
    var layer = dh.append(this.applyTo, {tag:'div',style:this.rppStyle}, true);
    
    // Append the row per page label
    dh.append(layer.dom, {tag:'span',html:this.lblRpp});
    var bar = dh.append(layer.dom, {tag:'span'});
    
    var ctn = '|';
    var len = this.rppSlt.length;
    for (var i = 0; i < len; i++) {
        if (this.rppSlt[i] == this.rowPerPage) {
            ctn += '&nbsp;<span style="font-weight:bold">'+this.rppSlt[i]+'</span>&nbsp;|';
        } else {
            ctn += '&nbsp;<a href="'+this.action+'" class="pgt_rpp">'+this.rppSlt[i]+'</a>&nbsp;|';
        }
    }
    bar.innerHTML = ctn;
};
com.ahliu.paginator.prototype.renderPageIndex = function(dh) {
    var layer = dh.append(this.applyTo, {tag:'div',style:this.pageBarStyle}, true);
    
    var tpn = this.getTotalPageNum();
    
    // Append "prev x page"
    if (this.pageNum > this.pageSpan) {
        var prev = dh.append(layer.dom, {tag:'span',style:'margin-right:10px'});
        prev.innerHTML = '<a href="javascript:void(0)" class="pgt_prev">'+this.lblPrev+'</a>';
    }
    
    dh.append(layer.dom, {tag:'span',html:this.lblPageNum});
    
    // Init the page index paginator bar
    var bar = dh.append(layer.dom, {tag:'span'});
    var si = this.getStartIndex();
    var ei = this.getEndIndex();
    var ctn = '|';
    if (si > 1) {
        if (this.pageNum == 1) {
            ctn += '&nbsp;<span style="font-weight:bold">1</span>&nbsp;|';
        } else {
            ctn += '&nbsp;<a id="pgt_idx_1" href="'+this.action+'" class="pgt_idx">1</a>&nbsp;|';
        }
        if (si > 2) {
            ctn += '...|'
        }
    }
    for (var i = si; i <= ei; i++) {
        if (i == this.pageNum) {
            ctn += '&nbsp;<span style="font-weight:bold">'+i+'</span>&nbsp;|';
        } else {
            ctn += '&nbsp;<a id="pgt_idx_'+i+'" href="'+this.action+'" class="pgt_idx">'+i+'</a>&nbsp;|';
        }
    }
    if (ei < tpn) {
        if (ei+1 < tpn) {
            ctn += '...|';
        }
        if (tpn == this.pageNum) {
            ctn += '&nbsp;<span style="font-weight:bold">'+tpn+'</span>&nbsp;|';
        } else {
            ctn += '&nbsp;<a id="pgt_idx_'+tpn+'" href="'+this.action+'" class="pgt_idx">'+tpn+'</a>&nbsp;|';
        }
    }
    bar.innerHTML = ctn;
    
    // Append "prev x page"
    if (this.pageNum + this.pageSpan <= tpn) {
        var next = dh.append(layer.dom, {tag:'span',style:'margin-left:10px'});
        next.innerHTML = '<a href="javascript:void(0)" class="pgt_next">'+this.lblNext+'</a>';
    }
};
com.ahliu.paginator.prototype.getAllIndexLinks = function() {
    return Ext.get(this.applyTo).query('a.pgt_idx');
};
com.ahliu.paginator.prototype.getPrevLink = function() {
    return Ext.get(this.applyTo).child('a.pgt_prev');
};
com.ahliu.paginator.prototype.getNextLink = function() {
    return Ext.get(this.applyTo).child('a.pgt_next');
};
com.ahliu.paginator.prototype.getAllRppLinks = function() {
    return Ext.get(this.applyTo).query('a.pgt_rpp');
};

var Paginator = com.ahliu.paginator;