"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 PLUGIN_KEY () {
        return PLUGIN_KEY;
    },
    get PLUGIN_PRIORITY () {
        return PLUGIN_PRIORITY;
    },
    get TrimRows () {
        return TrimRows;
    }
});
const _base = require("../base");
const _translations = require("../../translations");
const _array = require("../../helpers/array");
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_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);
}
const PLUGIN_KEY = 'trimRows';
const PLUGIN_PRIORITY = 330;
var /**
   * On map initialized hook callback.
   */ _onMapInit = /*#__PURE__*/ new WeakSet();
class TrimRows extends _base.BasePlugin {
    static get PLUGIN_KEY() {
        return PLUGIN_KEY;
    }
    static get PLUGIN_PRIORITY() {
        return PLUGIN_PRIORITY;
    }
    static get SETTING_KEYS() {
        return [
            PLUGIN_KEY
        ];
    }
    /**
   * Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
   * hook and if it returns `true` then the {@link TrimRows#enablePlugin} method is called.
   * When [[Options#dataProvider]] is a complete server-backed configuration, the DataProvider plugin blocks this plugin from enabling.
   *
   * @returns {boolean}
   */ isEnabled() {
        return !!this.hot.getSettings()[PLUGIN_KEY];
    }
    /**
   * Enables the plugin functionality for this Handsontable instance.
   */ enablePlugin() {
        if (this.enabled) {
            return;
        }
        this.trimmedRowsMap = this.hot.rowIndexMapper.registerMap('trimRows', new _translations.TrimmingMap());
        this.trimmedRowsMap.addLocalHook('init', ()=>_class_private_method_get(this, _onMapInit, onMapInit).call(this));
        super.enablePlugin();
    }
    /**
   * Updates the plugin's state.
   *
   * This method is executed when [`updateSettings()`](@/api/core.md#updatesettings) is invoked with any of the following configuration options:
   *  - [`trimRows`](@/api/options.md#trimrows)
   */ updatePlugin() {
        const trimmedRows = this.hot.getSettings()[PLUGIN_KEY];
        if (Array.isArray(trimmedRows)) {
            this.hot.batchExecution(()=>{
                this.trimmedRowsMap.clear();
                (0, _array.arrayEach)(trimmedRows, (physicalRow)=>{
                    this.trimmedRowsMap.setValueAtIndex(physicalRow, true);
                });
            }, true);
        }
        super.updatePlugin();
    }
    /**
   * Disables the plugin functionality for this Handsontable instance.
   */ disablePlugin() {
        this.hot.rowIndexMapper.unregisterMap('trimRows');
        super.disablePlugin();
    }
    /**
   * Get list of trimmed rows.
   *
   * @returns {Array} Physical rows.
   */ getTrimmedRows() {
        return this.trimmedRowsMap.getTrimmedIndexes();
    }
    /**
   * Trims the rows provided in the array.
   *
   * @param {number[]} rows Array of physical row indexes.
   * @fires Hooks#beforeTrimRow
   * @fires Hooks#afterTrimRow
   */ trimRows(rows) {
        const currentTrimConfig = this.getTrimmedRows();
        const isValidConfig = this.isValidConfig(rows);
        let destinationTrimConfig = currentTrimConfig;
        if (isValidConfig) {
            destinationTrimConfig = Array.from(new Set(currentTrimConfig.concat(rows)));
        }
        const allowTrimRow = this.hot.runHooks('beforeTrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig);
        if (allowTrimRow === false) {
            return;
        }
        if (isValidConfig) {
            this.hot.batchExecution(()=>{
                (0, _array.arrayEach)(rows, (physicalRow)=>{
                    this.trimmedRowsMap.setValueAtIndex(physicalRow, true);
                });
            }, true);
        }
        this.hot.runHooks('afterTrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig, isValidConfig && destinationTrimConfig.length > currentTrimConfig.length);
    }
    /**
   * Trims the row provided as a physical row index (counting from 0).
   *
   * @param {...number} row Physical row index.
   */ trimRow(...row) {
        this.trimRows(row);
    }
    /**
   * Untrims the rows provided in the array.
   *
   * @param {number[]} rows Array of physical row indexes.
   * @fires Hooks#beforeUntrimRow
   * @fires Hooks#afterUntrimRow
   */ untrimRows(rows) {
        const currentTrimConfig = this.getTrimmedRows();
        const isValidConfig = this.isValidConfig(rows);
        let destinationTrimConfig = currentTrimConfig;
        const trimmingMapValues = this.trimmedRowsMap.getValues().slice();
        const isAnyRowUntrimmed = rows.length > 0;
        if (isValidConfig && isAnyRowUntrimmed) {
            // Preparing new values for trimming map.
            (0, _array.arrayEach)(rows, (physicalRow)=>{
                trimmingMapValues[physicalRow] = false;
            });
            // Preparing new trimming config.
            destinationTrimConfig = (0, _array.arrayReduce)(trimmingMapValues, (trimmedIndexes, isTrimmed, physicalIndex)=>{
                if (isTrimmed) {
                    trimmedIndexes.push(physicalIndex);
                }
                return trimmedIndexes;
            }, []);
        }
        const allowUntrimRow = this.hot.runHooks('beforeUntrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig && isAnyRowUntrimmed);
        if (allowUntrimRow === false) {
            return;
        }
        if (isValidConfig && isAnyRowUntrimmed) {
            this.trimmedRowsMap.setValues(trimmingMapValues);
        }
        this.hot.runHooks('afterUntrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig && isAnyRowUntrimmed, isValidConfig && destinationTrimConfig.length < currentTrimConfig.length);
    }
    /**
   * Untrims the row provided as a physical row index (counting from 0).
   *
   * @param {...number} row Physical row index.
   */ untrimRow(...row) {
        this.untrimRows(row);
    }
    /**
   * Checks if given row is hidden.
   *
   * @param {number} physicalRow Physical row index.
   * @returns {boolean}
   */ isTrimmed(physicalRow) {
        return this.trimmedRowsMap.getValueAtIndex(physicalRow) || false;
    }
    /**
   * Untrims all trimmed rows.
   */ untrimAll() {
        this.untrimRows(this.getTrimmedRows());
    }
    /**
   * Get if trim config is valid. Check whether all of the provided physical row indexes are within source data.
   *
   * @param {Array} trimmedRows List of physical row indexes.
   * @returns {boolean}
   */ isValidConfig(trimmedRows) {
        const sourceRows = this.hot.countSourceRows();
        return trimmedRows.every((trimmedRow)=>Number.isInteger(trimmedRow) && trimmedRow >= 0 && trimmedRow < sourceRows);
    }
    /**
   * Destroys the plugin instance.
   */ destroy() {
        super.destroy();
    }
    constructor(...args){
        super(...args), _class_private_method_init(this, _onMapInit), /**
   * Map of skipped rows by the plugin.
   *
   * @private
   * @type {null|TrimmingMap}
   */ this.trimmedRowsMap = null;
    }
}
function onMapInit() {
    const trimmedRows = this.hot.getSettings()[PLUGIN_KEY];
    if (Array.isArray(trimmedRows)) {
        this.hot.batchExecution(()=>{
            (0, _array.arrayEach)(trimmedRows, (physicalRow)=>{
                this.trimmedRowsMap.setValueAtIndex(physicalRow, true);
            });
        }, true);
    }
}
