"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "ExtendMetaPropertiesMod", {
    enumerable: true,
    get: function() {
        return ExtendMetaPropertiesMod;
    }
});
const _console = require("../../../helpers/console");
const _errors = require("../../../helpers/errors");
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;
}
const correctFormatDeprecatedMessageShown = new WeakSet();
const datePickerConfigDeprecatedMessageShown = new WeakSet();
var /**
   * Callback called when the prop is marked as `initOnly`.
   *
   * @param {string} propName The property name.
   * @param {*} value The new value.
   * @param {boolean} isInitialChange Is the change initial.
   */ _initOnlyCallback = /*#__PURE__*/ new WeakMap();
class ExtendMetaPropertiesMod {
    /**
   * Extends the meta options based on the object descriptors from the `propDescriptors` list.
   */ extendMetaProps() {
        this.propDescriptors.forEach((descriptor, alias)=>{
            const { initOnly, target, onChange } = descriptor;
            const hasTarget = typeof target === 'string';
            const targetProp = hasTarget ? target : alias;
            const origProp = `_${targetProp}`;
            this.metaManager.globalMeta.meta[origProp] = this.metaManager.globalMeta.meta[targetProp];
            if (onChange) {
                this.installPropWatcher(alias, origProp, onChange);
                if (hasTarget) {
                    this.installPropWatcher(target, origProp, onChange);
                }
            } else if (initOnly) {
                this.installPropWatcher(alias, origProp, _class_private_field_get(this, _initOnlyCallback));
                if (!this.metaManager.globalMeta.meta._initOnlySettings) {
                    this.metaManager.globalMeta.meta._initOnlySettings = [];
                }
                this.metaManager.globalMeta.meta._initOnlySettings.push(alias);
            }
        });
    }
    /**
   * Installs the property watcher to the `propName` option and forwards getter and setter to
   * the new one.
   *
   * @param {string} propName The property to watch.
   * @param {string} origProp The property from/to the value is forwarded.
   * @param {Function} onChange The callback.
   */ installPropWatcher(propName, origProp, onChange) {
        const self = this;
        Object.defineProperty(this.metaManager.globalMeta.meta, propName, {
            get () {
                return this[origProp];
            },
            set (value) {
                const isInitialChange = !self.usageTracker.has(propName);
                self.usageTracker.add(propName);
                onChange.call(self, propName, value, isInitialChange);
                this[origProp] = value;
            },
            enumerable: true,
            configurable: true
        });
    }
    constructor(metaManager){
        _class_private_field_init(this, _initOnlyCallback, {
            writable: true,
            value: void 0
        });
        /**
   * @type {Set}
   */ this.usageTracker = new Set();
        /**
   * @type {Map}
   */ this.propDescriptors = new Map([
            [
                'ariaTags',
                {
                    initOnly: true
                }
            ],
            [
                'fixedColumnsLeft',
                {
                    target: 'fixedColumnsStart',
                    onChange (propName) {
                        const isRtl = this.metaManager.hot.isRtl();
                        if (isRtl && propName === 'fixedColumnsLeft') {
                            (0, _errors.throwWithCause)('The `fixedColumnsLeft` is not supported for RTL. Please use option `fixedColumnsStart`.');
                        }
                        if (this.usageTracker.has('fixedColumnsLeft') && this.usageTracker.has('fixedColumnsStart')) {
                            (0, _errors.throwWithCause)('The `fixedColumnsLeft` and `fixedColumnsStart` should not be used together. ' + 'Please use only the option `fixedColumnsStart`.');
                        }
                    }
                }
            ],
            [
                'correctFormat',
                {
                    onChange () {
                        if (!correctFormatDeprecatedMessageShown.has(this.metaManager.hot)) {
                            correctFormatDeprecatedMessageShown.add(this.metaManager.hot);
                            (0, _console.deprecatedWarn)('The `correctFormat` option is deprecated and will be removed in the next major release.\n\n' + 'Migration guide: https://handsontable.com/docs/migration-from-16.2-to-17.0/');
                        }
                    }
                }
            ],
            [
                'datePickerConfig',
                {
                    onChange () {
                        if (!datePickerConfigDeprecatedMessageShown.has(this.metaManager.hot)) {
                            datePickerConfigDeprecatedMessageShown.add(this.metaManager.hot);
                            (0, _console.deprecatedWarn)('The `datePickerConfig` option is deprecated and will be removed in the next major release.\n\n' + 'Migration guide: https://handsontable.com/docs/migration-from-16.2-to-17.0/');
                        }
                    }
                }
            ],
            [
                'layoutDirection',
                {
                    initOnly: true
                }
            ],
            [
                'renderAllColumns',
                {
                    initOnly: true
                }
            ],
            [
                'renderAllRows',
                {
                    initOnly: true
                }
            ]
        ]);
        _class_private_field_set(this, _initOnlyCallback, (propName, value, isInitialChange)=>{
            if (!isInitialChange) {
                (0, _errors.throwWithCause)(`The \`${propName}\` option can not be updated after the Handsontable is initialized.`);
            }
        });
        this.metaManager = metaManager;
        this.extendMetaProps();
    }
}
