"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getFullRenderRange = getFullRenderRange;
exports.makeRowHeightManager = makeRowHeightManager;
var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends"));
var _fill = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/fill"));
var _utils = require("../utils");
function getFullRenderRange(rowCount) {
  return {
    topIndex: 0,
    topBlank: 0,
    bottomIndex: rowCount,
    bottomBlank: 0
  };
}
function makeRowHeightManager(initRowCount, estimatedRowHeight) {
  var _context;
  var cache = (0, _fill.default)(_context = new Array(initRowCount)).call(_context, estimatedRowHeight);
  function getRenderRange(offset, maxRenderHeight, rowCount) {
    if (cache.length !== rowCount) {
      setRowCount(rowCount);
    }
    if (maxRenderHeight <= 0) {
      // maxRenderHeight <= 0 说明表格目前在 viewport 之外
      if (offset <= 0) {
        // 表格在 viewport 下方
        return getRenderRangeWhenBelowView();
      } else {
        // 表格在 viewport 上方
        return getRenderRangeWhenAboveView();
      }
    } else {
      // 表格与 viewport 相交
      return getRenderRangeWhenInView();
    }
    function getRenderRangeWhenBelowView() {
      var start = {
        topIndex: 0,
        topBlank: 0
      };
      var end = getEnd(0, start);
      return (0, _extends2.default)((0, _extends2.default)({}, start), end);
    }
    function getRenderRangeWhenAboveView() {
      var totalSize = getEstimatedTotalSize(rowCount);
      var start = getStart(totalSize);
      var end = getEnd(totalSize, start);
      return (0, _extends2.default)((0, _extends2.default)({}, start), end);
    }
    function getRenderRangeWhenInView() {
      var start = getStart(offset);
      var end = getEnd(offset + maxRenderHeight, start);
      return (0, _extends2.default)((0, _extends2.default)({}, start), end);
    }
    /** 获取虚拟滚动在 开始位置上的信息 */
    function getStart(offset) {
      if (cache.length === 0) {
        return {
          topIndex: 0,
          topBlank: 0
        };
      }
      var topIndex = 0;
      var topBlank = 0;
      while (topIndex < cache.length) {
        var h = cache[topIndex];
        if (topBlank + h >= offset) {
          break;
        }
        topBlank += h;
        topIndex += 1;
      }
      return overscanUpwards(topIndex, topBlank);
    }
    function overscanUpwards(topIndex, topBlank) {
      var overscanSize = 0;
      var overscanCount = 0;
      while (overscanCount < topIndex && overscanSize < _utils.OVERSCAN_SIZE) {
        overscanCount += 1;
        overscanSize += cache[topIndex - overscanCount];
      }
      return {
        topIndex: topIndex - overscanCount,
        topBlank: topBlank - overscanSize
      };
    }
    /** 获取虚拟滚动 在结束位置上的信息 */
    function getEnd(endOffset, startInfo) {
      var bottomIndex = startInfo.topIndex;
      var offset = startInfo.topBlank;
      while (bottomIndex < rowCount && offset < endOffset) {
        offset += cache[bottomIndex];
        bottomIndex += 1;
      }
      var bottomBlank = getEstimatedTotalSize(rowCount) - offset;
      return overscanDownwards(bottomIndex, bottomBlank);
    }
    function overscanDownwards(bottomIndex, bottomBlank) {
      var overscanSize = 0;
      var overscanCount = 0;
      while (overscanCount < rowCount - bottomIndex && overscanSize < _utils.OVERSCAN_SIZE) {
        overscanSize += cache[bottomIndex + overscanCount];
        overscanCount += 1;
      }
      return {
        bottomIndex: bottomIndex + overscanCount,
        bottomBlank: bottomBlank - overscanSize
      };
    }
    function getEstimatedTotalSize(rowCount) {
      return (0, _utils.sum)(cache) + (rowCount - cache.length) * estimatedRowHeight;
    }
    function setRowCount(count) {
      // 将 cache 的长度设置为 count
      if (count < cache.length) {
        cache.length = count;
      } else {
        var prevSize = cache.length;
        cache.length = count;
        (0, _fill.default)(cache).call(cache, estimatedRowHeight, prevSize);
      }
    }
  }
  function updateRow(index, offset, size) {
    cache[index] = size;
  }
  return {
    getRenderRange: getRenderRange,
    updateRow: updateRow,
    // 导出 cache，方便调试；上层在实际使用时 并不需要使用 cache 字段
    cache: cache
  };
}