// JScript source code
/*
    Takes a large table and splits it into paged versions
*/
jQuery.fn.paginate = function(o) {
    var cfg = {
        /* paging */
        paging: true, 										// create a paging toolbar
        pageNumber: 1,
        recordsPerPage: 0,
        totalRecords: 0,
        pageToolbarHeight: 25,
        pageToolbarClass: 'grid-page-toolbar',
        pageStartClass: 'grid-page-start',
        pagePrevClass: 'grid-page-prev',
        pageInfoClass: 'grid-page-info',
        pageInputClass: 'grid-page-input',
        pageNextClass: 'grid-page-next',
        pageEndClass: 'grid-page-end',
        pageLoadingClass: 'grid-page-loading',
        pageLoadingDoneClass: 'grid-page-loading-done',
        pageViewingRecordsInfoClass: 'grid-page-viewing-records-info'
    };
    jQuery.extend(cfg, o);
    var tbody = jQuery(this.find('tbody'));
    var headers = jQuery(tbody.find('tr:has(th)'));
    var rows = jQuery(tbody.find('tr:not(:has(th))'));
    var numRows = rows.length;
    var g = this;
    cfg.totalRecords = numRows;
    g.extend({ load: function(page, cb) {
        var newBody = jQuery('<tbody></tbody');
        var _start = (cfg.recordsPerPage * (page - 1));
        var _end = ((cfg.recordsPerPage * page) > cfg.totalRecords ? cfg.totalRecords : cfg.recordsPerPage * page);
        newBody.append(headers);
        for (var i = _start; i < _end; i++) {
            newBody.append(rows[i]);
        }
        tbody.html(newBody.html());
        if (cb) cb();
    }
    });
    g.load(1, null);
    if (cfg.paging) {

        // create a paging toolbar
        var totr = cfg.recordsPerPage > 0 ? cfg.recordsPerPage : tbody.find('tr').length;

        // total records viewing message (if we know total records)
        // total record count might not be passed in config, it's sometimes an expensive hit to the DB
        var pv;
        if (cfg.totalRecords > 0) {
            pv = jQuery('<div />')
						.addClass(cfg.pageViewingRecordsInfoClass)
						.extend({
						    updateViewInfo: function(loaded_rows, page) {
						        var _start = ((cfg.recordsPerPage * (page - 1) + 1));
						        var _end = ((_start + loaded_rows) > cfg.totalRecords ? cfg.totalRecords : _start + loaded_rows - 1);
						        this.html('Rows ' + _start + ' - ' + _end + ' of ' + cfg.totalRecords);
						        return this;
						    }
						});
            // update the "viewing x of y" record info
            pv.updateViewInfo(totr, cfg.pageNumber);
        }

        // create our paging control container
        var p = jQuery('<div />')
								.addClass(cfg.pageToolbarClass)
								.height(cfg.pageToolbarHeight)
								.extend({
								    setPage: function(p) {
								        var input = this.find('input.' + cfg.pageInputClass);
								        pload.removeClass(cfg.pageLoadingDoneClass);
								        g.load(p, function() {
								            input.val(p);
								            if (cfg.totalRecords > 0) {
								                var totr = tbody.find('tr').length;
								                pv.updateViewInfo(totr, p);
								            }
								            pload.addClass(cfg.pageLoadingDoneClass);
								        });
								        return this;
								    },
								    getPage: function() {
								        var p = Number(this.find('input.' + cfg.pageInputClass).val());
								        return p;
								    }
								});

        // start page button
        var pb1 = jQuery('<a href="#">&laquo;</a>').addClass(cfg.pageStartClass).click(function() {
            p.setPage(1);
        });

        // prev page button
        var pb2 = jQuery('<a href="#">&lt;</a>').addClass(cfg.pagePrevClass).click(function() {
            var _p = p.getPage();
            if (_p > 1) {
                _p--;
                p.setPage(_p);
            }
        });

        // next page button
        if (cfg.totalRecords > 0) {
            var totp = Math.ceil(cfg.totalRecords / totr);
        }
        var pb3 = jQuery('<a href="#">&gt;</a>').addClass(cfg.pageNextClass).click(function() {
            var _p = p.getPage(); _p++;
            if (totp) {
                if (_p <= totp) p.setPage(_p);
            } else {
                p.setPage(_p);
            }
        });

        // loading indicator
        var pload = jQuery('<div />').addClass(cfg.pageLoadingClass).addClass(cfg.pageLoadingDoneClass);

        // page field & form
        var pfld = jQuery('<input type="text" value="' + cfg.pageNumber + '"/>').addClass(cfg.pageInputClass);
        var pinfo = jQuery('<div />')
								.addClass(cfg.pageInfoClass)
								.append(pfld);
        var pform = jQuery('<form></form>').append(pinfo).submit(function() {
            var _p = parseInt(p.getPage());
            if (_p) {
                if (totp) {
                    if (_p <= totp) p.setPage(_p);
                } else if (_p > 0) {
                    p.setPage(_p);
                }
            } else {
                alert('Please Enter a Valid Page Number.');
            }
            return false;
        });

        // last page button & info (if we know total records)
        var pb4;
        if (cfg.totalRecords > 0) {
            pinfo.html('Page ' + pinfo.html() + ' of ' + totp);
            var pb4 = jQuery('<a href="#">&raquo;</a>').addClass(cfg.pageEndClass).click(function() {
                var _p = p.getPage();
                if (totp) {
                    if (_p < totp) {
                        p.setPage(totp);
                        _p++;
                    }
                }
            });
        } else {
            pinfo.html('Page ' + pinfo.html());
        }

        p.append(pb1).append(pb2).append(pform).append(pb3).append(pb4).append(pload).append(pv);
    }

    if (cfg.paging) {
        this.after(p).extend({ p: p });
    }
};
