"use strict";

exports.__esModule = true;
exports.calculateWidth = void 0;
exports.createResponsiveLayout = createResponsiveLayout;
exports.createResponsiveLayoutTemplate = createResponsiveLayoutTemplate;
exports.createStaticLayout = createStaticLayout;
exports.measureAndSetRootMinWidth = exports.getId = void 0;
var getId = exports.getId = function getId() {
  var idPrefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
  return idPrefix ? idPrefix + name : undefined;
};
var calculateWidth = totalPages => "".concat(totalPages.toString().length, "em");
exports.calculateWidth = calculateWidth;
var measureAndSetRootMinWidth = exports.measureAndSetRootMinWidth = function measureAndSetRootMinWidth(compNode, paginationMode) {
  var idPrefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
  compNode.style.minWidth = '';
  compNode.style.minHeight = '';
  var getById = id => compNode.querySelector("#".concat(getId(idPrefix, id)));
  var getMinWidth = elmnt => elmnt ? parseInt(window.getComputedStyle(elmnt).minWidth, 10) : 0;
  var getWidthWithMargins = element => {
    if (!element) {
      return 0;
    }
    var style = window.getComputedStyle(element);
    return parseInt(style.marginRight, 10) + element.offsetWidth + parseInt(style.marginLeft, 10);
  };
  var getHeightWithMargins = element => {
    if (!element) {
      return 0;
    }
    var style = window.getComputedStyle(element);
    return parseInt(style.marginBottom, 10) + element.offsetHeight + parseInt(style.marginTop, 10);
  };
  var navButtonsMinWidth = getWidthWithMargins(getById('navButtonNext')) + getWidthWithMargins(getById('navButtonPrevious')) + getWidthWithMargins(getById('navButtonFirst')) + getWidthWithMargins(getById('navButtonLast'));
  var selectionMinWidth = 0;
  var minHeight = 0;
  if (paginationMode === 'pages') {
    // means we're in "pages" pagination mode
    selectionMinWidth = getMinWidth(getById('pageStrip'));
    minHeight = Math.max(getHeightWithMargins(getById('pageStrip')), getHeightWithMargins(getById('navButtonNext')));
  } else if (paginationMode === 'input') {
    // means we're in "input" pagination mode
    selectionMinWidth = getWidthWithMargins(getById('totalPages')) + getWidthWithMargins(getById('slash')) + getWidthWithMargins(getById('pageInput'));
    minHeight = Math.max(getHeightWithMargins(getById('pageInput')), getHeightWithMargins(getById('navButtonNext')));
  } else if (paginationMode === 'compact') {
    // means we're in "compact" pagination mode
    selectionMinWidth = getWidthWithMargins(getById('totalPages')) + getWidthWithMargins(getById('slash')) + getWidthWithMargins(getById('currentPage'));
    minHeight = Math.max(getHeightWithMargins(getById('currentPage')), getHeightWithMargins(getById('navButtonNext')));
  }
  compNode.style.minWidth = navButtonsMinWidth + selectionMinWidth + 'px';
  compNode.style.minHeight = minHeight + 'px';
};
function createStaticLayout(_ref) {
  var {
    totalPages,
    currentPage,
    maxPagesToShow,
    showFirstPage,
    showLastPage
  } = _ref;
  return createLayout({
    totalPages,
    currentPage,
    lowerBound: 1,
    upperBound: totalPages,
    pageRangeCost: (a, b) => b - a + 1,
    showFirstPage,
    showLastPage,
    rewindToFirstCost: 2,
    rewindToLastCost: 2,
    budget: maxPagesToShow
  });
}
function rangeToPreRenderForResponsiveLayout(totalPages, currentPage, maxPagesToShow) {
  return [Math.max(currentPage - maxPagesToShow, 1), Math.min(currentPage + maxPagesToShow, totalPages)];
}
function createResponsiveLayoutTemplate(_ref2) {
  var {
    totalPages,
    currentPage,
    maxPagesToShow
  } = _ref2;
  var [lowerBound, upperBound] = rangeToPreRenderForResponsiveLayout(totalPages, currentPage, maxPagesToShow);
  return [1, 0, ...closedRange(lowerBound, upperBound), 0, totalPages];
}

// Takes a container with children rendered using createResponsiveLayoutTemplate,
// measures the children, and decides how many can be shown without overflowing the container.
// For measurements to work correctly the pages must not have any dynamic spacing between them
// such as justify-content: space-evenly, but they can have static spacing such as margins.
// As long as we're using flexbox with centered pages we don't need to worry about the outer
// margins of the first and last page, they will be trimmed by flexbox automatically.
// maxPagesToShow is not really taken into account, it's used to derive the range of pages
// that was pre-rendered by createResponsiveLayoutTemplate().
function createResponsiveLayout(_ref3) {
  var {
    container,
    totalPages,
    currentPage,
    maxPagesToShow,
    showFirstPage,
    showLastPage
  } = _ref3;
  var children = Array.from(container.children);
  var pages = children.slice(2, -2);
  var containerWidth = container.getBoundingClientRect().width;
  var firstRect = children[0].getBoundingClientRect();
  var lastRect = children[children.length - 1].getBoundingClientRect();
  var lowerRect = pages[0].getBoundingClientRect();
  var upperRect = pages[pages.length - 1].getBoundingClientRect();
  var rewindToFirstCost = mergeBoundingRects(firstRect, lowerRect).width - lowerRect.width;
  var rewindToLastCost = mergeBoundingRects(lastRect, upperRect).width - upperRect.width;
  var [lowerBound, upperBound] = rangeToPreRenderForResponsiveLayout(totalPages, currentPage, maxPagesToShow);
  var pageRangeCost = (a, b) => {
    var aRect = pages[a - lowerBound].getBoundingClientRect();
    var bRect = pages[b - lowerBound].getBoundingClientRect();
    return mergeBoundingRects(aRect, bRect).width;
  };
  return createLayout({
    totalPages,
    currentPage,
    lowerBound,
    upperBound,
    pageRangeCost,
    showFirstPage,
    showLastPage,
    rewindToFirstCost,
    rewindToLastCost,
    budget: containerWidth
  });
}
function createLayout(_ref4) {
  var {
    totalPages,
    currentPage,
    lowerBound,
    upperBound,
    pageRangeCost,
    showFirstPage,
    showLastPage,
    rewindToFirstCost,
    rewindToLastCost,
    budget
  } = _ref4;
  var prevOrLowerBound = Math.max(currentPage - 1, lowerBound);
  var nextOrUpperBound = Math.min(currentPage + 1, upperBound);
  var expand = (low, high, showRewindToFirst, showRewindToLast) => createLayoutByExpandingPageRange({
    totalPages,
    low,
    high,
    lowerBound,
    upperBound,
    pageRangeCost,
    budget,
    showRewindToFirst,
    showRewindToLast,
    rewindToFirstCost,
    rewindToLastCost
  });
  return (
    // Try to show the entire range.
    (lowerBound === 1 || !showFirstPage) && (upperBound === totalPages || !showLastPage) && expand(lowerBound, upperBound, false, false) ||
    // Ellipsis only in the end. Show at least one page after the current.
    showLastPage && lowerBound === 1 && expand(lowerBound, nextOrUpperBound, false, true) ||
    // Ellipsis only in the beginning. Show at least one page before the current.
    showFirstPage && upperBound === totalPages && expand(prevOrLowerBound, upperBound, true, false) ||
    // Ellipses on both sides. Show at least one page before the current and one after.
    showFirstPage && showLastPage && expand(prevOrLowerBound, nextOrUpperBound, true, true) ||
    // Ellipsis only in the end. Don't try to include the next page.
    showLastPage && lowerBound === 1 && expand(lowerBound, currentPage, false, true) ||
    // Ellipsis only in the beginning. Don't try to include the previous page.
    showFirstPage && upperBound === totalPages && expand(currentPage, upperBound, true, false) ||
    // Ellipses on both sides. Don't try to include the previous and the next page.
    showFirstPage && showLastPage && expand(currentPage, currentPage, true, true) ||
    // Cut off both sides without adding ellipses.
    expand(currentPage, currentPage, false, false) || [currentPage] // If there's not enough space even for the current page, still show it.
  );
}
function createLayoutByExpandingPageRange(_ref5) {
  var {
    totalPages,
    low,
    high,
    lowerBound,
    upperBound,
    pageRangeCost,
    budget,
    showRewindToFirst,
    showRewindToLast,
    rewindToFirstCost,
    rewindToLastCost
  } = _ref5;
  var safeLowerBound = showRewindToFirst ? Math.max(lowerBound, 4) : lowerBound;
  var safeUpperBound = showRewindToLast ? Math.min(upperBound, totalPages - 3) : upperBound;
  if (!isNondecreasing([lowerBound, safeLowerBound, low, high, safeUpperBound, upperBound])) {
    return null;
  }
  lowerBound = safeLowerBound;
  upperBound = safeUpperBound;
  budget -= (showRewindToFirst ? rewindToFirstCost : 0) + (showRewindToLast ? rewindToLastCost : 0);
  var acceptableLow = 0;
  var acceptableHigh = 0;
  while (lowerBound <= low && high <= upperBound && pageRangeCost(low, high) <= budget) {
    acceptableLow = low;
    acceptableHigh = high;
    if (low === lowerBound && high === upperBound) {
      break;
    }
    low = Math.max(low - 1, lowerBound);
    high = Math.min(high + 1, upperBound);
  }
  return acceptableLow && acceptableHigh ? [...(showRewindToFirst ? [1, 0] : []), ...closedRange(acceptableLow, acceptableHigh), ...(showRewindToLast ? [0, totalPages] : [])] : null;
}
function closedRange(start, stop) {
  var step = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
  var result = [];
  for (var i = start; i <= stop; i += step) {
    result.push(i);
  }
  return result;
}
function isNondecreasing(sequence) {
  for (var i = 1; i < sequence.length; i++) {
    if (sequence[i] < sequence[i - 1]) {
      return false;
    }
  }
  return true;
}
function mergeBoundingRects(a, b) {
  var top = Math.min(a.top, b.top);
  var right = Math.max(a.right, b.right);
  var bottom = Math.max(a.bottom, b.bottom);
  var left = Math.min(a.left, b.left);
  var width = right - left;
  var height = bottom - top;
  return {
    top,
    right,
    bottom,
    left,
    width,
    height
  };
}
//# sourceMappingURL=utils.js.map