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 { warn } from '../helpers/console.mjs';
import handsontableStyles from '../styles/handsontableStyles.mjs';
/**
 * The id of the core styles element injected into the document head.
 *
 * @type {string}
 */ const CORE_STYLES_ID = 'handsontable-core-styles';
var /**
   * The instance of the Handsontable.
   *
   * @type {Core}
   */ _hot = /*#__PURE__*/ new WeakMap(), /**
   * The name of the theme.
   *
   * @type {string|undefined}
   */ _themeName = /*#__PURE__*/ new WeakMap(), /**
   * The instance's root element.
   *
   * @type {HTMLElement}
   */ _rootElement = /*#__PURE__*/ new WeakMap(), /**
   * The computed style of the root element.
   *
   * @type {CSSStyleDeclaration}
   * @private
   */ _rootComputedStyle = /*#__PURE__*/ new WeakMap(), /**
   * The root document of the instance.
   *
   * @type {Document}
   */ _rootDocument = /*#__PURE__*/ new WeakMap(), /**
   * An object to store CSS variable values.
   *
   * @type {object}
   */ _cssVars = /*#__PURE__*/ new WeakMap(), /**
   * Stores the computed styles for various elements.
   *
   * @type {object} - An object containing the computed styles if a nested structure of `element: { [element type]: {property: value} }`.
   */ _computedStyles = /*#__PURE__*/ new WeakMap(), /**
   * The callback function to be called when the theme changes.
   *
   * @type {function(string)}
   */ _onThemeChange = /*#__PURE__*/ new WeakMap(), _injectCoreStyles = /*#__PURE__*/ new WeakSet(), /**
   * Calculates the row height based on the current theme and CSS variables.
   *
   * @returns {number|null} The calculated row height, or `null` if any required CSS variable is not found.
   */ _calculateRowHeight = /*#__PURE__*/ new WeakSet(), /**
   * Caches the computed style values for the root element and `td` element.
   */ _cacheStylesheetValues = /*#__PURE__*/ new WeakSet(), /**
   * Retrieves and processes the computed styles for a `td` element.
   *
   * This method creates a temporary table structure, appends it to the root element,
   * retrieves the computed styles for the `td` element, and then removes the table
   * from the DOM. The computed styles are passed to the provided callback function.
   *
   * @param {Array} cssProps - An array of CSS properties to retrieve.
   * @returns {object} An object containing the requested computed styles for the `td` element.
   * @private
   */ _getStylesForTD = /*#__PURE__*/ new WeakSet(), /**
   * Parses the numeric value of a specified CSS property from the root element's computed style.
   *
   * @param {string} property - The CSS property to retrieve and parse.
   * @returns {number|null} The parsed value of the CSS property or `null` if non-existent.
   */ _getParsedNumericCSSValue = /*#__PURE__*/ new WeakSet(), /**
   * Retrieves the non-numeric value of a specified CSS property from the root element's computed style.
   *
   * @param {string} property - The CSS property to retrieve.
   * @returns {string|null} The value of the specified CSS property or `null` if non-existent.
   */ _getCSSValue = /*#__PURE__*/ new WeakSet(), /**
   * Clears the cached values.
   */ _clearCachedValues = /*#__PURE__*/ new WeakSet();
/**
 * Handles the theme-related style operations.
 */ export class StylesHandler {
    /**
   * Retrieves the value of a specified CSS variable.
   *
   * @param {string} variableName - The name of the CSS variable to retrieve.
   * @returns {number|null|undefined} The value of the specified CSS variable, or `undefined` if not found.
   */ getCSSVariableValue(variableName) {
        if (_class_private_field_get(this, _cssVars)[`--ht-${variableName}`]) {
            return _class_private_field_get(this, _cssVars)[`--ht-${variableName}`];
        }
        const acquiredValue = _class_private_method_get(this, _getParsedNumericCSSValue, getParsedNumericCSSValue).call(this, `--ht-${variableName}`) ?? _class_private_method_get(this, _getCSSValue, getCSSValue).call(this, `--ht-${variableName}`);
        if (acquiredValue !== null) {
            _class_private_field_get(this, _cssVars)[`--ht-${variableName}`] = acquiredValue;
            return acquiredValue;
        }
    }
    /**
   * Retrieves the computed style value for a specified CSS property of a `td` element.
   *
   * @param {string} cssProperty - The CSS property to retrieve the value for.
   * @returns {number|string|undefined} The value of the specified CSS property, or `undefined` if not found.
   */ getStyleForTD(cssProperty) {
        return _class_private_field_get(this, _computedStyles)?.td?.[cssProperty];
    }
    /**
   * Calculates the row height based on the current theme and CSS variables.
   *
   * @param {number} [visualRowIndex] The visual row index.
   * @returns {number} The calculated row height.
   */ getDefaultRowHeight(visualRowIndex) {
        const rowHeight = _class_private_method_get(this, _calculateRowHeight, calculateRowHeight).call(this);
        if (visualRowIndex !== undefined && visualRowIndex === _class_private_field_get(this, _hot).view.getFirstRenderedVisibleRow()) {
            // add 1px border-top-width compensation for the first rendered row
            return rowHeight + 1;
        }
        return rowHeight;
    }
    /**
   * Checks if the cells are using the `border-box` box-sizing model.
   *
   * @returns {boolean}
   */ areCellsBorderBox() {
        return this.getStyleForTD('box-sizing') === 'border-box';
    }
    /**
   * Applies the specified theme to the instance.
   *
   * @param {string|undefined|boolean} [themeName] - The name of the theme to apply.
   */ useTheme(themeName) {
        if (!/ht-theme-.*/.test(themeName)) {
            warn(`${themeName} isn't a valid theme name. Please ensure it follows the format ht-theme-<theme-name>.`);
            return;
        }
        _class_private_method_get(this, _clearCachedValues, clearCachedValues).call(this);
        if (themeName && themeName !== _class_private_field_get(this, _themeName)) {
            _class_private_field_set(this, _themeName, themeName);
        }
        _class_private_field_get(this, _onThemeChange).call(this, _class_private_field_get(this, _themeName));
        _class_private_method_get(this, _cacheStylesheetValues, cacheStylesheetValues).call(this);
    }
    /**
   * Gets the name of the theme.
   *
   * @returns {string|undefined}
   */ getThemeName() {
        return _class_private_field_get(this, _themeName);
    }
    /**
   * Clears all cached CSS variable values and computed styles.
   * This should be called when theme CSS variables are dynamically updated.
   */ clearCache() {
        _class_private_method_get(this, _clearCachedValues, clearCachedValues).call(this);
        _class_private_method_get(this, _cacheStylesheetValues, cacheStylesheetValues).call(this);
    }
    /**
   * Initializes a new instance of the `StylesHandler` class.
   *
   * @param {object} options The options for the `StylesHandler` instance.
   * @param {Core} options.hot The instance of the Handsontable.
   * @param {HTMLElement} options.rootElement The root element of the instance.
   * @param {Document} options.rootDocument The root document of the instance.
   * @param {function(string)} options.onThemeChange The callback function to be called when the theme changes.
   * @param {boolean} options.injectCoreCss Whether to inject the core styles into the document head.
   */ constructor({ hot, rootElement, rootDocument, onThemeChange = ()=>{}, injectCoreCss = true }){
        _class_private_method_init(this, _injectCoreStyles);
        _class_private_method_init(this, _calculateRowHeight);
        _class_private_method_init(this, _cacheStylesheetValues);
        _class_private_method_init(this, _getStylesForTD);
        _class_private_method_init(this, _getParsedNumericCSSValue);
        _class_private_method_init(this, _getCSSValue);
        _class_private_method_init(this, _clearCachedValues);
        _class_private_field_init(this, _hot, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _themeName, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _rootElement, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _rootComputedStyle, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _rootDocument, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _cssVars, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _computedStyles, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _onThemeChange, {
            writable: true,
            value: void 0
        });
        _class_private_field_set(this, _cssVars, {});
        _class_private_field_set(this, _computedStyles, {});
        _class_private_field_set(this, _hot, hot);
        _class_private_field_set(this, _rootElement, rootElement);
        _class_private_field_set(this, _rootDocument, rootDocument);
        _class_private_field_set(this, _onThemeChange, onThemeChange);
        if (injectCoreCss) {
            _class_private_method_get(this, _injectCoreStyles, injectCoreStyles).call(this);
        }
    }
}
function injectCoreStyles() {
    if (!_class_private_field_get(this, _hot) || !_class_private_field_get(this, _rootDocument) || !_class_private_field_get(this, _rootDocument).head) {
        return;
    }
    const existing = _class_private_field_get(this, _rootDocument).getElementById(CORE_STYLES_ID);
    if (existing && existing instanceof HTMLStyleElement) {
        return;
    }
    const baseStyles = _class_private_field_get(this, _rootDocument).createElement('style');
    baseStyles.id = CORE_STYLES_ID;
    baseStyles.textContent = handsontableStyles;
    _class_private_field_get(this, _rootDocument).head.appendChild(baseStyles);
}
function calculateRowHeight() {
    const lineHeightVarValue = this.getCSSVariableValue('line-height');
    const verticalPaddingVarValue = this.getCSSVariableValue('cell-vertical-padding');
    const bottomBorderWidth = Math.ceil(parseFloat(this.getStyleForTD('border-bottom-width')));
    if (lineHeightVarValue === null || verticalPaddingVarValue === null || isNaN(bottomBorderWidth)) {
        return null;
    }
    return lineHeightVarValue + 2 * verticalPaddingVarValue + bottomBorderWidth;
}
function cacheStylesheetValues() {
    _class_private_field_set(this, _rootComputedStyle, getComputedStyle(_class_private_field_get(this, _rootElement)));
    const stylesForTD = _class_private_method_get(this, _getStylesForTD, getStylesForTD).call(this, [
        'box-sizing',
        'border-bottom-width'
    ]);
    _class_private_field_get(this, _computedStyles).td = {
        ..._class_private_field_get(this, _computedStyles).td,
        ...{
            'box-sizing': stylesForTD['box-sizing'],
            'border-bottom-width': stylesForTD['border-bottom-width']
        }
    };
}
function getStylesForTD(cssProps) {
    const rootDocument = _class_private_field_get(this, _rootDocument);
    const rootElement = _class_private_field_get(this, _rootElement);
    const table = rootDocument.createElement('table');
    const tbody = rootDocument.createElement('tbody');
    const tr = rootDocument.createElement('tr');
    // This needs not to be the first row in order to get "regular" values.
    const tr2 = rootDocument.createElement('tr');
    const td = rootDocument.createElement('td');
    tr2.appendChild(td);
    tbody.appendChild(tr);
    tbody.appendChild(tr2);
    table.appendChild(tbody);
    rootElement.appendChild(table);
    const computedStyle = getComputedStyle(td);
    const returnObject = {};
    cssProps.forEach((prop)=>{
        returnObject[prop] = computedStyle.getPropertyValue(prop);
    });
    rootElement.removeChild(table);
    return returnObject;
}
function getParsedNumericCSSValue(property) {
    const parsedValue = Math.ceil(parseFloat(_class_private_method_get(this, _getCSSValue, getCSSValue).call(this, property)));
    return Number.isNaN(parsedValue) ? null : parsedValue;
}
function getCSSValue(property) {
    const acquiredValue = _class_private_field_get(this, _rootComputedStyle)?.getPropertyValue(property);
    return acquiredValue === '' ? null : acquiredValue;
}
function clearCachedValues() {
    _class_private_field_set(this, _computedStyles, {});
    _class_private_field_set(this, _cssVars, {});
}
