"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get CopyableRangesFactory () {
        return CopyableRangesFactory;
    },
    get normalizeRanges () {
        return normalizeRanges;
    }
});
const _array = require("../../helpers/array");
const _number = require("../../helpers/number");
function _check_private_redeclaration(obj, privateCollection) {
    if (privateCollection.has(obj)) {
        throw new TypeError("Cannot initialize the same private elements twice on an object");
    }
}
function _class_apply_descriptor_get(receiver, descriptor) {
    if (descriptor.get) {
        return descriptor.get.call(receiver);
    }
    return descriptor.value;
}
function _class_apply_descriptor_set(receiver, descriptor, value) {
    if (descriptor.set) {
        descriptor.set.call(receiver, value);
    } else {
        if (!descriptor.writable) {
            throw new TypeError("attempted to set read only private field");
        }
        descriptor.value = value;
    }
}
function _class_extract_field_descriptor(receiver, privateMap, action) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to " + action + " private field on non-instance");
    }
    return privateMap.get(receiver);
}
function _class_private_field_get(receiver, privateMap) {
    var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
    return _class_apply_descriptor_get(receiver, descriptor);
}
function _class_private_field_init(obj, privateMap, value) {
    _check_private_redeclaration(obj, privateMap);
    privateMap.set(obj, value);
}
function _class_private_field_set(receiver, privateMap, value) {
    var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
    _class_apply_descriptor_set(receiver, descriptor, value);
    return value;
}
function _class_private_method_get(receiver, privateSet, fn) {
    if (!privateSet.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return fn;
}
function _class_private_method_init(obj, privateSet) {
    _check_private_redeclaration(obj, privateSet);
    privateSet.add(obj);
}
var /**
   * @type {CellRange}
   */ _selectedRange = /*#__PURE__*/ new WeakMap(), /**
   * @type {function(): number}
   */ _countRows = /*#__PURE__*/ new WeakMap(), /**
   * @type {function(): number}
   */ _countColumns = /*#__PURE__*/ new WeakMap(), /**
   * @type {function(): number}
   */ _rowsLimit = /*#__PURE__*/ new WeakMap(), /**
   * @type {function(): number}
   */ _columnsLimit = /*#__PURE__*/ new WeakMap(), /**
   * @type {function(): number}
   */ _countColumnHeaders = /*#__PURE__*/ new WeakMap(), /**
   * Trimmed the columns range to the limit.
   *
   * @param {*} startColumn The lowest column index in the range.
   * @param {*} endColumn The highest column index in the range.
   * @returns {number} Returns trimmed column index if it exceeds the limit.
   */ _trimColumnsRange = /*#__PURE__*/ new WeakSet(), /**
   * Trimmed the rows range to the limit.
   *
   * @param {*} startRow The lowest row index in the range.
   * @param {*} endRow The highest row index in the range.
   * @returns {number} Returns trimmed row index if it exceeds the limit.
   */ _trimRowsRange = /*#__PURE__*/ new WeakSet();
class CopyableRangesFactory {
    /* eslint-enable jsdoc/require-description-complete-sentence */ /**
   * Sets the selection range to be processed.
   *
   * @param {CellRange} selectedRange The selection range represented by the CellRange class.
   */ setSelectedRange(selectedRange) {
        _class_private_field_set(this, _selectedRange, selectedRange);
    }
    /**
   * Returns a new coords object within the dataset range (cells) with `startRow`, `startCol`, `endRow`
   * and `endCol` keys.
   *
   * @returns {{startRow: number, startCol: number, endRow: number, endCol: number} | null}
   */ getCellsRange() {
        if (_class_private_field_get(this, _countRows).call(this) === 0 || _class_private_field_get(this, _countColumns).call(this) === 0) {
            return null;
        }
        const { row: startRow, col: startCol } = _class_private_field_get(this, _selectedRange).getTopStartCorner();
        const { row: endRow, col: endCol } = _class_private_field_get(this, _selectedRange).getBottomEndCorner();
        const finalEndRow = _class_private_method_get(this, _trimRowsRange, trimRowsRange).call(this, startRow, endRow);
        const finalEndCol = _class_private_method_get(this, _trimColumnsRange, trimColumnsRange).call(this, startCol, endCol);
        const isRangeTrimmed = endRow !== finalEndRow || endCol !== finalEndCol;
        return {
            isRangeTrimmed,
            startRow,
            startCol,
            endRow: finalEndRow,
            endCol: finalEndCol
        };
    }
    /**
   * Returns a new coords object within the most-bottom column headers range with `startRow`,
   * `startCol`, `endRow` and `endCol` keys.
   *
   * @returns {{startRow: number, startCol: number, endRow: number, endCol: number} | null}
   */ getMostBottomColumnHeadersRange() {
        if (_class_private_field_get(this, _countColumns).call(this) === 0 || _class_private_field_get(this, _countColumnHeaders).call(this) === 0) {
            return null;
        }
        const { col: startCol } = _class_private_field_get(this, _selectedRange).getTopStartCorner();
        const { col: endCol } = _class_private_field_get(this, _selectedRange).getBottomEndCorner();
        const finalEndCol = _class_private_method_get(this, _trimColumnsRange, trimColumnsRange).call(this, startCol, endCol);
        const isRangeTrimmed = endCol !== finalEndCol;
        return {
            isRangeTrimmed,
            startRow: -1,
            startCol,
            endRow: -1,
            endCol: finalEndCol
        };
    }
    /**
   * Returns a new coords object within all column headers layers (including nested headers) range with
   * `startRow`, `startCol`, `endRow` and `endCol` keys.
   *
   * @returns {{startRow: number, startCol: number, endRow: number, endCol: number} | null}
   */ getAllColumnHeadersRange() {
        if (_class_private_field_get(this, _countColumns).call(this) === 0 || _class_private_field_get(this, _countColumnHeaders).call(this) === 0) {
            return null;
        }
        const { col: startCol } = _class_private_field_get(this, _selectedRange).getTopStartCorner();
        const { col: endCol } = _class_private_field_get(this, _selectedRange).getBottomEndCorner();
        const finalEndCol = _class_private_method_get(this, _trimColumnsRange, trimColumnsRange).call(this, startCol, endCol);
        const isRangeTrimmed = endCol !== finalEndCol;
        return {
            isRangeTrimmed,
            startRow: -_class_private_field_get(this, _countColumnHeaders).call(this),
            startCol,
            endRow: -1,
            endCol: finalEndCol
        };
    }
    /* eslint-disable jsdoc/require-description-complete-sentence */ /**
   * @param {{
   *   countRows: function(): number,
   *   countColumns: function(): number,
   *   rowsLimit: function(): number,
   *   columnsLimit: function(): number,
   *   countColumnHeaders: function(): number
   * }} dependencies The utils class dependencies.
   */ constructor({ countRows, countColumns, rowsLimit, columnsLimit, countColumnHeaders }){
        _class_private_method_init(this, _trimColumnsRange);
        _class_private_method_init(this, _trimRowsRange);
        _class_private_field_init(this, _selectedRange, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _countRows, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _countColumns, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _rowsLimit, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _columnsLimit, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _countColumnHeaders, {
            writable: true,
            value: void 0
        });
        _class_private_field_set(this, _countRows, countRows);
        _class_private_field_set(this, _countColumns, countColumns);
        _class_private_field_set(this, _rowsLimit, rowsLimit);
        _class_private_field_set(this, _columnsLimit, columnsLimit);
        _class_private_field_set(this, _countColumnHeaders, countColumnHeaders);
    }
}
function trimColumnsRange(startColumn, endColumn) {
    return Math.min(endColumn, Math.max(startColumn + _class_private_field_get(this, _columnsLimit).call(this) - 1, startColumn));
}
function trimRowsRange(startRow, endRow) {
    return Math.min(endRow, Math.max(startRow + _class_private_field_get(this, _rowsLimit).call(this) - 1, startRow));
}
function normalizeRanges(ranges) {
    const rows = [];
    const columns = [];
    (0, _array.arrayEach)(ranges, (range)=>{
        const minRow = Math.min(range.startRow, range.endRow);
        const maxRow = Math.max(range.startRow, range.endRow);
        (0, _number.rangeEach)(minRow, maxRow, (row)=>{
            if (rows.indexOf(row) === -1) {
                rows.push(row);
            }
        });
        const minColumn = Math.min(range.startCol, range.endCol);
        const maxColumn = Math.max(range.startCol, range.endCol);
        (0, _number.rangeEach)(minColumn, maxColumn, (column)=>{
            if (columns.indexOf(column) === -1) {
                columns.push(column);
            }
        });
    });
    return {
        rows,
        columns
    };
}
