(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common'), require('@wm/components/base'), require('@wm/core'), require('lodash-es')) :
    typeof define === 'function' && define.amd ? define(['exports', '@angular/core', '@angular/common', '@wm/components/base', '@wm/core', 'lodash-es'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.wm = global.wm || {}, global.wm.components = global.wm.components || {}, global.wm.components.prefab = {}), global.ng.core, global.ng.common, global.wm.components.base, global.wm.core, global._));
})(this, (function (exports, i0, common, base, i1, lodashEs) { 'use strict';

    function _interopNamespaceDefault(e) {
        var n = Object.create(null);
        if (e) {
            Object.keys(e).forEach(function (k) {
                if (k !== 'default') {
                    var d = Object.getOwnPropertyDescriptor(e, k);
                    Object.defineProperty(n, k, d.get ? d : {
                        enumerable: true,
                        get: function () { return e[k]; }
                    });
                }
            });
        }
        n.default = e;
        return Object.freeze(n);
    }

    var i0__namespace = /*#__PURE__*/_interopNamespaceDefault(i0);
    var i1__namespace = /*#__PURE__*/_interopNamespaceDefault(i1);

    const prefabProps = new Map([
        ['animation', base.PROP_STRING],
        ['class', { value: '', ...base.PROP_STRING }],
        ['name', base.PROP_STRING],
        ['show', { value: true, ...base.PROP_BOOLEAN }]
    ]);

    const DEFAULT_CLS$1 = 'app-prefab';
    const registeredPropsSet = new Set();
    class PrefabDirective extends base.StylableComponent {
        constructor(inj, elRef, cdr, prefabName, explicitContext) {
            const widgetType = `wm-prefab-${prefabName}`;
            const WIDGET_CONFIG = { widgetType, hostClass: DEFAULT_CLS$1 };
            let resolveFn = i1.noop;
            super(inj, WIDGET_CONFIG, explicitContext, new Promise(res => resolveFn = res));
            this.propsReady = resolveFn;
            this.prefabName = prefabName;
            this.widgetType = widgetType;
            this.name = elRef.nativeElement.getAttribute('name');
            base.styler(this.nativeElement, this);
            // Call on property change on name to set name attribute on element.
            this.registerReadyStateListener(() => {
                super.onPropertyChange('name', this.name);
            });
        }
        onStyleChange(key, nv, ov) {
            if (key === 'height') {
                i1.setCSS(this.nativeElement, 'overflow', 'auto');
            }
        }
        setProps(config) {
            if (!config || !config.properties) {
                return;
            }
            if (!registeredPropsSet.has(this.widgetType)) {
                base.register(this.widgetType, this.prepareProps(config.properties));
            }
            this.propsReady();
        }
        handleEvent() {
            // do not call the super;
            // prevent events from getting registered
        }
        prepareProps(props = {}) {
            const propsMap = new Map(prefabProps);
            Object.entries(props).forEach(([k, v]) => {
                let type = base.PROP_TYPE.STRING;
                if (v.type === 'boolean') {
                    type = base.PROP_TYPE.BOOLEAN;
                }
                else if (v.type === 'number') {
                    type = base.PROP_TYPE.NUMBER;
                }
                else if (v.type !== 'string') {
                    type = v.type;
                }
                // Do not set the 'bind:*' values
                propsMap.set(k, { type, value: lodashEs.startsWith(v.value, 'bind:') ? undefined : v.value });
            });
            registeredPropsSet.add(this.widgetType);
            return propsMap;
        }
        ngOnDestroy() {
            this.invokeEventCallback('destroy', { widget: this });
        }
        static { this.ɵfac = function PrefabDirective_Factory(t) { return new (t || PrefabDirective)(i0__namespace.ɵɵdirectiveInject(i0__namespace.Injector), i0__namespace.ɵɵdirectiveInject(i0__namespace.ElementRef), i0__namespace.ɵɵdirectiveInject(i0__namespace.ChangeDetectorRef), i0__namespace.ɵɵinjectAttribute('prefabname'), i0__namespace.ɵɵdirectiveInject('EXPLICIT_CONTEXT', 8)); }; }
        static { this.ɵdir = /*@__PURE__*/ i0__namespace.ɵɵdefineDirective({ type: PrefabDirective, selectors: [["section", "wmPrefab", ""]], features: [i0__namespace.ɵɵProvidersFeature([
                    base.provideAsWidgetRef(PrefabDirective)
                ]), i0__namespace.ɵɵInheritDefinitionFeature] }); }
    }
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassMetadata(PrefabDirective, [{
            type: i0.Directive,
            args: [{
                    selector: 'section[wmPrefab]',
                    providers: [
                        base.provideAsWidgetRef(PrefabDirective)
                    ]
                }]
        }], () => [{ type: i0__namespace.Injector }, { type: i0__namespace.ElementRef }, { type: i0__namespace.ChangeDetectorRef }, { type: undefined, decorators: [{
                    type: i0.Attribute,
                    args: ['prefabname']
                }] }, { type: undefined, decorators: [{
                    type: i0.Inject,
                    args: ['EXPLICIT_CONTEXT']
                }, {
                    type: i0.Optional
                }] }], null); })();

    const registerProps = () => {
        base.register('wm-prefab-container', new Map([
            ['class', base.PROP_STRING],
            ['name', base.PROP_STRING],
            ['show', { value: true, ...base.PROP_BOOLEAN }],
        ]));
    };

    const DEFAULT_CLS = 'app-prefab-container full-height';
    const WIDGET_CONFIG = {
        widgetType: 'wm-prefab-container',
        hostClass: DEFAULT_CLS
    };
    class PrefabContainerDirective extends base.StylableComponent {
        static { this.initializeProps = registerProps(); }
        constructor(inj, viewport, explicitContext) {
            super(inj, WIDGET_CONFIG, explicitContext);
            this.viewport = viewport;
            base.styler(this.nativeElement, this);
            this.registerDestroyListener(this.viewport.subscribe("resize" /* ViewportEvent.RESIZE */, data => this.callback('resize', data)));
            this.registerDestroyListener(this.viewport.subscribe("orientationchange" /* ViewportEvent.ORIENTATION_CHANGE */, data => this.callback('orientationchange', data)));
        }
        callback(eventName, locals) {
            locals = lodashEs.assign({ widget: this }, locals);
            this.invokeEventCallback(eventName, locals);
        }
        ngOnAttach() {
            this.callback('attach');
        }
        ngOnDetach() {
            this.callback('detach');
        }
        ngOnDestroy() {
            this.callback('destroy');
            super.ngOnDestroy();
        }
        static { this.ɵfac = function PrefabContainerDirective_Factory(t) { return new (t || PrefabContainerDirective)(i0__namespace.ɵɵdirectiveInject(i0__namespace.Injector), i0__namespace.ɵɵdirectiveInject(i1__namespace.Viewport), i0__namespace.ɵɵdirectiveInject('EXPLICIT_CONTEXT', 8)); }; }
        static { this.ɵdir = /*@__PURE__*/ i0__namespace.ɵɵdefineDirective({ type: PrefabContainerDirective, selectors: [["", "wmPrefabContainer", ""]], features: [i0__namespace.ɵɵProvidersFeature([
                    base.provideAsWidgetRef(PrefabContainerDirective)
                ]), i0__namespace.ɵɵInheritDefinitionFeature] }); }
    }
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassMetadata(PrefabContainerDirective, [{
            type: i0.Directive,
            args: [{
                    selector: '[wmPrefabContainer]',
                    providers: [
                        base.provideAsWidgetRef(PrefabContainerDirective)
                    ]
                }]
        }], () => [{ type: i0__namespace.Injector }, { type: i1__namespace.Viewport }, { type: undefined, decorators: [{
                    type: i0.Inject,
                    args: ['EXPLICIT_CONTEXT']
                }, {
                    type: i0.Optional
                }] }], null); })();

    const components = [
        PrefabDirective,
        PrefabContainerDirective
    ];
    class PrefabModule {
        static { this.ɵfac = function PrefabModule_Factory(t) { return new (t || PrefabModule)(); }; }
        static { this.ɵmod = /*@__PURE__*/ i0__namespace.ɵɵdefineNgModule({ type: PrefabModule }); }
        static { this.ɵinj = /*@__PURE__*/ i0__namespace.ɵɵdefineInjector({ imports: [common.CommonModule,
                base.WmComponentsModule] }); }
    }
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassMetadata(PrefabModule, [{
            type: i0.NgModule,
            args: [{
                    imports: [
                        common.CommonModule,
                        base.WmComponentsModule
                    ],
                    declarations: [...components],
                    exports: [...components]
                }]
        }], null, null); })();
    (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0__namespace.ɵɵsetNgModuleScope(PrefabModule, { declarations: [PrefabDirective,
            PrefabContainerDirective], imports: [common.CommonModule,
            base.WmComponentsModule], exports: [PrefabDirective,
            PrefabContainerDirective] }); })();

    exports.PrefabContainerDirective = PrefabContainerDirective;
    exports.PrefabDirective = PrefabDirective;
    exports.PrefabModule = PrefabModule;

}));
