text: 'use strict';
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.hasPrevPage = exports.hasNextPage = exports.getCurrentPage = exports.getSkipForPage = exports.getPageCount = undefined;
  
  var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
  
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  
  var _react = require('react');
  
  var _react2 = _interopRequireDefault(_react);
  
  var _propTypes = require('prop-types');
  
  var _propTypes2 = _interopRequireDefault(_propTypes);
  
  var _autoBind = require('@zippytech/react-class/autoBind');
  
  var _autoBind2 = _interopRequireDefault(_autoBind);
  
  var _NumericInput = require('../../NumericInput');
  
  var _NumericInput2 = _interopRequireDefault(_NumericInput);
  
  var _ComboBox = require('../../ComboBox');
  
  var _ComboBox2 = _interopRequireDefault(_ComboBox);
  
  var _ToolBar = require('../../ToolBar');
  
  var _ToolBar2 = _interopRequireDefault(_ToolBar);
  
  var _Separator = require('../../ToolBar/Separator');
  
  var _Separator2 = _interopRequireDefault(_Separator);
  
  var _cleanProps = require('../../common/cleanProps');
  
  var _cleanProps2 = _interopRequireDefault(_cleanProps);
  
  var _shouldComponentUpdate2 = require('../../common/shouldComponentUpdate');
  
  var _shouldComponentUpdate3 = _interopRequireDefault(_shouldComponentUpdate2);
  
  var _join = require('../../common/join');
  
  var _join2 = _interopRequireDefault(_join);
  
  var _PaginationIcon = require('./PaginationIcon');
  
  var _PaginationIcon2 = _interopRequireDefault(_PaginationIcon);
  
  var _getIcons = require('./getIcons');
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  
  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * Copyright (c) 2015-present, Zippy Technologies
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * This source code is licensed under the MIT license found in the
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * LICENSE file in the root directory of this source tree.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  */
  
  var emptyObject = {};
  
  var PAGE_SIZES = [{ value: 5 }, { value: 10 }, { value: 20 }, { value: 25 }, { value: 40 }, { value: 50 }, { value: 100 }];
  
  var ICONS = { FIRST_PAGE: _getIcons.FIRST_PAGE, LAST_PAGE: _getIcons.LAST_PAGE, PREV_PAGE: _getIcons.PREV_PAGE, NEXT_PAGE: _getIcons.NEXT_PAGE, REFRESH: _getIcons.REFRESH };
  
  var CLASS_NAME = 'zippy-react-pagination-toolbar';
  
  var SPACER = _react2.default.createElement('div', { className: CLASS_NAME + '__spacer' });
  
  var getPageCount = exports.getPageCount = function getPageCount(_ref) {
    var count = _ref.count,
        limit = _ref.limit;
    return Math.ceil(count / limit);
  };
  var getSkipForPage = exports.getSkipForPage = function getSkipForPage(_ref2) {
    var page = _ref2.page,
        limit = _ref2.limit;
    return Math.max(0, limit * (page - 1));
  };
  var getCurrentPage = exports.getCurrentPage = function getCurrentPage(_ref3) {
    var skip = _ref3.skip,
        limit = _ref3.limit;
    return Math.floor(skip / limit) + 1;
  };
  
  // it's 1 based
  var hasNextPage = exports.hasNextPage = function hasNextPage(_ref4) {
    var skip = _ref4.skip,
        limit = _ref4.limit,
        count = _ref4.count;
    return getCurrentPage({ skip: skip, limit: limit }) < getPageCount({ count: count, limit: limit });
  };
  
  var hasPrevPage = exports.hasPrevPage = function hasPrevPage(_ref5) {
    var skip = _ref5.skip,
        limit = _ref5.limit;
    return getCurrentPage({ skip: skip, limit: limit }) > 1;
  };
  
  var ZippyPaginationToolbar = function (_React$Component) {
    _inherits(ZippyPaginationToolbar, _React$Component);
  
    function ZippyPaginationToolbar(props) {
      _classCallCheck(this, ZippyPaginationToolbar);
  
      var _this = _possibleConstructorReturn(this, (ZippyPaginationToolbar.__proto__ || Object.getPrototypeOf(ZippyPaginationToolbar)).call(this, props));
  
      (0, _autoBind2.default)(_this);
  
      _this.state = { skip: props.defaultSkip, limit: props.defaultLimit };
  
      _this.ACTIONS = {
        REFRESH: _this.refresh,
        FIRST_PAGE: _this.gotoFirstPage,
        LAST_PAGE: _this.gotoLastPage,
        PREV_PAGE: _this.gotoPrevPage,
        NEXT_PAGE: _this.gotoNextPage
      };
  
      _this.refNumberInput = function (cmp) {
        _this.numberInput = cmp;
      };
      return _this;
    }
  
    _createClass(ZippyPaginationToolbar, [{
      key: 'shouldComponentUpdate',
      value: function shouldComponentUpdate(nextProps, nextState) {
        return (0, _shouldComponentUpdate3.default)(this, nextProps, nextState);
      }
    }, {
      key: 'getSkip',
      value: function getSkip() {
        var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props;
  
        return props.skip === undefined ? this.state.skip : props.skip;
      }
    }, {
      key: 'getLimit',
      value: function getLimit() {
        var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props;
  
        return props.limit === undefined ? this.state.limit : props.limit;
      }
    }, {
      key: 'render',
      value: function render() {
        var _props = this.props,
            totalCount = _props.totalCount,
            theme = _props.theme,
            remotePagination = _props.remotePagination,
            rootClassName = _props.rootClassName,
            changeButtonStyles = _props.changeButtonStyles;
  
  
        var skip = this.getSkip();
        var limit = this.getLimit();
  
        var skipLimitCount = { skip: skip, limit: limit, count: totalCount };
  
        var currentPage = getCurrentPage(skipLimitCount);
        var pageCount = getPageCount(skipLimitCount);
  
        var firstPage = this.renderIcon('FIRST_PAGE', currentPage <= 1);
        var lastPage = this.renderIcon('LAST_PAGE', currentPage >= pageCount);
        var prevPage = this.renderIcon('PREV_PAGE', !hasPrevPage(skipLimitCount));
        var nextPage = this.renderIcon('NEXT_PAGE', !hasNextPage(skipLimitCount));
  
        var refresh = remotePagination ? this.renderIcon('REFRESH', false) : null;
  
        var start = totalCount ? skip + 1 : 0;
        var end = Math.min(skip + limit, totalCount);
  
        var className = (0, _join2.default)(this.props.className, CLASS_NAME, theme && CLASS_NAME + '--theme-' + theme, this.props.bordered && CLASS_NAME + '--bordered');
  
        var combo = this.renderPageSizeCombo();
        var currentPageInput = this.renderCurrentPageInput({
          pageCount: pageCount,
          currentPage: currentPage
        });
  
        var domProps = _extends({}, (0, _cleanProps2.default)(this.props, ZippyPaginationToolbar.propTypes), {
          className: className,
          theme: theme
        });
  
        var result = void 0;
  
        if (this.props.renderToolbar) {
          result = this.props.renderToolbar(domProps, {
            gotoFirstPageIcon: firstPage,
            gotoLastPageIcon: lastPage,
            gotoPrevPageIcon: prevPage,
            gotoNextPageIcon: nextPage,
            refreshIcon: refresh,
            pageSizeCombo: combo,
            start: start,
            end: end,
            totalCount: totalCount,
            currentPageInput: currentPageInput
          });
  
          if (result !== undefined) {
            return result;
          }
        }
  
        return _react2.default.createElement(
          _ToolBar2.default,
          _extends({}, domProps, { useTransformOnScroll: false }),
          _react2.default.createElement(
            'div',
            { className: CLASS_NAME + '__region' },
            firstPage,
            prevPage,
            _react2.default.createElement(
              'span',
              { className: CLASS_NAME + '__page-text' },
              this.props.pageText
            ),
            ' ',
            currentPageInput,
            ' ',
            this.props.ofText,
            ' ',
            _react2.default.createElement(
              'span',
              {
                className: CLASS_NAME + '__page-count-text',
                style: {
                  minWidth: Math.max(('' + pageCount).length * 10, 25)
                }
              },
              ' ' + (pageCount.toLocaleString ? pageCount.toLocaleString() : pageCount)
            ),
            nextPage,
            lastPage,
            _react2.default.createElement(_Separator2.default, null),
            _react2.default.createElement(
              'span',
              { className: CLASS_NAME + '__per-page-text' },
              this.props.pageSizes === false ? null : this.props.perPageText
            ),
            ' ',
            combo,
            this.props.pageSizes !== false && refresh ? _react2.default.createElement(_Separator2.default, null) : null,
            refresh
          ),
          SPACER,
          _react2.default.createElement(
            'div',
            { className: CLASS_NAME + '__region' },
            this.props.showingText,
            ' ',
            start.toLocaleString ? start.toLocaleString() : start,
            ' -',
            ' ',
            end.toLocaleString ? end.toLocaleString() : end,
            ' ',
            this.props.ofText,
            ' ',
            totalCount.toLocaleString ? totalCount.toLocaleString() : totalCount
          )
        );
      }
    }, {
      key: 'renderCurrentPageInput',
      value: function renderCurrentPageInput(_ref6) {
        var pageCount = _ref6.pageCount,
            currentPage = _ref6.currentPage;
  
        var inputProps = {
          updateOnArrowKeys: false,
          className: CLASS_NAME + '__current-page',
          onBlur: this.onBlur,
          ref: this.refNumberInput,
          defaultValue: currentPage,
          currentPage: currentPage,
          onChange: this.onNumberInputChange,
          enableClearButton: false,
          allowFloat: false,
          allowNegative: false,
          minValue: 1,
          maxValue: pageCount,
          style: { minWidth: 70 },
          size: ('' + pageCount).length
        };
  
        var result = void 0;
  
        if (this.props.renderCurrentPageInput) {
          result = this.props.renderCurrentPageInput(inputProps);
        }
        if (result === undefined) {
          delete inputProps.currentPage;
          result = _react2.default.createElement(_NumericInput2.default, inputProps);
        }
  
        return result;
      }
    }, {
      key: 'renderPageSizeCombo',
      value: function renderPageSizeCombo() {
        var _comboProps;
  
        if (this.props.pageSizes === false) {
          return null;
        }
  
        var limit = this.getLimit();
  
        var comboProps = (_comboProps = {
          shadow: false,
          style: { minWidth: 70, width: 70 },
          className: CLASS_NAME + '__page-size-combo',
          borderRadius: 0,
          idProperty: 'value',
          displayProperty: 'value',
          value: limit,
          constrainTo: this.props.constrainTo,
          onChange: this.setPageSize,
          dataSource: this.props.pageSizes ? this.props.pageSizes.map(function (s) {
            return { value: s };
          }) : PAGE_SIZES,
          collapseOnSelect: true,
          changeValueOnNavigation: false,
          multiple: false,
          searchable: false,
          clearIcon: false
        }, _defineProperty(_comboProps, 'shadow', true), _defineProperty(_comboProps, 'showShadowOnMouseOver', true), _defineProperty(_comboProps, 'allowSelectionToggle', false), _defineProperty(_comboProps, 'highlightFirst', false), _comboProps);
  
        var result = void 0;
  
        if (this.props.renderPageSizeCombo) {
          result = this.props.renderPageSizeCombo(comboProps);
        }
  
        if (result === undefined) {
          result = _react2.default.createElement(_ComboBox2.default, _extends({}, comboProps, { relativeToViewport: true }));
        }
  
        return result;
      }
    }, {
      key: 'renderIcon',
      value: function renderIcon(name, disabled) {
        var icons = this.props.icons || ICONS;
        var icon = icons[name];
  
        var iconProps = {
          name: name,
          size: this.props.iconSize,
          icon: icon,
          disabled: disabled,
          action: this.ACTIONS[name]
        };
  
        var result = void 0;
  
        if (this.props.renderIcon) {
          result = this.props.renderIcon(iconProps);
        }
  
        if (result === undefined) {
          result = _react2.default.createElement(_PaginationIcon2.default, iconProps);
        }
  
        return result;
      }
    }, {
      key: 'UNSAFE_componentWillReceiveProps',
      value: function UNSAFE_componentWillReceiveProps(nextProps) {
        var _this2 = this;
  
        var skip = this.getSkip();
        var limit = this.getLimit();
        var pageCount = getPageCount({ count: this.props.totalCount, limit: limit });
  
        var currentPage = Math.min(pageCount, getCurrentPage({ skip: skip, limit: limit }));
  
        var nextSkip = this.getSkip(nextProps);
        var nextLimit = this.getLimit(nextProps);
        var nextPageCount = getPageCount({
          count: nextProps.totalCount,
          limit: nextLimit
        });
  
        var nextCurrentPage = Math.min(nextPageCount, getCurrentPage({ skip: nextSkip, limit: nextLimit }));
  
        this.forceUpdate(function () {
          // this is after setState in order to protect against a scenario where
          // the nextCurrentPage would be less than the current maxPage and
          // the number input would not update if doesn't yet have new props
          // so we wait for it for new props & update the input using setValue
          if (currentPage != nextCurrentPage) {
            _this2.setCurrentPageInputValue(nextCurrentPage, nextProps);
          }
        });
      }
    }, {
      key: 'setCurrentPageInputValue',
      value: function setCurrentPageInputValue(value) {
        var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.props;
  
        this.lastNotifiedSkip = getSkipForPage({
          page: value,
          limit: this.getLimit(props)
        });
  
        if (this.numberInput && typeof this.numberInput.setValue === 'function') {
          this.numberInput.setValue('' + value);
        }
      }
    }, {
      key: 'onBlur',
      value: function onBlur() {
        var currentPage = getCurrentPage({
          skip: this.getSkip(),
          limit: this.getLimit()
        });
        this.setCurrentPageInputValue(currentPage);
      }
    }, {
      key: 'onNumberInputChange',
      value: function onNumberInputChange(numericValue) {
        this.gotoPage(numericValue || 1);
      }
    }, {
      key: 'setPageSize',
      value: function setPageSize(limit) {
        var currentSkip = this.getSkip();
        var currentPage = getCurrentPage({
          skip: currentSkip,
          limit: this.getLimit()
        });
  
        var maxPage = getPageCount({ count: this.props.totalCount, limit: limit });
  
        var newPage = Math.min(currentPage, maxPage);
        var newSkip = getSkipForPage({ page: newPage, limit: limit });
  
        if (this.props.onPageSizeChange) {
          this.props.onPageSizeChange(limit);
        }
  
        if (this.props.onLimitChange) {
          this.props.onLimitChange(limit);
        }
  
        if (this.props.limit === undefined) {
          this.setState({ limit: limit });
        }
  
        if (newSkip != currentSkip && this.props.adjustSkipOnLimitChange) {
          this.gotoPage(newPage, { limit: limit });
        }
      }
    }, {
      key: 'gotoPage',
      value: function gotoPage(page) {
        var _this3 = this;
  
        var _ref7 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : emptyObject,
            _ref7$limit = _ref7.limit,
            limit = _ref7$limit === undefined ? this.getLimit() : _ref7$limit;
  
        var skip = getSkipForPage({ page: page, limit: limit });
  
        // in order to avoid page being adjusted twise by both icons click & number input onChange
        if (this.lastNotifiedSkip === skip) {
          return;
        }
  
        setTimeout(function () {
          delete _this3.lastNotifiedSkip;
        }, 50);
  
        this.lastNotifiedSkip = skip;
  
        if (this.props.onPageChange) {
          this.props.onPageChange(page);
        }
  
        if (this.props.onSkipChange) {
          this.props.onSkipChange(skip);
        }
  
        if (this.props.skip === undefined) {
          this.setCurrentPageInputValue('' + page);
          this.setState({ skip: skip });
        }
      }
    }, {
      key: 'refresh',
      value: function refresh() {
        if (this.props.onRefresh) {
          this.props.onRefresh();
        }
      }
    }, {
      key: 'gotoFirstPage',
      value: function gotoFirstPage() {
        this.gotoPage(1);
      }
    }, {
      key: 'gotoLastPage',
      value: function gotoLastPage() {
        var lastPage = getPageCount({
          count: this.props.totalCount,
          limit: this.getLimit()
        });
        this.gotoPage(lastPage);
      }
    }, {
      key: 'gotoNextPage',
      value: function gotoNextPage() {
        var nextPage = getCurrentPage({
          skip: this.getSkip(),
          limit: this.getLimit()
        }) + 1;
  
        this.gotoPage(nextPage);
      }
    }, {
      key: 'gotoPrevPage',
      value: function gotoPrevPage() {
        var prevPage = getCurrentPage({
          skip: this.getSkip(),
          limit: this.getLimit()
        }) - 1;
  
        this.gotoPage(prevPage);
      }
    }]);
  
    return ZippyPaginationToolbar;
  }(_react2.default.Component);
  
  exports.default = ZippyPaginationToolbar;
  
  
  ZippyPaginationToolbar.defaultProps = {
    adjustSkipOnLimitChange: true,
    theme: 'default',
    bordered: true,
    iconSize: 24,
    remotePagination: false,
    pageText: 'Page ',
    ofText: ' of ',
    perPageText: 'Results per page',
    showingText: 'Showing ',
    rootClassName: 'zippy-react-pagination-toolbar'
  };
  
  ZippyPaginationToolbar.propTypes = {
    adjustSkipOnLimitChange: _propTypes2.default.bool,
    bordered: _propTypes2.default.bool,
    iconSize: _propTypes2.default.number,
    pageText: _propTypes2.default.node,
    ofText: _propTypes2.default.node,
    perPageText: _propTypes2.default.node,
    showingText: _propTypes2.default.node,
    limit: _propTypes2.default.number,
    defaultLimit: _propTypes2.default.number,
    skip: _propTypes2.default.number,
    defaultSkip: _propTypes2.default.number,
    totalCount: _propTypes2.default.number,
    gotoNextPage: _propTypes2.default.func,
    gotoPrevPage: _propTypes2.default.func,
    pageSize: _propTypes2.default.number,
    currentPage: _propTypes2.default.number,
    pageCount: _propTypes2.default.number,
    onRefresh: _propTypes2.default.func,
    hasNextPage: _propTypes2.default.func,
    hasPrevPage: _propTypes2.default.func,
    gotoLastPage: _propTypes2.default.func,
    gotoFirstPage: _propTypes2.default.func,
    remotePagination: _propTypes2.default.bool,
    constrainTo: _propTypes2.default.any,
    onPageChange: _propTypes2.default.func,
    onSkipChange: _propTypes2.default.func,
    onLimitChange: _propTypes2.default.func,
    onPageSizeChange: _propTypes2.default.func,
    pageSizes: _propTypes2.default.arrayOf(_propTypes2.default.number),
    renderCurrentPageInput: _propTypes2.default.func,
    rootClassName: _propTypes2.default.string,
    renderIcon: _propTypes2.default.func,
    renderPageSizeCombo: _propTypes2.default.func,
    renderToolbar: _propTypes2.default.func,
    theme: _propTypes2.default.string
  };