var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "../services/JsonService", "../services/ReferenceService", "./types"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.AtomLoader = void 0;
    const JsonService_1 = require("../services/JsonService");
    const ReferenceService_1 = require("../services/ReferenceService");
    const types_1 = require("./types");
    class AtomLoader {
        static load(url, app) {
            return __awaiter(this, void 0, void 0, function* () {
                if (url.host === "reference") {
                    const r = app.get(ReferenceService_1.default).get(url.path);
                    if (!r) {
                        throw new Error("reference not found");
                    }
                    return r.consume();
                }
                if (url.host === "class") {
                    const r = app.get(ReferenceService_1.default).get(url.path);
                    if (!r) {
                        throw new Error("reference not found");
                    }
                    return app.resolve(r.consume(), true);
                }
                const type = yield types_1.DI.resolveViewClassAsync(url.path);
                if (!type) {
                    throw new Error(`Type not found for ${url}`);
                }
                const obj = app.resolve(type, true);
                return obj;
            });
        }
        static loadView(url, app, hookCloseEvents, vmFactory) {
            return __awaiter(this, void 0, void 0, function* () {
                const busyIndicator = app.createBusyIndicator();
                try {
                    const view = yield AtomLoader.load(url, app);
                    let vm = view.viewModel;
                    if (!vm) {
                        if (!vmFactory) {
                            return { view };
                        }
                        vm = vmFactory();
                        view.viewModel = vm;
                    }
                    if (vm) {
                        const jsonService = app.get(JsonService_1.JsonService);
                        for (const key in url.query) {
                            if (url.query.hasOwnProperty(key)) {
                                const element = url.query[key];
                                if (typeof element === "object") {
                                    vm[key] = jsonService.parse(jsonService.stringify(element));
                                    continue;
                                }
                                if (/^json\:/.test(key)) {
                                    const k = key.split(":")[1];
                                    vm[k] = jsonService.parse(element.toString());
                                    continue;
                                }
                                if (/^ref\:/.test(key)) {
                                    const rs = app.get(ReferenceService_1.default);
                                    const v = rs.get(element);
                                    vm[key.split(":", 2)[1]] = v.consume();
                                    continue;
                                }
                                try {
                                    vm[key] = element;
                                }
                                catch (e) {
                                    // tslint:disable-next-line: no-console
                                    console.error(e);
                                }
                            }
                        }
                    }
                    // register hooks !! if it is a window !!
                    if (hookCloseEvents && vm) {
                        const disposables = view.disposables;
                        const id = (AtomLoader.id++).toString();
                        view.id = id;
                        const returnPromise = new Promise((resolve, reject) => {
                            disposables.add(app.subscribe(`atom-window-close:${id}`, (m, r) => {
                                resolve(r);
                                view.dispose();
                            }));
                            disposables.add(app.subscribe(`atom-window-cancel:${id}`, () => {
                                reject("cancelled");
                                view.dispose();
                            }));
                        });
                        // it is responsibility of view holder to dispose the view
                        // disposables.add((view as any));
                        vm.windowName = id;
                        view.returnPromise = returnPromise;
                        return { view, disposables, returnPromise, id };
                    }
                    return { view };
                }
                finally {
                    busyIndicator.dispose();
                }
            });
        }
    }
    exports.AtomLoader = AtomLoader;
    AtomLoader.id = 1;
});
//# sourceMappingURL=AtomLoader.js.map