/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { PureEventEmitter } from '@breadstone/mosaik-elements';
// #endregion
/**
 * The `Theme2` class.
 *
 * @public
 */
export class Theme2 {
    // #region Fields
    static _themeElements = [];
    _themeChanged;
    _schemeChanged;
    _paletteChanged;
    // #endregion
    // #region Ctor
    /**
     * Constructs a new instance of the `Theme` class.
     *
     * @public
     */
    constructor() {
        this._themeChanged = new PureEventEmitter();
        this._schemeChanged = new PureEventEmitter();
        this._paletteChanged = new PureEventEmitter();
    }
    // #endregion
    // #region Properties
    /**
     * @public
     * @readonly
     * @eventProperty
     */
    get themeChanged() {
        return this._themeChanged;
    }
    /**
     * @public
     * @readonly
     * @eventProperty
     */
    get schemeChanged() {
        return this._schemeChanged;
    }
    /**
     * @public
     * @readonly
     * @eventProperty
     */
    get paletteChanged() {
        return this._paletteChanged;
    }
    // #endregion
    // #region Methods
    /**
     * @public
     * @static
     */
    static register(element) {
        Theme2._themeElements.push(element);
    }
    /**
     * @public
     * @static
     */
    static unregister(element) {
        const index = Theme2._themeElements.indexOf(element);
        if (index > -1) {
            Theme2._themeElements.splice(index, 1);
        }
    }
    /**
     * @public
     */
    getTheme() {
        const current = Theme2._themeElements.at(0)?.theme;
        if (!current) {
            throw new Error('No theme set.');
        }
        return current;
    }
    getDocumentTheme() {
        return document.documentElement.getAttribute('theme');
    }
    getDocumentThemeMode() {
        return document.documentElement.getAttribute('theme-mode');
    }
    /**
     * Applies the specified scheme.
     *
     * @public
     */
    applyScheme(scheme) {
        Theme2._themeElements.forEach((element) => {
            element.applyScheme(scheme);
        });
        this._schemeChanged.emit({ scheme: scheme });
    }
    /**
     * Replaces the scheme with the specified key.
     * This is useful when you want to replace a specific scheme in the theme.
     *
     * @public
     */
    replaceScheme(key, scheme) {
        Theme2._themeElements.forEach((element) => {
            element.applyScheme({
                ...element.theme?.scheme,
                [key]: scheme
            });
        });
    }
    /**
     * Applies the specified palette.
     *
     * @public
     */
    applyPalette(palette) {
        Theme2._themeElements.forEach((element) => {
            element.applyPalette(palette);
        });
        this._paletteChanged.emit({ palette: palette });
    }
    /**
     * Replaces the palette with the specified key.
     * This is useful when you want to replace a specific palette in the theme.
     *
     * @public
     */
    replacePalette(key, palette) {
        Theme2._themeElements.forEach((element) => {
            // element.theme.palette[key] = palette;
            element.applyPalette({
                ...element.theme?.palette,
                [key]: palette
            });
        });
        this._paletteChanged.emit({ palette: palette });
    }
    /**
     * Applies the specified font family.
     *
     * @public
     */
    applyFontFamily(fontFamily) {
        Theme2._themeElements.forEach((element) => {
            element.applyFontFamily(fontFamily);
        });
    }
    /**
     * Replaces the font family with the specified value.
     * This is useful when you want to replace the font family in the theme.
     *
     * @public
     */
    replaceFontFamily(fontFamily) {
        Theme2._themeElements.forEach((element) => {
            element.applyFontFamily(fontFamily);
        });
    }
    /**
     * @public
     */
    applyTypography(typography) {
        Theme2._themeElements.forEach((element) => {
            element.applyTypography(typography);
        });
    }
    /**
     * Applies the specified layout.
     *
     * @public
     */
    applyLayout(layout) {
        Theme2._themeElements.forEach((element) => {
            element.applyLayout(layout);
        });
    }
    /**
     * Replaces the layout with the specified value.
     * This is useful when you want to replace the layout in the theme.
     *
     * @public
     */
    replaceLayout(layout) {
        Theme2._themeElements.forEach((element) => {
            element.applyLayout(layout);
        });
    }
    /**
     * @public
     */
    applyElevation(elevation) {
        Theme2._themeElements.forEach((element) => {
            element.applyElevation(elevation);
        });
    }
}
/**
 * @public
 */
export class Theme2ServiceLocator {
    // #region Fields
    static _current = null;
    // #endregion
    // #region Properties
    static get current() {
        if (!Theme2ServiceLocator.isSet()) {
            throw new Error('\'Theme\' not set.');
        }
        return Theme2ServiceLocator._current;
    }
    // #endregion
    // #region Methods
    static isSet() {
        return Theme2ServiceLocator._current !== null;
    }
    static set(current) {
        Theme2ServiceLocator._current = current;
    }
}
Theme2ServiceLocator.set(new Theme2());
//# sourceMappingURL=Theme2.js.map