"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.boot = boot;
exports.destroy = destroy;
const EventEmitter_1 = require("../EventEmitter");
const Object_1 = require("../Object");
const Registry_1 = require("../Registry");
const context_1 = require("../client/context");
const icons_1 = require("../client/icons");
const theme_1 = require("../client/theme");
const fromBundle_1 = require("../spec/fromBundle");
const wrapper_1 = require("../types/interface/async/wrapper");
const array_1 = require("../util/array");
const weakMerge_1 = require("../weakMerge");
const style_1 = require("./style");
function boot(parent = null, api, opt) {
    const { specs = {}, classes = {}, components = {}, flags = {} } = opt;
    const path = opt.path || '/';
    const keyboard = {
        pressed: [],
        repeat: false,
    };
    const gamepads = [];
    const pointers = {};
    const customEvent = new Set();
    const context = [];
    const input = {
        keyboard,
        gamepads,
        pointers,
    };
    const cache = {
        iframe: [],
        dragAndDrop: {},
        pointerCapture: {},
        spriteSheetMap: {},
        servers: {},
    };
    const feature = {};
    const specs__ = (0, weakMerge_1.weakMerge)(specs, {});
    const registry = new Registry_1.Registry(specs__);
    const { specs_ } = registry;
    const { specsCount, newSpecId, hasSpec, emptySpec, newSpec, getSpec, setSpec, forkSpec, injectSpecs, deleteSpec, registerUnit, unregisterUnit, shouldFork, } = registry;
    const emitter = parent ? parent.emitter : new EventEmitter_1.EventEmitter_();
    const componentRemoteToLocal = {};
    const theme = 'dark';
    const color = (0, theme_1.themeColor)(theme);
    const system = {
        path,
        parent,
        emitter,
        animated: true,
        root: null,
        theme,
        customEvent,
        async: wrapper_1.ASYNC,
        input,
        context,
        specs_,
        specs: specs__,
        classes,
        components,
        icons: icons_1.icons,
        graphs: [],
        specsCount,
        cache,
        feature,
        foreground: {
            svg: undefined,
            app: undefined,
        },
        style: style_1.style,
        showLongPress: undefined,
        captureGesture: undefined,
        global: parent
            ? parent.global
            : {
                ref: {},
                graph: {},
                data: new Object_1.Object_({}),
                scope: {},
            },
        api,
        flags: {
            defaultInputModeNone: false,
            ...flags,
        },
        boot: (opt) => boot(system, api, opt),
        fromBundle: (bundle) => {
            return (0, fromBundle_1.fromBundle)(bundle, specs, {});
        },
        newGraph: (Bundle) => {
            const graph = new Bundle(system);
            return graph;
        },
        getSpec: getSpec.bind(registry),
        hasSpec: hasSpec.bind(registry),
        newSpecId: newSpecId.bind(registry),
        emptySpec: emptySpec.bind(registry),
        forkSpec: forkSpec.bind(registry),
        newSpec: newSpec.bind(registry),
        setSpec: setSpec.bind(registry),
        injectSpecs: injectSpecs.bind(registry),
        deleteSpec: deleteSpec.bind(registry),
        registerUnit: registerUnit.bind(registry),
        unregisterUnit: unregisterUnit.bind(registry),
        shouldFork: shouldFork.bind(registry),
        getLocalComponents: function (remoteGlobalId) {
            const components = componentRemoteToLocal[remoteGlobalId];
            return components !== null && components !== void 0 ? components : [];
        },
        registerLocalComponent: function (component, remoteGlobalId) {
            var _a;
            componentRemoteToLocal[remoteGlobalId] =
                (_a = componentRemoteToLocal[remoteGlobalId]) !== null && _a !== void 0 ? _a : [];
            componentRemoteToLocal[remoteGlobalId].push(component);
            emitter.emit(remoteGlobalId, component);
        },
        unregisterLocalComponent: function (component, remoteGlobalId) {
            const components = componentRemoteToLocal[remoteGlobalId];
            (0, array_1.remove)(components, component);
        },
        destroy: function () {
            for (const graph of system.graphs) {
                graph.destroy();
            }
        },
        color,
    };
    return system;
}
function destroy(system) {
    const { graphs, context } = system;
    for (const graph of graphs) {
        graph.destroy();
    }
    for (const context_ of context) {
        (0, context_1.unmount)(context_);
    }
}
//# sourceMappingURL=index.js.map