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);
}
import { BasePlugin } from '../base/index.mjs';
import { Hooks } from '../../core/hooks/index.mjs';
import freezeColumnItem from './contextMenuItem/freezeColumn.mjs';
import unfreezeColumnItem from './contextMenuItem/unfreezeColumn.mjs';
Hooks.getSingleton().register('beforeColumnFreeze');
Hooks.getSingleton().register('afterColumnFreeze');
Hooks.getSingleton().register('beforeColumnUnfreeze');
Hooks.getSingleton().register('afterColumnUnfreeze');
export const PLUGIN_KEY = 'manualColumnFreeze';
export const PLUGIN_PRIORITY = 110;
var /**
   * Determines when the moving operation is allowed.
   *
   * @type {boolean}
   */ _afterFirstUse = /*#__PURE__*/ new WeakMap(), /**
   * Adds the manualColumnFreeze context menu entries.
   *
   * @private
   * @param {object} options Context menu options.
   */ _addContextMenuEntry = /*#__PURE__*/ new WeakSet(), /**
   * Prevents moving the columns from/to fixed area.
   *
   * @private
   * @param {Array} columns Array of visual column indexes to be moved.
   * @param {number} finalIndex Visual column index, being a start index for the moved columns. Points to where the elements will be placed after the moving action.
   * @returns {boolean|undefined}
   */ _onBeforeColumnMove = /*#__PURE__*/ new WeakSet();
/* eslint-disable jsdoc/require-description-complete-sentence */ /**
 * @plugin ManualColumnFreeze
 * @class ManualColumnFreeze
 *
 * @description
 * This plugin allows to manually "freeze" and "unfreeze" a column using an entry in the Context Menu or using API.
 * You can turn it on by setting a {@link Options#manualColumnFreeze} property to `true`.
 *
 * @example
 * ```js
 * // Enables the plugin
 * manualColumnFreeze: true,
 * ```
 */ export class ManualColumnFreeze extends BasePlugin {
    static get PLUGIN_KEY() {
        return PLUGIN_KEY;
    }
    static get PLUGIN_PRIORITY() {
        return PLUGIN_PRIORITY;
    }
    /**
   * 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 ManualColumnFreeze#enablePlugin} method is called.
   *
   * @returns {boolean}
   */ isEnabled() {
        return !!this.hot.getSettings()[PLUGIN_KEY];
    }
    /**
   * Enables the plugin functionality for this Handsontable instance.
   */ enablePlugin() {
        if (this.enabled) {
            return;
        }
        this.addHook('afterContextMenuDefaultOptions', (options)=>_class_private_method_get(this, _addContextMenuEntry, addContextMenuEntry).call(this, options));
        this.addHook('beforeColumnMove', (columns, finalIndex)=>_class_private_method_get(this, _onBeforeColumnMove, onBeforeColumnMove).call(this, columns, finalIndex));
        super.enablePlugin();
    }
    /**
   * Disables the plugin functionality for this Handsontable instance.
   */ disablePlugin() {
        _class_private_field_set(this, _afterFirstUse, false);
        super.disablePlugin();
    }
    /**
   * Updates the plugin's state.
   *
   * This method is executed when [`updateSettings()`](@/api/core.md#updatesettings) is invoked with any of the following configuration options:
   *  - [`manualColumnFreeze`](@/api/options.md#manualcolumnfreeze)
   */ updatePlugin() {
        this.disablePlugin();
        this.enablePlugin();
        super.updatePlugin();
    }
    /**
   * Freezes the specified column (adds it to fixed columns).
   *
   * `freezeColumn()` doesn't re-render the table,
   * so you need to call the `render()` method afterward.
   *
   * @param {number} column Visual column index.
   */ freezeColumn(column) {
        const settings = this.hot.getSettings();
        // columns are already fixed (frozen)
        const freezePerformed = settings.fixedColumnsStart < this.hot.countCols() && column > settings.fixedColumnsStart - 1;
        if (!_class_private_field_get(this, _afterFirstUse)) {
            _class_private_field_set(this, _afterFirstUse, true);
        }
        const beforeColumnFreezeHook = this.hot.runHooks('beforeColumnFreeze', column, freezePerformed);
        if (beforeColumnFreezeHook === false) {
            return;
        }
        if (freezePerformed) {
            this.hot.columnIndexMapper.moveIndexes(column, settings.fixedColumnsStart);
            // Since 12.0.0, the "fixedColumnsLeft" is replaced with the "fixedColumnsStart" option.
            // However, keeping the old name still in effect. When both option names are used together,
            // the error is thrown. To prevent that, the plugin needs to modify the original option key
            // to bypass the validation.
            settings._fixedColumnsStart += 1;
        }
        this.hot.runHooks('afterColumnFreeze', column, freezePerformed);
    }
    /**
   * Unfreezes the given column (remove it from fixed columns and bring to it's previous position).
   *
   * @param {number} column Visual column index.
   */ unfreezeColumn(column) {
        const settings = this.hot.getSettings();
        // columns are not fixed (not frozen)
        const unfreezePerformed = settings.fixedColumnsStart > 0 && column <= settings.fixedColumnsStart - 1;
        if (!_class_private_field_get(this, _afterFirstUse)) {
            _class_private_field_set(this, _afterFirstUse, true);
        }
        const beforeColumnUnfreezeHook = this.hot.runHooks('beforeColumnUnfreeze', column, unfreezePerformed);
        if (beforeColumnUnfreezeHook === false) {
            return;
        }
        if (unfreezePerformed) {
            // Since 12.0.0, the "fixedColumnsLeft" is replaced with the "fixedColumnsStart" option.
            // However, keeping the old name still in effect. When both option names are used together,
            // the error is thrown. To prevent that, the plugin needs to modify the original option key
            // to bypass the validation.
            settings._fixedColumnsStart -= 1;
            this.hot.columnIndexMapper.moveIndexes(column, settings.fixedColumnsStart);
        }
        this.hot.runHooks('afterColumnUnfreeze', column, unfreezePerformed);
    }
    constructor(...args){
        super(...args), _class_private_method_init(this, _addContextMenuEntry), _class_private_method_init(this, _onBeforeColumnMove), _class_private_field_init(this, _afterFirstUse, {
            writable: true,
            value: void 0
        }), _class_private_field_set(this, _afterFirstUse, false);
    }
}
function addContextMenuEntry(options) {
    options.items.push({
        name: '---------'
    }, freezeColumnItem(this), unfreezeColumnItem(this));
}
function onBeforeColumnMove(columns, finalIndex) {
    if (_class_private_field_get(this, _afterFirstUse)) {
        const freezeLine = this.hot.getSettings().fixedColumnsStart;
        // Moving any column before the "freeze line" isn't possible.
        if (finalIndex < freezeLine) {
            return false;
        }
        // Moving frozen column isn't possible.
        if (columns.some((column)=>column < freezeLine)) {
            return false;
        }
    }
}
