import { __asyncValues, __awaiter } from "tslib";
import { Inject, Injectable } from '@angular/core';
import { DynamicItemLoader } from '@anglr/dynamic';
import { LAYOUT_COMPONENTS_LOADER } from '@anglr/dynamic/layout';
import { LayoutComponentsIteratorService } from '@anglr/dynamic/layout-editor';
import { Subscription } from 'rxjs';
import { LayoutManager } from '../layoutManager/layoutManager.service';
import * as i0 from "@angular/core";
import * as i1 from "../layoutManager/layoutManager.service";
import * as i2 from "@anglr/dynamic/layout-editor";
import * as i3 from "@anglr/dynamic";
/**
 * Register for layout components that are part of relations
 */
export class LayoutComponentsRegister {
    //######################### public properties #########################
    /**
     * Gets available types that are used as layout components
     */
    get types() {
        var _a;
        (_a = this.initPromise) !== null && _a !== void 0 ? _a : (this.initPromise = this.initializeTypes());
        return this.initPromise.then(() => {
            return Object.keys(this.definedTypes);
        });
    }
    //######################### constructor #########################
    constructor(layoutManager, loader, iteratorSvc) {
        this.layoutManager = layoutManager;
        this.loader = loader;
        this.iteratorSvc = iteratorSvc;
        //######################### protected fields #########################
        /**
         * Subscriptions created during initialization
         */
        this.initSubscriptions = new Subscription();
        /**
         * Object storing defined types
         */
        this.definedTypes = {};
        /**
         * Initialization promise
         */
        this.initPromise = null;
        this.initSubscriptions.add(this.layoutManager.layoutChange.subscribe(() => this.initPromise = null));
    }
    //######################### public methods - implementation of OnDestroy #########################
    /**
     * Called when component is destroyed
     */
    ngOnDestroy() {
        this.initSubscriptions.unsubscribe();
    }
    //######################### public methods #########################
    /**
     * Gets type by its name
     * @param name - Name of type that should be obtained
     */
    getType(name) {
        var _a, _b, _c;
        return __awaiter(this, void 0, void 0, function* () {
            yield ((_a = this.initPromise) !== null && _a !== void 0 ? _a : (this.initPromise = this.initializeTypes()));
            return (_c = (_b = this.definedTypes[name]) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : null;
        });
    }
    /**
     * Gets display name of type by its name
     * @param name - Name of type that display name should be obtained
     */
    getDisplayName(name) {
        var _a, _b, _c;
        return __awaiter(this, void 0, void 0, function* () {
            yield ((_a = this.initPromise) !== null && _a !== void 0 ? _a : (this.initPromise = this.initializeTypes()));
            return (_c = (_b = this.definedTypes[name]) === null || _b === void 0 ? void 0 : _b.displayName) !== null && _c !== void 0 ? _c : undefined;
        });
    }
    /**
     * Gets scope of type by its name
     * @param name - Name of type that scope should be obtained
     */
    getScope(name) {
        var _a, _b;
        return __awaiter(this, void 0, void 0, function* () {
            yield ((_a = this.initPromise) !== null && _a !== void 0 ? _a : (this.initPromise = this.initializeTypes()));
            return (_b = this.definedTypes[name]) === null || _b === void 0 ? void 0 : _b.scope;
        });
    }
    /**
     * Gets component name of type byt its name
     * @param name - Name of type that component name should be obtained
     */
    getComponentName(name) {
        var _a, _b, _c;
        return __awaiter(this, void 0, void 0, function* () {
            yield ((_a = this.initPromise) !== null && _a !== void 0 ? _a : (this.initPromise = this.initializeTypes()));
            return (_c = (_b = this.definedTypes[name]) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : null;
        });
    }
    /**
     * Gets component package of type byt its name
     * @param name - Name of type that component package should be obtained
     */
    getComponentPackage(name) {
        var _a, _b, _c;
        return __awaiter(this, void 0, void 0, function* () {
            yield ((_a = this.initPromise) !== null && _a !== void 0 ? _a : (this.initPromise = this.initializeTypes()));
            return (_c = (_b = this.definedTypes[name]) === null || _b === void 0 ? void 0 : _b.package) !== null && _c !== void 0 ? _c : null;
        });
    }
    //######################### protected method #########################
    /**
     * Initialize layout types
     */
    initializeTypes() {
        var _a, e_1, _b, _c;
        return __awaiter(this, void 0, void 0, function* () {
            this.definedTypes = {};
            if (!this.layoutManager.layout) {
                return;
            }
            const layoutComponents = this.iteratorSvc.getIteratorFor(this.layoutManager.layout);
            try {
                for (var _d = true, layoutComponents_1 = __asyncValues(layoutComponents), layoutComponents_1_1; layoutComponents_1_1 = yield layoutComponents_1.next(), _a = layoutComponents_1_1.done, !_a; _d = true) {
                    _c = layoutComponents_1_1.value;
                    _d = false;
                    const component = _c;
                    const type = yield this.loader.loadItem(component.metadata);
                    if (!type) {
                        continue;
                    }
                    this.definedTypes[component.metadata.id] =
                        {
                            type: type.data,
                            displayName: component.metadata.displayName,
                            name: component.metadata.name,
                            scope: component.metadata.scope,
                            package: component.metadata.package,
                        };
                }
            }
            catch (e_1_1) { e_1 = { error: e_1_1 }; }
            finally {
                try {
                    if (!_d && !_a && (_b = layoutComponents_1.return)) yield _b.call(layoutComponents_1);
                }
                finally { if (e_1) throw e_1.error; }
            }
        });
    }
}
LayoutComponentsRegister.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: LayoutComponentsRegister, deps: [{ token: i1.LayoutManager }, { token: LAYOUT_COMPONENTS_LOADER }, { token: i2.LayoutComponentsIteratorService }], target: i0.ɵɵFactoryTarget.Injectable });
LayoutComponentsRegister.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: LayoutComponentsRegister });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: LayoutComponentsRegister, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.LayoutManager }, { type: i3.DynamicItemLoader, decorators: [{
                    type: Inject,
                    args: [LAYOUT_COMPONENTS_LOADER]
                }] }, { type: i2.LayoutComponentsIteratorService }] });
//# sourceMappingURL=layoutComponentsRegister.service.js.map