/**
 * jquery 动态分页
 * Copyright (c) 2019 xiaofanku
 * build on jQuery 3.2.1 & BootStrap v3
 * @author xiaofanku <xiaofanku@live.cn>
 * @version 0.0.1 - 20191212
 *
*/
(function($) {
    'use strict';
    var pagination = {
        /**
         * 计算有多少页
         * @param {number} totalRecords - 总记录数
         * @param {number} pageSize - 每页显示的记录数
         * @returns {Object}
         */
        getTotalPage: function(totalRecords, pageSize){
            var tp = (totalRecords == 0)?-1:1;
            if(totalRecords > pageSize){
                var tp = Math.floor(totalRecords / pageSize);
                if(totalRecords % pageSize !== 0){
                    tp+=1;
                }
            }
            return {
                pageSize : pageSize,
                pages : tp,
                records : totalRecords
            };
        },
        /**
         * 获取数据
         * @param {string} requestURI - 异步请求的地址
         * @param {string} dataType - 请求的数据类型, json|jsonp
         * @param {number} pageSize - 每页显示的记录数
         * @param {number} page - 当前页码值
         * @param {Object} jqEle - 当前的jQuery元素
         */
        getData: function(requestURI, dataType, pageSize, page, jqEle){
            var self = this; //self.disable();
            var formatAjaxParams = {
                type: 'get',
                cache: false,
                data: {},
                contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
                dataType: dataType,
                async: true,
                timeout: 3000
            };
            formatAjaxParams.url = requestURI;
            var postData = {};
                postData.pageSize = pageSize;
                postData.pageNumber = page;
            $.extend(formatAjaxParams.data || {}, postData);
            formatAjaxParams.success = function(response){
                var a = self.getTotalPage(response.total, pageSize);
                // gtx.range=页码范围
                // a.pages=总页数
                var b = self.calc(page, 10, a.pages);
                        self.render(b.start, b.end, page, a.pages, jqEle);
                if($.isFunction(self.jsonCallbackHandler)){
                        self.jsonCallbackHandler(response.result);
                }
                //滚动到顶部
                $('html, body').animate({ scrollTop: 0 }, 500);
                console.log('[pagination] scroll is top');
            };
            formatAjaxParams.error = function(jqXHR, textStatus, errorThrown){
            };
            formatAjaxParams.beforeSend = function(xhr) {
                if($.isFunction(self.ajaxBeforeHandler)){
                    self.ajaxBeforeHandler(xhr);
                }
                console.log('[pagination] ajax before send exec');
            };
            formatAjaxParams.complete = function(xhr, textStatus) {
                if($.isFunction(self.ajaxCompleteHandler)){
                    self.ajaxCompleteHandler(xhr, textStatus);
                }
                //记入历史
                recordHistory(page, pageSize);
                console.log('[pagination] ajax is complete');
            };
            $.ajax(formatAjaxParams);
        },
        /**
         * 绑定翻页事件
         * @param {Object} page - 所有的配置参数
         * @param {Object} jqEle - 当前的jQuery元素
         */
        bindEvent: function(finalConfig, jqEle){
            var self = this;
            $('body').on('click', 'a.previous-btn,a.next-btn', function(e){
                e.stopPropagation();
                //
                var _pageNumber = $(this).parent().attr('data-num');
                self.getData(finalConfig.url, finalConfig.dataType, finalConfig.pageSize, parseInt(_pageNumber), jqEle);
                return false;
            });
            $('body').on('click', 'li[data-num]', function(e){
                //
                var _pageNumber = $(this).attr('data-num');
                self.getData(finalConfig.url, finalConfig.dataType, finalConfig.pageSize, parseInt(_pageNumber), jqEle);
            });
        },
        /**
         * 渲染HTML
         * @param {number} rangeStart - 显示页码值显示的上界
         * @param {number} rangeEnd - 显示页码值显示的下界
         * @param {number} currentPage - 当前页码值
         * @param {number} totalPage - 总页数
         * @param {Object} jqEle - 当前的jQuery元素
         */
        render: function(rangeStart, rangeEnd, currentPage, totalPage, jqEle){
            if(totalPage == -1){
                return;
            }
            var pnSelector = '.page-navigation';
            var T = ''
                   +'<nav class="'+pnSelector.substring(1)+'" aria-label="Page navigation">'
                   +'  <ul class="pagination">';
            //是否显示前页
            if(currentPage > 1){
               T +='    <li class="page-item" data-num="'+ (currentPage-1) +'">'
                  +'      <a href="javascript:;" aria-label="Previous" class="previous-btn page-link">'
                  +'        <span aria-hidden="true">&laquo;</span>'
                  +'      </a>'
                  +'    </li>';
            }
            // Main loop
            for(var i = rangeStart; i <= rangeEnd; i++){
                if(i == currentPage){
                    T += '<li class="page-item active"><a href="#" class="page-link">'+ i +'<\/a><\/li>';
                }else{
                    T += '<li class="page-item" data-num="'+ i +'"><a href="javascript:;" class="page-link">'+ i +'<\/a><\/li>';
                }
            }
            //是否显示下页
            if(currentPage < totalPage){
                T +='   <li class="page-item" data-num="'+ (currentPage+1) +'">'
                   +'      <a href="#" aria-label="Next" class="next-btn page-link">'
                   +'        <span aria-hidden="true">&raquo;</span>'
                   +'      </a>'
                   +'   </li>';
            }
            T+='  </ul>'
              +'</nav>';
            jqEle.find('.page-navigation').remove();
            jqEle.append(T);
            //
            if($.isFunction(this.renderCompleteHandler)){
                this.renderCompleteHandler(T, pnSelector);
            }
        },
        /**
         * 计算显示页码值显示的上下界
         * @param {number} currentPage - 当前页码值
         * @param {number} pageRange - 页码显示的范围值
         * @param {number} totalPage - 总页数
         * @returns {Object}
         */
        calc: function(currentPage, pageRange, totalPage){
            var nR = Math.floor(currentPage / pageRange);
            if(currentPage%pageRange>0){
                nR += 1;
            }
            var rangeEnd = nR * pageRange;
            if(rangeEnd>totalPage){
                rangeEnd = totalPage;
            }
            var rangeStart = nR * pageRange - pageRange + 1;
            return {
                start : rangeStart,
                end : rangeEnd
            };
        },
        /**
         * 合成配置参数
         * @param {Object} option - 配置参数
         * @returns {Object}
         */
        init:function(option){
            var config=$.extend({pageSize:20, totalRecords:0, page:1, range:10, url: '', dataType: 'json'}, option);
            return config;
        }
    };
    $.fn.pagination = function(option) {
        option.page = getCurrentPageNumber();
        var gtx = pagination.init(option);
                  //增加外部回调函数
                  //拿到数据后的回调
                  pagination.jsonCallbackHandler = option.jsonCallback || null;
                  //ajax开始的回调,用以显示loading...
                  pagination.ajaxBeforeHandler = option.ajaxBefore || null;
                  //ajax完成后的回调,用以删除loading...
                  pagination.ajaxCompleteHandler = option.ajaxComplete || null;
                  //附加回调,在完成HTML分页元素时触发
                  pagination.renderCompleteHandler = option.randerPageStruct || null;
        var _self=this;
        // 没有总记录数
        pagination.getData(gtx.url, gtx.dataType, gtx.pageSize, gtx.page, _self);
        //绑定事件
        pagination.bindEvent(gtx, _self);
        return this;
    };
    //无分页查询字符串返回1,有的返回其值
    function getCurrentPageNumber(){
        //固定的参数:写诗在此(Pagination)
        var pnParam = 'p';
        //当前浏览器地址栏中的查询参数
        var cuQueryString = window.location.search;
        if(cuQueryString){
            var pn = getQueryString(pnParam, cuQueryString);
            return (isBlank(pn))?1:pn;
        }
        return 1;
    };
    //设置历史
    //https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
    function recordHistory(pageNumber, pageSize){
        //固定的参数:写诗在此(Pagination)
        var pnParam = 'p';
        //没有分页参数的地址
        var location = clearPageQueryNameURL();
        //加入
        if(location.indexOf('?')== -1){
            location+='?';
        }else{
            location+='&';
        }
        location+=pnParam+'='+pageNumber;
        //是否考虑页标题中加入第n页
        var pageTitle = document.title;
        var state = {'page_number': pageNumber, 'page_size': pageSize};
        window.history.pushState(state, pageTitle, location);
    };
    //清掉分页参数的地址
    function clearPageQueryNameURL(){
        //固定的参数:写诗在此(Pagination)
        //var pnParam = 'p=';
        //当前浏览器地址栏中的地址
        var cuLocation = window.location.href;
        var cuQueryString = window.location.search;
        if(cuQueryString){
            cuLocation=cuLocation.substring(0, cuLocation.indexOf('?'));
            cuQueryString = cuQueryString.replace(/[?&]p=\d+/g, '').substring(1);
            if(!isBlank(cuQueryString)){
                cuLocation+='?'+cuQueryString;
            }
        }
        return cuLocation;
    };
    /**
     * Get the value of a querystring
     * @param  {String} field The field to get the value of
     * @param  {String} url   The URL to get the value from (optional)
     * @return {String}       The field value
     */
    function getQueryString(field, url) {
        var href = url ? url : window.location.href;
        var reg = new RegExp( '[?&]' + field + '=([^&#]*)', 'i' );
        var string = reg.exec(href);
        return string ? string[1] : null;
    };
})(jQuery);
