define(["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.getDefaultTarget = exports.setDefaultTarget = exports.notifyHostChanged = exports.cleanupDefaultLayerHost = exports.createDefaultLayerHost = exports.unregisterLayerHost = exports.registerLayerHost = exports.getLayerHost = exports.getLayerCount = exports.unregisterLayer = exports.registerLayer = void 0;
    var _layersByHostId = {};
    var _layerHostsById = {};
    var defaultHostId = 'fluent-default-layer-host';
    var _defaultHostSelector = "#" + defaultHostId;
    /**
     * Register a layer for a given host id
     * @param hostId Id of the layer host
     * @param layer Layer instance
     */
    function registerLayer(hostId, callback) {
        if (!_layersByHostId[hostId]) {
            _layersByHostId[hostId] = [];
        }
        _layersByHostId[hostId].push(callback);
        var layerHosts = _layerHostsById[hostId];
        if (layerHosts) {
            for (var _i = 0, layerHosts_1 = layerHosts; _i < layerHosts_1.length; _i++) {
                var layerHost = layerHosts_1[_i];
                layerHost.notifyLayersChanged();
            }
        }
    }
    exports.registerLayer = registerLayer;
    /**
     * Unregister a layer for a given host id
     * @param hostId Id of the layer host
     * @param layer Layer instance
     */
    function unregisterLayer(hostId, callback) {
        var layers = _layersByHostId[hostId];
        if (layers) {
            var idx = layers.indexOf(callback);
            if (idx >= 0) {
                layers.splice(idx, 1);
                if (layers.length === 0) {
                    delete _layersByHostId[hostId];
                }
            }
        }
        var layerHosts = _layerHostsById[hostId];
        if (layerHosts) {
            for (var _i = 0, layerHosts_2 = layerHosts; _i < layerHosts_2.length; _i++) {
                var layerHost = layerHosts_2[_i];
                layerHost.notifyLayersChanged();
            }
        }
    }
    exports.unregisterLayer = unregisterLayer;
    /**
     * Gets the number of layers currently registered with a host id.
     * @param hostId Id of the layer host.
     * @returns The number of layers currently registered with the host.
     */
    function getLayerCount(hostId) {
        var layers = _layerHostsById[hostId];
        return layers ? layers.length : 0;
    }
    exports.getLayerCount = getLayerCount;
    /**
     * Gets the Layer Host instance associated with a hostId, if applicable.
     * @param hostId
     * @returns A component ref for the associated layer host.
     */
    function getLayerHost(hostId) {
        var layerHosts = _layerHostsById[hostId];
        return (layerHosts && layerHosts[0]) || undefined;
    }
    exports.getLayerHost = getLayerHost;
    /**
     * Registers a Layer Host with an associated hostId.
     * @param hostId Id of the layer host
     * @param layerHost layer host instance
     */
    function registerLayerHost(hostId, layerHost) {
        var layerHosts = _layerHostsById[hostId] || (_layerHostsById[hostId] = []);
        // Insert this at the start of an array to avoid race conditions between mount and unmount.
        // If a LayerHost is re-mounted, and mount of the new instance may occur before the unmount of the old one.
        // Putting the new instance at the start of this array ensures that calls to `getLayerHost` will immediately
        // get the new one even if the old one is around briefly.
        layerHosts.unshift(layerHost);
    }
    exports.registerLayerHost = registerLayerHost;
    /**
     * Unregisters a Layer Host from the associated hostId.
     * @param hostId Id of the layer host
     * @param layerHost layer host instance
     */
    function unregisterLayerHost(hostId, layerHost) {
        var layerHosts = _layerHostsById[hostId];
        if (layerHosts) {
            var idx = layerHosts.indexOf(layerHost);
            if (idx >= 0) {
                layerHosts.splice(idx, 1);
            }
            if (layerHosts.length === 0) {
                delete _layerHostsById[hostId];
            }
        }
    }
    exports.unregisterLayerHost = unregisterLayerHost;
    /**
     * When no default layer host is provided, this function is executed to create the default host.
     */
    function createDefaultLayerHost(doc, shadowRoot) {
        var host = doc.createElement('div');
        host.setAttribute('id', defaultHostId);
        host.style.cssText = 'position:fixed;z-index:1000000';
        if (shadowRoot) {
            shadowRoot.appendChild(host);
        }
        else {
            doc === null || doc === void 0 ? void 0 : doc.body.appendChild(host);
        }
        return host;
    }
    exports.createDefaultLayerHost = createDefaultLayerHost;
    /**
     * This function can be optionally called to clean up the default layer host as needed.
     */
    function cleanupDefaultLayerHost(doc, shadowRoot) {
        var host = shadowRoot ? shadowRoot.querySelector("#" + defaultHostId) : doc.querySelector("#" + defaultHostId);
        if (host) {
            if (shadowRoot) {
                shadowRoot.removeChild(host);
            }
            else {
                doc.removeChild(host);
            }
        }
    }
    exports.cleanupDefaultLayerHost = cleanupDefaultLayerHost;
    /**
     * Used for notifying applicable Layers that a host is available/unavailable and to re-evaluate Layers that
     * care about the specific host.
     */
    function notifyHostChanged(id) {
        if (_layersByHostId[id]) {
            _layersByHostId[id].forEach(function (callback) { return callback(); });
        }
    }
    exports.notifyHostChanged = notifyHostChanged;
    /**
     * Sets the default target selector to use when determining the host in which
     * Layered content will be injected into. If not provided, an element will be
     * created at the end of the document body.
     *
     * Passing in a falsy value will clear the default target and reset back to
     * using a created element at the end of document body.
     */
    function setDefaultTarget(selector) {
        _defaultHostSelector = selector;
    }
    exports.setDefaultTarget = setDefaultTarget;
    /**
     * Get the default target selector when determining a host
     */
    function getDefaultTarget() {
        return _defaultHostSelector;
    }
    exports.getDefaultTarget = getDefaultTarget;
});
//# sourceMappingURL=Layer.notification.js.map