define('jForumPagination', [
    'require',
    'jquery',
    'jForumUtils'
], function (require, $, util) {
    'use strict';
    
    var jForumPagination = (function () {
        class Page {
            constructor(jqDeferred, option) {
                option.page = getCurrentPageNumber();
                this.config = $.extend({ pageSize: 20, totalRecords: 0, range: 10, url: '', dataType: 'json' }, option);
                this.defer = jqDeferred;
            }
            getPage() {
                return this.config.page;
            }
            /**
                 * 计算有多少页
                 * @param {number} totalRecords - 总记录数
                 * @param {number} pageSize - 每页显示的记录数
                 * @returns 总页数
                 */
            _getTotalPage(totalRecords, pageSize) {
                var tr = totalRecords;
                var ps = pageSize;

                var tp = (tr == 0) ? -1 : 1;
                if (tr > ps) {
                    var tp = Math.floor(tr / ps);
                    if (tr % ps !== 0) {
                        tp += 1;
                    }
                }
                return tp;
            }
            /**
                 * 获取数据
                 * @param {number} page - 当前页码值
                 * @param {Object} jqEle - 当前的jQuery元素
                 */
            getData(page, jqEle) {
                var curi = this.config.url;
                var dt = this.config.dataType;
                //
                var formatAjaxParams = {
                    type: 'get',
                    cache: false,
                    data: {},
                    contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
                    dataType: dt,
                    async: true,
                    timeout: 3000
                };
                formatAjaxParams.url = curi;
                var postData = {}; var _curIns = this;
                postData.pageSize = this.config.pageSize;
                postData.pageNumber = page;
                $.extend(formatAjaxParams.data || {}, postData);
                formatAjaxParams.success = function (response) {
                    var a = _curIns._getTotalPage(response.total, response.size);
                    // 当前页
                    // a=总页数
                    var b = _curIns._calc(response.page, a);
                    _curIns.render(b.start, b.end, response.page, a, jqEle);
                    if ($.isFunction(_curIns.config.jsonCallback)) {
                        _curIns.config.jsonCallback(response.result);
                    }
                    //滚动到顶部
                    $('html, body').animate({ scrollTop: 0 }, 500);
                    _curIns.defer.resolve(response.result);
                    console.log('[pagination] scroll is top');
                };
                formatAjaxParams.error = function (jqXHR, textStatus, errorThrown) {
                    this.defer.reject(jqXHR, textStatus);
                };

                formatAjaxParams.beforeSend = function (xhr) {
                    if ($.isFunction(_curIns.config.ajaxBefore)) {
                        _curIns.config.ajaxBefore(xhr);
                    }
                    console.log('[pagination] ajax before send exec');
                };
                formatAjaxParams.complete = function (xhr, textStatus) {
                    if ($.isFunction(_curIns.config.ajaxComplete)) {
                        _curIns.config.ajaxComplete(xhr, textStatus);
                    }
                    //记入历史
                    recordHistory(page, postData.pageSize);
                    if ($.isFunction(_curIns.config.deferCallback)) {
                        _curIns.config.deferCallback();
                    }
                    console.log('[pagination] ajax is complete');
                };
                $.ajax(formatAjaxParams);
            }
            /**
                 * 绑定翻页事件
                 * @param {Object} jqEle - 当前的jQuery元素
                 */
            bindEvent(jqEle) {
                var _curIns = this;
                $('body').on('click', 'a.previous-btn,a.next-btn', function (e) {
                    e.stopPropagation();
                    var _ele = $(this);
                    //
                    var _pageNumber = _ele.parent().attr('data-num');
                    _curIns.getData(parseInt(_pageNumber), jqEle);
                    return false;
                });
                $('body').on('click', 'li[data-num]>a.page-link', function (e) {
                    var _ele = $(this);
                    var _pageNumber = _ele.parent().attr('data-num');
                    _curIns.getData(parseInt(_pageNumber), jqEle);
                });
            }
            /**
                 * 渲染HTML
                 * @param {number} rangeStart - 显示页码值显示的上界
                 * @param {number} rangeEnd - 显示页码值显示的下界
                 * @param {number} currentPage - 当前页码值
                 * @param {number} totalPage - 总页数
                 * @param {Object} jqEle - 当前的jQuery元素
                 */
            render(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.config.randerPageStruct)) {
                    this.config.randerPageStruct(T, pnSelector);
                }
            }
            /**
                 * 计算显示页码值显示的上下界
                 * @param {number} currentPage - 当前页码值
                 * @param {number} totalPage - 总页数
                 * @returns {Object}
                 */
            _calc(currentPage, totalPage) {
                var cp = this.config.range;
                var nR = Math.floor(currentPage / cp);
                if (currentPage % cp > 0) {
                    nR += 1;
                }
                var rangeEnd = nR * cp;
                if (rangeEnd > totalPage) {
                    rangeEnd = totalPage;
                }
                var rangeStart = nR * cp - cp + 1;
                return {
                    start: rangeStart,
                    end: rangeEnd
                };
            }
        }
        //无分页查询字符串返回1,有的返回其值
        function getCurrentPageNumber() {
            //固定的参数:写诗在此(Pagination)
            var pnParam = 'p';
            //当前浏览器地址栏中的查询参数
            var cuQueryString = window.location.search;
            if (cuQueryString) {
                var pn = getQueryString(pnParam, cuQueryString);
                return (util.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 (!util.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;
        };
        return Page;
    })();
    return jForumPagination;
});
