import { __awaiter } from "tslib";
import { ChangeDetectorRef, Directive, ElementRef, Inject, Injector, Optional } from '@angular/core';
import { LOGGER } from '@anglr/common';
import { isEmptyObject, nameof } from '@jscrpt/common';
import * as i0 from "@angular/core";
/**
 * Base component for layout component
 */
export class LayoutComponentBase {
    //######################### protected properties #########################
    /**
     * Gets element that is used within extension
     */
    get element() {
        return this.componentElement;
    }
    /**
     * Gets options that are used within extension
     */
    get extensionsOptions() {
        return this.options;
    }
    //######################### constructor #########################
    constructor(changeDetector, componentElement, injector, logger) {
        this.changeDetector = changeDetector;
        this.componentElement = componentElement;
        this.injector = injector;
        this.logger = logger;
        //######################### protected fields #########################
        /**
         * Array of extensions that are registered for component
         */
        this.extensions = [];
        /**
         * Indication whether initialization was already done
         */
        this.initialized = false;
        /**
         * Indication whether was component destroyed
         */
        this.destroyed = false;
    }
    //######################### public methods - implementation of OnDestroy #########################
    /**
     * Called when component is destroyed
     */
    ngOnDestroy() {
        if (this.destroyed) {
            return;
        }
        this.destroyed = true;
        for (const ext of this.extensions) {
            ext.destroy();
        }
        this.onDestroy();
    }
    //######################### public methods - implementation of LayoutComponent #########################
    /**
     * @inheritdoc
     */
    ngOnInit() {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
        return __awaiter(this, void 0, void 0, function* () {
            if (this.initialized) {
                return;
            }
            this.initialized = true;
            const extensionsOptions = this.extensionsOptions;
            (_a = this.logger) === null || _a === void 0 ? void 0 : _a.verbose('LayoutComponentBase: before onInit for {{@id}}', { id: (_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.typeMetadata) === null || _c === void 0 ? void 0 : _c.id });
            yield this.onInit();
            (_d = this.logger) === null || _d === void 0 ? void 0 : _d.verbose('LayoutComponentBase: after onInit for {{@id}}', { id: (_f = (_e = this.options) === null || _e === void 0 ? void 0 : _e.typeMetadata) === null || _f === void 0 ? void 0 : _f.id });
            (_g = this.logger) === null || _g === void 0 ? void 0 : _g.verbose('LayoutComponentBase: before onOptionsSet for {{@id}}', { id: (_j = (_h = this.options) === null || _h === void 0 ? void 0 : _h.typeMetadata) === null || _j === void 0 ? void 0 : _j.id });
            yield this.onOptionsSet();
            (_k = this.logger) === null || _k === void 0 ? void 0 : _k.verbose('LayoutComponentBase: after onOptionsSet for {{@id}}', { id: (_m = (_l = this.options) === null || _l === void 0 ? void 0 : _l.typeMetadata) === null || _m === void 0 ? void 0 : _m.id });
            if (extensionsOptions) {
                for (const extension of this.extensions) {
                    yield extension.initialize(this.injector, this.element, this);
                }
            }
            (_o = this.logger) === null || _o === void 0 ? void 0 : _o.verbose('LayoutComponentBase: before afterInit for {{@id}}', { id: (_q = (_p = this.options) === null || _p === void 0 ? void 0 : _p.typeMetadata) === null || _q === void 0 ? void 0 : _q.id });
            yield this.afterInit();
            (_r = this.logger) === null || _r === void 0 ? void 0 : _r.verbose('LayoutComponentBase: after afterInit for {{@id}}', { id: (_t = (_s = this.options) === null || _s === void 0 ? void 0 : _s.typeMetadata) === null || _t === void 0 ? void 0 : _t.id });
        });
    }
    /**
     * @inheritdoc
     */
    ngOnChanges(changes) {
        return __awaiter(this, void 0, void 0, function* () {
            //options has changed
            if (nameof('options') in changes) {
                yield this.onOptionsSet();
                const extensionsOptions = this.extensionsOptions;
                //set options in extensions
                if (extensionsOptions) {
                    for (const extension of this.extensions) {
                        yield extension.optionsChange(extensionsOptions);
                    }
                }
                if (!this.initialized) {
                    return;
                }
                yield this.onOptionsChange();
            }
            delete changes[nameof('options')];
            if (!isEmptyObject(changes)) {
                this.onChanges(changes);
            }
        });
    }
    /**
     * @inheritdoc
     */
    registerExtensions(extensions) {
        this.extensions = extensions;
    }
    /**
     * @inheritdoc
     */
    invalidateVisuals() {
        this.changeDetector.detectChanges();
    }
    //######################### protected methods #########################
    /**
     * Called on initialzation of component, options are already set
     */
    onInit() {
    }
    /**
     * Called right after initialization finished, including extesions
     */
    afterInit() {
    }
    /**
     * Called on change of options, after initialization
     */
    onOptionsChange() {
    }
    /**
     * Occurs when some property changes on component
     * @param _changes - Changes that occured on component
     */
    onChanges(_changes) {
    }
    /**
     * Called everytime options are set, after initialization and later
     */
    onOptionsSet() {
    }
    /**
     * Called when component is being destroyed
     */
    onDestroy() {
    }
}
LayoutComponentBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: LayoutComponentBase, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Injector }, { token: LOGGER, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
LayoutComponentBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.4", type: LayoutComponentBase, usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: LayoutComponentBase, decorators: [{
            type: Directive
        }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Injector }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [LOGGER]
                }, {
                    type: Optional
                }] }] });
//# sourceMappingURL=layoutComponentBase.js.map