import { isNonNullable } from '../utils.js';
import { findPropertyDescriptor, REACT_UI_THEME_MARKERS } from './ThemeHelpers.js';
import { LIGHT_THEME } from './themes/LightTheme.js';
var ThemeFactory = /** @class */ (function () {
    function ThemeFactory() {
    }
    Object.defineProperty(ThemeFactory, "defaultTheme", {
        get: function () {
            return this.overridableDefaultTheme;
        },
        enumerable: false,
        configurable: true
    });
    ThemeFactory.create = function (theme, baseTheme) {
        var base = baseTheme || this.defaultTheme;
        return this.constructTheme(base, theme);
    };
    ThemeFactory.overrideBaseTheme = function (theme) {
        var _this = this;
        // copying theme variables
        ThemeFactory.getKeys(this.defaultTheme).forEach(function (variableName) {
            var descriptor = findPropertyDescriptor(theme, variableName);
            Object.defineProperty(_this.defaultTheme, variableName, descriptor);
        });
        // copying theme markers
        Object.values(REACT_UI_THEME_MARKERS).forEach(function (marker) {
            var descriptor = findPropertyDescriptor(theme, marker.key);
            Object.defineProperty(_this.defaultTheme, marker.key, descriptor);
        });
    };
    ThemeFactory.getKeys = function (theme) {
        var keys = [];
        while (isNonNullable(theme)) {
            Object.keys(theme).forEach(function (key) {
                if (!keys.includes(key)) {
                    keys.push(key);
                }
            });
            // TODO: Enable `no-param-reassign` rule.
            // eslint-disable-next-line no-param-reassign
            theme = Object.getPrototypeOf(theme);
        }
        return keys.sort();
    };
    ThemeFactory.constructTheme = function (base, theme) {
        var newTheme = Object.create(base);
        Object.keys(theme).forEach(function (propName) {
            var descriptor = Object.getOwnPropertyDescriptor(theme, propName);
            if (descriptor) {
                Object.defineProperty(newTheme, propName, descriptor);
            }
        });
        return Object.freeze(newTheme);
    };
    /**
     * The default theme created with Object.create() is needed for the "overrideBaseTheme" to work.
     *
     * Themes should be frozen objects. But it is not possible to define properties on frozen objects.
     * So, an object created by Object.create({ *frozen_object* }) acts as frozen too,
     * but allows to apply Object.defineProperty to his own properties.
     */
    ThemeFactory.overridableDefaultTheme = Object.create(LIGHT_THEME);
    return ThemeFactory;
}());
export { ThemeFactory };
//# sourceMappingURL=ThemeFactory.js.map