/**
 * @license
 * Copyright Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { ICON_REGISTRY_KEY } from './icon-constants';
/**
 * The registry for SVG icon instances being used within the current context.
 */
export class IconRegistry {
    static get _icons() {
        if (!window[ICON_REGISTRY_KEY]) {
            window[ICON_REGISTRY_KEY] = new Map();
        }
        return window[ICON_REGISTRY_KEY];
    }
    /**
     * Defines a new icon.
     * @param icon The icon(s) to register.
     */
    static define(icon, svgData) {
        if (Array.isArray(icon)) {
            return icon.filter(i => IconRegistry._isIconObject(i))
                .forEach(i => IconRegistry._register(i.name, i.data));
        }
        const { name, data } = IconRegistry._parseIcon(icon, svgData);
        IconRegistry._register(name, data);
    }
    /**
     * Removes a defined icon.
     * @param icon The icon to unregister.
     */
    static remove(icon) {
        const key = IconRegistry._isIconObject(icon) ? icon.name : icon;
        IconRegistry._icons.delete(key);
    }
    /**
     * Removes a listener
     * @param key The icon name.
     * @param listener The listener callback.
     */
    static removeListener(key, listener) {
        const listeners = IconRegistry._listeners.get(key);
        if (Array.isArray(listeners) && listeners.includes(listener)) {
            listeners.splice(listeners.indexOf(listener), 1);
        }
    }
    /** Removes all defined icons. */
    static clear() {
        IconRegistry._icons.clear();
        IconRegistry._listeners.clear();
    }
    /** Gets the icon data by its name, or `undefined` if not found. */
    static get(name) {
        return IconRegistry._icons.get(name);
    }
    /** Sets the icon node for a given icon name. */
    static setNode(name, node) {
        const descriptor = IconRegistry.get(name);
        if (descriptor) {
            descriptor.node = node;
        }
    }
    /** Gets the names of registered icons. */
    static getIconNames() {
        return Array.from(IconRegistry._icons.keys());
    }
    /** Registers a listener to be notified when an icon with the provided key is registered in the future. */
    static awaitIcon(key, listener) {
        var _a;
        if (IconRegistry._icons.has(key)) {
            listener();
            return;
        }
        const listeners = (_a = IconRegistry._listeners.get(key)) !== null && _a !== void 0 ? _a : [];
        IconRegistry._listeners.set(key, [...listeners, listener]);
    }
    /** Gets the number of defined icons in the registry. */
    static get size() {
        return IconRegistry._icons.size;
    }
    /** Registers an icon, and attempts to invalidate any listeners. */
    static _register(key, value) {
        IconRegistry._icons.set(key, { raw: value, node: undefined });
        IconRegistry._invalidateListeners(key);
    }
    /** Gets all listeners for a specific key, calls the listeners (if any are found), and removes the listeners after they are called. */
    static _invalidateListeners(key) {
        const listeners = IconRegistry._listeners.get(key);
        if (Array.isArray(listeners) && listeners.length) {
            listeners.forEach(listener => listener());
            IconRegistry._listeners.delete(key);
        }
    }
    /** Normalizes incoming parameters to an `IIcon` type. */
    static _parseIcon(icon, data = '') {
        if (IconRegistry._isIconObject(icon)) {
            return icon;
        }
        return { name: icon, data };
    }
    /** Determines if the provided `icon` matches the `IIcon` shape. */
    static _isIconObject(icon) {
        return typeof icon === 'object' && icon.hasOwnProperty('name') && icon.hasOwnProperty('data');
    }
}
IconRegistry._listeners = new Map();
