/**
 * This file serves as a temporary holding area for deprecated functions.
 * Once a deprecated function is removed from the public API then it can
 * be either deleted from this file or moved to a permanent location.
 */
import { Logger } from "../clients/logger";
import LinkerClient from "./linkerClient";
import { AppsClient } from "../clients";
/**
 * Gets all active or pending window names. Active windows have completed spawning.  Pending windows have been spawned but haven't yet completed.
 *
 * @param {StandardCallback} cb Callback returns an array of window names (as does the resolved Promise).
 * @private
 */
export const deprecatedGetActiveAndPendingWindowNames = (routerClient, cb = Function.prototype) => {
    const promiseResolver = (resolve) => {
        routerClient.query("Launcher.getActiveAndPendingWindowNames", {}, (err, response) => {
            if (err) {
                Logger.system.error(err);
            }
            cb(err, response.data);
            resolve({ err, data: response.data });
        });
    };
    return new Promise(promiseResolver);
};
/**
 *
 * Helper to see if element has a class.
 * @param {HTMLElement} el
 * @param {String} className
 * @private
 * @return {HTMLElement}
 */
function hasClass(el, className) {
    if (el.classList) {
        return el.classList.contains(className);
    }
    return !!el.className.match(new RegExp(`(\\s|^)${className}(\\s|$)`));
}
/**
 * Adds a class to an HTML element
 * @param {HTMLElement} el
 * @param {String} className
 * @private
 */
function addClass(el, className) {
    if (el.classList) {
        el.classList.add(className);
    }
    else if (!hasClass(el, className)) {
        el.className = `${el.className} ${className}`;
    }
}
/**
 *
 * Removes class from HTML element
 * @param {HTMLElement} el
 * @param {String} className
 * @private
 */
function removeClass(el, className) {
    if (el.classList) {
        el.classList.remove(className);
    }
    else if (hasClass(el, className)) {
        const reg = new RegExp(`(\\s|^)${className}(\\s|$)`);
        el.className = el.className.replace(reg, " ");
    }
}
/**
 * Highlights the window as active by creating a border around the window.
 *
 * @param {boolean} active  Set to false to turn off activity
 * @private
 */
export const deprecatedSetActive = (active) => {
    if (active) {
        addClass(document.documentElement, "desktop-active");
    }
    else {
        removeClass(document.documentElement, "desktop-active");
    }
};
/**
 * Gets the window name of current window or the parent, if tabbed. The code that manages window movement will not see a child window if it's part of a stacked window. This function will return the window name that the Window Service cares about for window movement.
 */
export const deprecatedGetWindowNameForDocking = (finsembleWindow) => {
    return finsembleWindow.name;
};
/** Daniel H. 1/14/2019
 * This method is only used in the DragAndDrop client, and it introduces a sneaky circular dependency between
 * this module and the launcherClient. It should be refactored out of this module. This can't be done until v4.0.0, as
 * it would be a breaking change to our API.
 */
/**
 * This will either open a component with the shared data or publish the shared data using the linker client if the window is linked.
 *
 * @param {object} params
 * @param {object} [params.data]
 * @param {boolean} [params.publishOnly] if the component is linked, this will only publish the data, not force open a window if it does not exist. If the component is not linked, this is ignored.
 * @param {function} [params.multipleOpenerHandler] Optional. This function is called with on object that contains a map of componentTypes to the data types they can open. It must return a list of components to be opened. If no handler is provided, the first found component will be chosen. It is possible that the component opened may not handle all the data provided.
 * @param {function} cb callback invoked with action taken.
 *
 */
export function openSharedData(params, cb) {
    const launcherClient = AppsClient;
    const linkerClient = LinkerClient;
    // If no handler is specified to deal with multiple components, use the first found
    if (!params.multipleOpenerHandler) {
        params.multipleOpenerHandler = function (componentsMappedToData) {
            // find the component that can open the most amount of data
            let maxDataTypesOpened = 0;
            let componentToOpen;
            for (const componentType of Object.keys(componentsMappedToData)) {
                if (componentsMappedToData[componentType].length > maxDataTypesOpened) {
                    componentToOpen = componentType;
                    maxDataTypesOpened = componentsMappedToData[componentType].length;
                }
            }
            return [componentToOpen];
        };
    }
    const errors = [];
    const componentsMappedToData = {};
    // Loop through the data
    launcherClient.getComponentsThatCanReceiveDataTypes({ dataTypes: Object.keys(params.data) }, (err, dataTypeComponentMap) => {
        for (const dataType of Object.keys(dataTypeComponentMap)) {
            if (!dataTypeComponentMap[dataType].componentTypes.length) {
                const error = `No Components Available to Handle the type: ${dataType}`;
                errors.push(error);
                Logger.system.error(error);
            }
            else {
                for (const component of dataTypeComponentMap[dataType].componentTypes) {
                    if (!componentsMappedToData[component]) {
                        componentsMappedToData[component] = [dataType];
                    }
                    else
                        componentsMappedToData[component].push(dataType);
                }
            }
        }
        // What if multiple components need to be opened?
        let componentsToOpen = Object.keys(componentsMappedToData);
        if (componentsToOpen.length) {
            if (componentsToOpen.length > 1) {
                componentsToOpen = params.multipleOpenerHandler(componentsMappedToData);
            }
            const linkerChannels = Object.keys(linkerClient.channels);
            if (linkerChannels.length) {
                // if linked
                const linkedWindows = linkerClient.getLinkedComponents({
                    componentTypes: componentsToOpen,
                    windowIdentifier: linkerClient.windowIdentifier(),
                });
                if (linkedWindows.length || params.publishOnly) {
                    // If publishOnly is true then just publish, not spawn
                    linkerClient.publish({
                        dataType: "Finsemble.DragAndDropClient",
                        data: params.data,
                    }, () => { });
                    if (cb)
                        cb(errors.length ? errors : null, "Data published");
                }
                else {
                    // spawn
                    for (const component of componentsToOpen) {
                        launcherClient.spawn(component, {
                            data: {
                                sharedData: params.data,
                                linker: {
                                    channels: linkerChannels,
                                },
                            },
                            addToWorkspace: true,
                        });
                    }
                    if (cb)
                        cb(errors.length ? errors : null, "Linked Window(s) spawned with data");
                }
            }
            else if (!params.publishOnly) {
                for (const component of componentsToOpen) {
                    launcherClient.spawn(component, {
                        data: {
                            sharedData: params.data,
                        },
                        addToWorkspace: true,
                    });
                }
                if (cb)
                    cb(errors.length ? errors : null, "New Window(s) spawned with data");
            }
        }
        else if (cb)
            cb(errors.length ? errors : null, null);
    });
}
//# sourceMappingURL=deprecatedFunctions.js.map