import { System } from "../../common/system";
import { Logger } from "../logger";
import { RouterClient } from "../routerClient";
import { ConfigClient } from "../configClient";
import uuidv4 from "uuid-random";
// Ensures that a path, such as documentRoot, ends with a trailing slash
const ensureEndSlash = (path) => {
    if (path.substr(-1) === "/")
        return path;
    return `${path}/`;
};
/**
 * Inserts a child element into a parent element ensuring that the child becomes the
 * first element in the parent.
 */
const insertAsFirstElement = (parent, child) => {
    if (parent.firstChild) {
        parent.insertBefore(child, parent.firstChild);
    }
    else {
        parent.appendChild(child);
    }
};
/**
 * Starts up the listener for theme updates from the Smart Desktop Designer (SDD). This page's local CSS variables
 * will be updated with values from received messages.
 */
const startSDDThemeUpdates = (systemManifest) => {
    var _a;
    /**
     * Ian: IIRC the theme is imported into the tsx at build time and bundled into the component.
     * I think we can just move it into the html of each component so it remains a stylesheet link.
     * Terry: Since SDD doesn't use theme.css then the config probably can be eliminated
     */
    const documentRoot = (_a = systemManifest === null || systemManifest === void 0 ? void 0 : systemManifest.finsemble) === null || _a === void 0 ? void 0 : _a.documentRoot;
    if (documentRoot) {
        const cacheBuster = uuidv4();
        const themeCssUrl = `${ensureEndSlash(documentRoot)}assets/css/theme.css?${cacheBuster}`;
        const themeLink = document.createElement("link");
        themeLink.setAttribute("rel", "stylesheet");
        themeLink.setAttribute("type", "text/css");
        themeLink.setAttribute("href", themeCssUrl);
        /**
         * Append theme.css' <link> at the top of the *body*. It's important to put this link
         * in the body and not the head because "style-loader" (webpack) will inject <style>
         * tags into the <head> which could override theme.css. There is no control over the
         * order of operations, so by putting theme.css into the <body> we guarantee that it is
         * always processed after any injected styles.
         */
        insertAsFirstElement(document.body, themeLink);
        RouterClient.addListener("Finsemble-ui-change.themeUpdate", (error, data) => {
            const css = data === null || data === void 0 ? void 0 : data.data;
            if (css) {
                for (const [key, value] of Object.entries(css)) {
                    document.documentElement.style.setProperty(key, String(value));
                }
            }
            else {
                Logger.system.error("FSBL.entry.ts: Expected CSS for Finsemble-ui-change.themeUpdate but got error", error);
            }
        });
    }
    else {
        Logger.system.error("Could not find manifest entry: finsemble.documentRoot");
    }
};
/**
 * Receives a notice from SDD that the taskbar icon has been updated. The updated location
 * is retrieved from config and then set for the current window.
 */
const startSDDTaskbarUpdates = () => {
    RouterClient.addListener("Finsemble-ui-change.taskbarIconUpdate", () => {
        Logger.system.log("Finsemble-ui-change: dynamic taskbar icon change -- resetting component icon");
        ConfigClient.get(["startup_app", "applicationIcon"], (err, applicationIcon) => {
            if (err) {
                Logger.system.error(`error updating taskbar icon: ${err}`);
            }
            else {
                System.Window.getCurrent().setTaskbarIcon({ iconURL: applicationIcon });
            }
        });
    });
};
/**
 * Starts up listeners for SDD's dynamic updates.
 *
 * @param {*} systemManifest System manifest (e.g. obtained from System.getOptions() )
 * @param {string} componentType The type of component (e.g. from components.json). All components have theme.css injected except the SDD itself.
 */
export const start = (systemManifest, componentType) => {
    // Every component should listen for theme updates except for the SDD itself
    if (componentType !== "smartDesktopDesigner") {
        startSDDThemeUpdates(systemManifest);
        startSDDTaskbarUpdates();
    }
};
//# sourceMappingURL=SDDListeners.js.map