"use strict";

function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = MeasureColumnWidths;

var React = _interopRequireWildcard(require("react"));

var _index = require("../styles/index.js");

var _headerCell = _interopRequireDefault(require("./header-cell.js"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

// Measures the column header + sampled data
function MeasureColumn(_ref) {
  var sampleIndexes = _ref.sampleIndexes,
      column = _ref.column,
      columnIndex = _ref.columnIndex,
      rows = _ref.rows,
      isSelectable = _ref.isSelectable,
      onLayout = _ref.onLayout;

  var _useStyletron = (0, _index.useStyletron)(),
      _useStyletron2 = _slicedToArray(_useStyletron, 1),
      css = _useStyletron2[0];

  var ref = (0, React.useRef)();
  React.useEffect(function () {
    if (ref.current) {
      onLayout(columnIndex, ref.current.getBoundingClientRect());
    }
  }, []);
  return /*#__PURE__*/React.createElement("div", {
    ref: ref,
    className: css({
      display: 'flex',
      flexDirection: 'column',
      width: 'fit-content'
    })
  }, /*#__PURE__*/React.createElement(_headerCell.default, {
    index: columnIndex,
    isHovered: true,
    isMeasured: true,
    isSelectedAll: false,
    isSelectedIndeterminate: false,
    onMouseEnter: function onMouseEnter() {},
    onMouseLeave: function onMouseLeave() {},
    onSelectAll: function onSelectAll() {},
    onSelectNone: function onSelectNone() {},
    onSort: function onSort(i) {},
    sortable: column.sortable,
    sortDirection: null,
    title: column.title,
    isSelectable: isSelectable
  }), sampleIndexes.map(function (rowIndex, i) {
    var Cell = column.renderCell;
    return /*#__PURE__*/React.createElement(Cell, {
      key: "measure-".concat(i),
      value: column.mapDataToValue(rows[rowIndex].data),
      isSelectable: isSelectable,
      isMeasured: true,
      sortable: column.sortable,
      x: 0,
      y: rowIndex
    });
  }));
}

var MAX_SAMPLE_SIZE = 50;

function generateSampleIndices(inputMin, inputMax, maxSamples) {
  var indices = [];
  var queue = [[inputMin, inputMax]];

  while (queue.length > 0) {
    var _queue$shift = queue.shift(),
        _queue$shift2 = _slicedToArray(_queue$shift, 2),
        min = _queue$shift2[0],
        max = _queue$shift2[1];

    if (indices.length < maxSamples) {
      var pivot = Math.floor((min + max) / 2);
      indices.push(pivot);
      var left = pivot - 1;
      var right = pivot + 1;

      if (left >= min) {
        queue.push([min, left]);
      }

      if (right <= max) {
        queue.push([right, max]);
      }
    }
  }

  return indices;
}

function MeasureColumnWidths(_ref2) {
  var columns = _ref2.columns,
      rows = _ref2.rows,
      widths = _ref2.widths,
      isSelectable = _ref2.isSelectable,
      onWidthsChange = _ref2.onWidthsChange;

  var _useStyletron3 = (0, _index.useStyletron)(),
      _useStyletron4 = _slicedToArray(_useStyletron3, 1),
      css = _useStyletron4[0];

  var widthMap = React.useMemo(function () {
    return new Map();
  }, []);
  var sampleSize = rows.length < MAX_SAMPLE_SIZE ? rows.length : MAX_SAMPLE_SIZE;
  var finishedMeasurementCount = (sampleSize + 1) * columns.length;
  var sampleIndexes = React.useMemo(function () {
    return generateSampleIndices(0, rows.length - 1, sampleSize);
  }, [columns, rows, widths, sampleSize]);
  var handleDimensionsChange = React.useCallback(function (columnIndex, dimensions) {
    var nextWidth = Math.min(Math.max(columns[columnIndex].minWidth || 0, widthMap.get(columnIndex) || 0, dimensions.width + 1), columns[columnIndex].maxWidth || Infinity);

    if (nextWidth !== widthMap.get(columnIndex)) {
      widthMap.set(columnIndex, nextWidth);
    }

    if ( // Refresh at 100% of done
    widthMap.size === columns.length || // ...50%
    widthMap.size === Math.floor(columns.length / 2) || // ...25%
    widthMap.size === Math.floor(columns.length / 4)) {
      onWidthsChange(Array.from(widthMap.values()));
    }
  }, [columns, finishedMeasurementCount, onWidthsChange]);
  var hiddenStyle = css({
    position: 'absolute',
    overflow: 'hidden',
    height: 0
  }); // Remove the measurement nodes after we are done updating our column width

  if (widthMap.size === columns.length) {
    return null;
  }

  return (
    /*#__PURE__*/
    // eslint-disable-next-line jsx-a11y/role-supports-aria-props
    React.createElement("div", {
      className: hiddenStyle,
      "aria-hidden": true,
      role: "none"
    }, columns.map(function (column, i) {
      return /*#__PURE__*/React.createElement(MeasureColumn, {
        key: column.title + i,
        column: column,
        rows: rows,
        isSelectable: isSelectable,
        onLayout: handleDimensionsChange,
        columnIndex: i,
        sampleIndexes: sampleIndexes
      });
    }))
  );
}