"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 ACTIVE_HEADER_TYPE () {
        return _src.HIGHLIGHT_ACTIVE_HEADER_TYPE;
    },
    get AREA_TYPE () {
        return _src.HIGHLIGHT_AREA_TYPE;
    },
    get COLUMN_TYPE () {
        return _src.HIGHLIGHT_COLUMN_TYPE;
    },
    get CUSTOM_SELECTION_TYPE () {
        return _src.HIGHLIGHT_CUSTOM_SELECTION_TYPE;
    },
    get FILL_TYPE () {
        return _src.HIGHLIGHT_FILL_TYPE;
    },
    get FOCUS_TYPE () {
        return _src.HIGHLIGHT_FOCUS_TYPE;
    },
    get HEADER_TYPE () {
        return _src.HIGHLIGHT_HEADER_TYPE;
    },
    get ROW_TYPE () {
        return _src.HIGHLIGHT_ROW_TYPE;
    },
    get default () {
        return _default;
    }
});
const _activeHeader = require("./types/activeHeader");
const _areaLayered = require("./types/areaLayered");
const _area = require("./types/area");
const _column = require("./types/column");
const _focus = require("./types/focus");
const _customSelection = require("./types/customSelection");
const _fill = require("./types/fill");
const _header = require("./types/header");
const _row = require("./types/row");
const _src = require("../../3rdparty/walkontable/src");
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);
}
var /**
   * Creates (if not exist in the cache) Walkontable Selection instance.
   *
   * @param {Map} cacheMap The map where the instance will be cached.
   * @param {Function} highlightFactory The function factory.
   * @returns {VisualSelection}
   */ _createHighlight = /*#__PURE__*/ new WeakSet();
/**
 * Highlight class responsible for managing Walkontable Selection classes.
 *
 * With Highlight object you can manipulate four different highlight types:
 *  - `cell` can be added only to a single cell at a time and it defines currently selected cell;
 *  - `fill` can occur only once and its highlight defines selection of autofill functionality (managed by the plugin with the same name);
 *  - `areas` can be added to multiple cells at a time. This type highlights selected cell or multiple cells.
 *    The multiple cells have to be defined as an uninterrupted order (regular shape). Otherwise, the new layer of
 *    that type should be created to manage not-consecutive selection;
 *  - `header` can occur multiple times. This type is designed to highlight only headers. Like `area` type it
 *    can appear with multiple highlights (accessed under different level layers).
 *
 * @class Highlight
 * @util
 */ class Highlight {
    /**
   * Check if highlight cell rendering is disabled for specified highlight type.
   *
   * @param {string} highlightType Highlight type. Possible values are: `cell`, `area`, `fill` or `header`.
   * @param {CellCoords} coords The CellCoords instance with defined visual coordinates.
   * @returns {boolean}
   */ isEnabledFor(highlightType, coords) {
        let type = highlightType;
        // Legacy compatibility.
        if (highlightType === _src.HIGHLIGHT_FOCUS_TYPE) {
            type = 'current'; // One from settings for `disableVisualSelection` up to Handsontable 0.36/Handsontable Pro 1.16.0.
        }
        let disableHighlight = this.options.disabledCellSelection(coords.row, coords.col);
        if (typeof disableHighlight === 'string') {
            disableHighlight = [
                disableHighlight
            ];
        }
        return !disableHighlight || Array.isArray(disableHighlight) && !disableHighlight.includes(type);
    }
    /**
   * Set a new layer level to make access to the desire `area` and `header` highlights.
   *
   * @param {number} [level=0] Layer level to use.
   * @returns {Highlight}
   */ useLayerLevel(level = 0) {
        this.layerLevel = level;
        return this;
    }
    /**
   * Get Walkontable Selection instance created for controlling highlight of the currently
   * focused cell (or header).
   *
   * @returns {Selection}
   */ getFocus() {
        return this.focus;
    }
    /**
   * Get Walkontable Selection instance created for controlling highlight of the autofill functionality.
   *
   * @returns {Selection}
   */ getFill() {
        return this.fill;
    }
    /**
   * Creates (if not exist in the cache) Walkontable Selection instance created for controlling
   * `area` highlights.
   *
   * @returns {Selection}
   */ createLayeredArea() {
        return _class_private_method_get(this, _createHighlight, createHighlight).call(this, this.layeredAreas, _areaLayered.createHighlight);
    }
    /**
   * Get all Walkontable Selection instances which describes the state of the visual highlight of the cells.
   *
   * @returns {Selection[]}
   */ getLayeredAreas() {
        return [
            ...this.layeredAreas.values()
        ];
    }
    /**
   * Creates (if not exist in the cache) Walkontable Selection instance created for controlling
   * `highlight` highlights.
   *
   * @returns {Selection}
   */ createArea() {
        return _class_private_method_get(this, _createHighlight, createHighlight).call(this, this.areas, _area.createHighlight);
    }
    /**
   * Get all Walkontable Selection instances which describes the state of the visual highlight of the cells.
   *
   * @returns {Selection[]}
   */ getAreas() {
        return [
            ...this.areas.values()
        ];
    }
    /**
   * Creates (if not exist in the cache) Walkontable Selection instance created for controlling
   * header highlight for rows.
   *
   * @returns {Selection}
   */ createRowHeader() {
        return _class_private_method_get(this, _createHighlight, createHighlight).call(this, this.rowHeaders, _header.createHighlight);
    }
    /**
   * Get all Walkontable Selection instances which describes the state of the visual highlight of the headers.
   *
   * @returns {Selection[]}
   */ getRowHeaders() {
        return [
            ...this.rowHeaders.values()
        ];
    }
    /**
   * Creates (if not exist in the cache) Walkontable Selection instance created for controlling
   * header highlight for columns.
   *
   * @returns {Selection}
   */ createColumnHeader() {
        return _class_private_method_get(this, _createHighlight, createHighlight).call(this, this.columnHeaders, _header.createHighlight);
    }
    /**
   * Get all Walkontable Selection instances which describes the state of the visual highlight of the headers.
   *
   * @returns {Selection[]}
   */ getColumnHeaders() {
        return [
            ...this.columnHeaders.values()
        ];
    }
    /**
   * Creates (if not exist in the cache) Walkontable Selection instance created for controlling
   * highlight for active row headers.
   *
   * @returns {Selection}
   */ createActiveRowHeader() {
        return _class_private_method_get(this, _createHighlight, createHighlight).call(this, this.activeRowHeaders, _activeHeader.createHighlight);
    }
    /**
   * Get all Walkontable Selection instances which describes the state of the visual highlight of the active headers.
   *
   * @returns {Selection[]}
   */ getActiveRowHeaders() {
        return [
            ...this.activeRowHeaders.values()
        ];
    }
    /**
   * Creates (if not exist in the cache) Walkontable Selection instance created for controlling
   * highlight for active column headers.
   *
   * @returns {Selection}
   */ createActiveColumnHeader() {
        return _class_private_method_get(this, _createHighlight, createHighlight).call(this, this.activeColumnHeaders, _activeHeader.createHighlight);
    }
    /**
   * Get all Walkontable Selection instances which describes the state of the visual highlight of the active headers.
   *
   * @returns {Selection[]}
   */ getActiveColumnHeaders() {
        return [
            ...this.activeColumnHeaders.values()
        ];
    }
    /**
   * Creates (if not exist in the cache) Walkontable Selection instance created for controlling
   * highlight for the headers corner.
   *
   * @returns {Selection}
   */ createActiveCornerHeader() {
        return _class_private_method_get(this, _createHighlight, createHighlight).call(this, this.activeCornerHeaders, _activeHeader.createHighlight);
    }
    /**
   * Get all Walkontable Selection instances which describes the state of the visual highlight of the headers corner.
   *
   * @returns {Selection[]}
   */ getActiveCornerHeaders() {
        return [
            ...this.activeCornerHeaders.values()
        ];
    }
    /**
   * Creates (if not exist in the cache) Walkontable Selection instance created for controlling
   * highlight cells in a row.
   *
   * @returns {Selection}
   */ createRowHighlight() {
        return _class_private_method_get(this, _createHighlight, createHighlight).call(this, this.rowHighlights, _row.createHighlight);
    }
    /**
   * Get all Walkontable Selection instances which describes the state of the rows highlighting.
   *
   * @returns {Selection[]}
   */ getRowHighlights() {
        return [
            ...this.rowHighlights.values()
        ];
    }
    /**
   * Creates (if not exist in the cache) Walkontable Selection instance created for controlling
   * highlight cells in a column.
   *
   * @returns {Selection}
   */ createColumnHighlight() {
        return _class_private_method_get(this, _createHighlight, createHighlight).call(this, this.columnHighlights, _column.createHighlight);
    }
    /**
   * Get all Walkontable Selection instances which describes the state of the columns highlighting.
   *
   * @returns {Selection[]}
   */ getColumnHighlights() {
        return [
            ...this.columnHighlights.values()
        ];
    }
    /**
   * Get Walkontable Selection instance created for controlling highlight of the custom selection functionality.
   *
   * @returns {Selection}
   */ getCustomSelections() {
        return [
            ...this.customSelections.values()
        ];
    }
    /**
   * Add selection to the custom selection instance. The new selection are added to the end of the selection collection.
   *
   * @param {object} selectionInstance The selection instance.
   */ addCustomSelection(selectionInstance) {
        this.customSelections.push((0, _customSelection.createHighlight)({
            ...this.options,
            ...selectionInstance
        }));
    }
    /**
   * Updates the CSS class names used for row, column, header, and active header highlights.
   * Necessary when the related settings change at runtime (e.g. via `updateSettings()`).
   *
   * @param {object} options Options with updated class names.
   * @param {string} [options.rowClassName] The new class name for row highlights.
   * @param {string} [options.columnClassName] The new class name for column highlights.
   * @param {string} [options.headerClassName] The new class name for header highlights.
   * @param {string} [options.activeHeaderClassName] The new class name for active header highlights.
   */ updateHighlightClassNames(options) {
        if ('rowClassName' in options) {
            this.options.rowClassName = options.rowClassName;
            (0, _array.arrayEach)(this.rowHighlights.values(), (h)=>{
                h.settings.className = options.rowClassName;
            });
        }
        if ('columnClassName' in options) {
            this.options.columnClassName = options.columnClassName;
            (0, _array.arrayEach)(this.columnHighlights.values(), (h)=>{
                h.settings.className = options.columnClassName;
            });
        }
        if ('headerClassName' in options) {
            this.options.headerClassName = options.headerClassName;
            (0, _array.arrayEach)(this.rowHeaders.values(), (h)=>{
                h.settings.className = options.headerClassName;
            });
            (0, _array.arrayEach)(this.columnHeaders.values(), (h)=>{
                h.settings.className = options.headerClassName;
            });
        }
        if ('activeHeaderClassName' in options) {
            this.options.activeHeaderClassName = options.activeHeaderClassName;
            (0, _array.arrayEach)(this.activeRowHeaders.values(), (h)=>{
                h.settings.className = options.activeHeaderClassName;
            });
            (0, _array.arrayEach)(this.activeColumnHeaders.values(), (h)=>{
                h.settings.className = options.activeHeaderClassName;
            });
            (0, _array.arrayEach)(this.activeCornerHeaders.values(), (h)=>{
                h.settings.className = options.activeHeaderClassName;
            });
        }
    }
    /**
   * Perform cleaning visual highlights for the whole table.
   */ clear() {
        this.focus.clear();
        this.fill.clear();
        (0, _array.arrayEach)(this.areas.values(), (highlight)=>void highlight.clear());
        (0, _array.arrayEach)(this.layeredAreas.values(), (highlight)=>void highlight.clear());
        (0, _array.arrayEach)(this.rowHeaders.values(), (highlight)=>void highlight.clear());
        (0, _array.arrayEach)(this.columnHeaders.values(), (highlight)=>void highlight.clear());
        (0, _array.arrayEach)(this.activeRowHeaders.values(), (highlight)=>void highlight.clear());
        (0, _array.arrayEach)(this.activeColumnHeaders.values(), (highlight)=>void highlight.clear());
        (0, _array.arrayEach)(this.activeCornerHeaders.values(), (highlight)=>void highlight.clear());
        (0, _array.arrayEach)(this.rowHighlights.values(), (highlight)=>void highlight.clear());
        (0, _array.arrayEach)(this.columnHighlights.values(), (highlight)=>void highlight.clear());
    }
    /**
   * This object can be iterate over using `for of` syntax or using internal `arrayEach` helper.
   *
   * @returns {Selection[]}
   */ [Symbol.iterator]() {
        return [
            this.focus,
            this.fill,
            ...this.areas.values(),
            ...this.layeredAreas.values(),
            ...this.rowHeaders.values(),
            ...this.columnHeaders.values(),
            ...this.activeRowHeaders.values(),
            ...this.activeColumnHeaders.values(),
            ...this.activeCornerHeaders.values(),
            ...this.rowHighlights.values(),
            ...this.columnHighlights.values(),
            ...this.customSelections
        ][Symbol.iterator]();
    }
    constructor(options){
        _class_private_method_init(this, _createHighlight);
        /**
   * The property which describes which layer level of the visual selection will be modified.
   * This option is valid only for `area` and `header` highlight types which occurs multiple times on
   * the table (as a non-consecutive selection).
   *
   * An order of the layers is the same as the order of added new non-consecutive selections.
   *
   * @type {number}
   * @default 0
   */ this.layerLevel = 0;
        /**
   * Collection of the `area` highlights. That objects describes attributes for the borders and selection of
   * the multiple selected cells. It can occur multiple times on the table.
   *
   * @type {Map.<number, Selection>}
   */ this.layeredAreas = new Map();
        /**
   * Collection of the `highlight` highlights. That objects describes attributes for the borders and selection of
   * the multiple selected cells. It can occur multiple times on the table.
   *
   * @type {Map.<number, Selection>}
   */ this.areas = new Map();
        /**
   * Collection of the `header` highlights. That objects describes attributes for the selection of
   * the multiple selected rows in the table header. It can occur multiple times on the table.
   *
   * @type {Map.<number, Selection>}
   */ this.rowHeaders = new Map();
        /**
   * Collection of the `header` highlights. That objects describes attributes for the selection of
   * the multiple selected columns in the table header. It can occur multiple times on the table.
   *
   * @type {Map.<number, Selection>}
   */ this.columnHeaders = new Map();
        /**
   * Collection of the `active-header` highlights. That objects describes attributes for the selection of
   * the multiple selected rows in the table header. The table headers which have selected all items in
   * a row will be marked as `active-header`.
   *
   * @type {Map.<number, Selection>}
   */ this.activeRowHeaders = new Map();
        /**
   * Collection of the `active-header` highlights. That objects describes attributes for the selection of
   * the multiple selected columns in the table header. The table headers which have selected all items in
   * a row will be marked as `active-header`.
   *
   * @type {Map.<number, Selection>}
   */ this.activeColumnHeaders = new Map();
        /**
   * Collection of the `active-header` highlights. That objects describes attributes for the selection of
   * the selected corner in the table header. The table headers which have selected all items in
   * a row will be marked as `active-header`.
   *
   * @type {Map.<number, Selection>}
   */ this.activeCornerHeaders = new Map();
        /**
   * Collection of the `rows` highlights. That objects describes attributes for the selection of
   * the multiple selected cells in a row. It can occur multiple times on the table.
   *
   * @type {Map.<number, Selection>}
   */ this.rowHighlights = new Map();
        /**
   * Collection of the `columns` highlights. That objects describes attributes for the selection of
   * the multiple selected cells in a column. It can occur multiple times on the table.
   *
   * @type {Map.<number, Selection>}
   */ this.columnHighlights = new Map();
        /**
   * Collection of the `custom-selection`, holder for example borders added through CustomBorders plugin.
   *
   * @type {Selection[]}
   */ this.customSelections = [];
        this.options = options;
        this.focus = (0, _focus.createHighlight)(options);
        this.fill = (0, _fill.createHighlight)(options);
    }
}
function createHighlight(cacheMap, highlightFactory) {
    const layerLevel = this.layerLevel;
    if (cacheMap.has(layerLevel)) {
        return cacheMap.get(layerLevel);
    }
    const highlight = highlightFactory({
        layerLevel,
        ...this.options
    });
    cacheMap.set(layerLevel, highlight);
    return highlight;
}
const _default = Highlight;
