var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
import { ComponentFactoryResolver, Inject, Injectable, Injector, TemplateRef, } from '@angular/core';
import { filter } from 'rxjs/operators';
import { ElComponentPortal, ElOverlayPositionBuilder, } from '../cdk/overlay/mapping';
import { ElOverlayService } from '../cdk/overlay/overlay-service';
import { ElBlockScrollStrategyAdapter } from '../cdk/adapter/block-scroll-strategy-adapter';
import { EL_WINDOW_CONFIG, EL_WINDOW_CONTENT, EL_WINDOW_CONTEXT, ElWindowConfig, ElWindowState, } from './window.options';
import { ElWindowRef } from './window-ref';
import { ElWindowsContainerComponent } from './windows-container.component';
import { ElWindowComponent } from './window.component';
import { EL_DOCUMENT } from '../../theme.options';
/**
 * The `ElWindowService` can be used to open windows.
 *
 * @stacked-example(Showcase, window/window-showcase.component)
 *
 * ### Installation
 *
 * Import `ElWindowModule` to your app module.
 * ```ts
 * @NgModule({
 *   imports: [
 *     // ...
 *     ElWindowModule.forRoot(config),
 *   ],
 * })
 * export class AppModule { }
 * ```
 *
 * If you are using it in a lazy loaded module than you have to install `ElWindowModule.forChild`:
 * ```ts
 * @NgModule({
 *   imports: [
 *     // ...
 *     ElWindowModule.forChild(config),
 *   ],
 * })
 * export class LazyLoadedModule { }
 * ```
 *
 * ### Usage
 *
 * A new window can be opened by calling the `open` method with a component or template to be loaded
 * and an optional configuration.
 * `open` method will return `ElWindowRef` that can be used for the further manipulations.
 *
 * ```ts
 * const windowRef = this.windowService.open(MyComponent, { ... });
 * ```
 *
 * `ElWindowRef` gives you ability manipulate opened window.
 * Also, you can inject `ElWindowRef` inside provided component which rendered in window.
 *
 * ```ts
 * this.windowService.open(MyWindowComponent, { ... });
 *
 * // my.component.ts
 * constructor(protected windowRef: ElWindowRef) {
 * }
 *
 * minimize() {
 *   this.windowRef.minimize();
 * }
 *
 * close() {
 *   this.windowRef.close();
 * }
 * ```
 *
 * Instead of component you can create window from TemplateRef. As usual you can access context provided via config
 * via `let-` variables. Also you can get reference to the `ElWindowRef` in context's `windowRef` property.
 *
 * @stacked-example(Window content from TemplateRef, window/template-window.component)
 *
 * ### Configuration
 *
 * As mentioned above, `open` method of the `ElWindowService` may receive optional configuration options.
 * Also, you can modify default windows configuration through `ElWindowModule.forRoot({ ... })`.
 * You can read about all available options on [API tab](docs/components/window/api#elwindowconfig).
 *
 * @stacked-example(Configuration, window/windows-backdrop.component)
 */
var ElWindowService = /** @class */ (function () {
    function ElWindowService(componentFactoryResolver, overlayService, overlayPositionBuilder, blockScrollStrategy, defaultWindowsConfig, cfr, document) {
        this.componentFactoryResolver = componentFactoryResolver;
        this.overlayService = overlayService;
        this.overlayPositionBuilder = overlayPositionBuilder;
        this.blockScrollStrategy = blockScrollStrategy;
        this.defaultWindowsConfig = defaultWindowsConfig;
        this.cfr = cfr;
        this.openWindows = [];
        this.document = document;
    }
    /**
     * Opens new window.
     * @param windowContent
     * @param windowConfig
     * */
    ElWindowService.prototype.open = function (windowContent, windowConfig) {
        if (windowConfig === void 0) { windowConfig = {}; }
        if (this.shouldCreateWindowsContainer()) {
            this.createWindowsContainer();
        }
        var config = new ElWindowConfig(this.defaultWindowsConfig, windowConfig);
        var windowRef = new ElWindowRef(config);
        windowRef.componentRef = this.appendWindow(windowContent, config, windowRef);
        this.openWindows.push(windowRef);
        this.subscribeToEvents(windowRef);
        return windowRef;
    };
    ElWindowService.prototype.shouldCreateWindowsContainer = function () {
        if (this.windowsContainerViewRef) {
            var containerEl = this.windowsContainerViewRef.element.nativeElement;
            return !this.document.body.contains(containerEl);
        }
        return true;
    };
    ElWindowService.prototype.createWindowsContainer = function () {
        if (this.overlayRef) {
            this.overlayRef.dispose();
        }
        this.overlayRef = this.overlayService.create({
            scrollStrategy: this.overlayService.scrollStrategies.noop(),
            positionStrategy: this.overlayPositionBuilder.global().bottom().right(),
            hasBackdrop: true,
        });
        var windowsContainerPortal = new ElComponentPortal(ElWindowsContainerComponent, null, null, this.cfr);
        var overlayRef = this.overlayRef.attach(windowsContainerPortal);
        this.windowsContainerViewRef = overlayRef.instance.viewContainerRef;
    };
    ElWindowService.prototype.appendWindow = function (content, config, windowRef) {
        var context = content instanceof TemplateRef
            ? { $implicit: config.context, windowRef: windowRef }
            : config.context;
        var providers = [
            { provide: EL_WINDOW_CONTENT, useValue: content },
            { provide: EL_WINDOW_CONTEXT, useValue: context },
            { provide: ElWindowConfig, useValue: config },
            { provide: ElWindowRef, useValue: windowRef },
        ];
        var parentInjector = config.viewContainerRef
            ? config.viewContainerRef.injector
            : this.windowsContainerViewRef.injector;
        var injector = Injector.create({ parent: parentInjector, providers: providers });
        var windowFactory = this.componentFactoryResolver.resolveComponentFactory(ElWindowComponent);
        var ref = this.windowsContainerViewRef.createComponent(windowFactory, null, injector);
        ref.instance.cfr = this.cfr;
        ref.changeDetectorRef.detectChanges();
        return ref;
    };
    ElWindowService.prototype.subscribeToEvents = function (windowRef) {
        var _this = this;
        if (windowRef.config.closeOnBackdropClick) {
            this.overlayRef.backdropClick().subscribe(function () { return windowRef.close(); });
        }
        if (windowRef.config.closeOnEsc) {
            this.overlayRef.keydownEvents()
                .pipe(filter(function (event) { return event.keyCode === 27; }))
                .subscribe(function () { return windowRef.close(); });
        }
        windowRef.stateChange.subscribe(function () { return _this.checkAndUpdateOverlay(); });
        windowRef.onClose.subscribe(function () {
            _this.openWindows.splice(_this.openWindows.indexOf(windowRef), 1);
            _this.checkAndUpdateOverlay();
        });
    };
    ElWindowService.prototype.checkAndUpdateOverlay = function () {
        var fullScreenWindows = this.openWindows.filter(function (w) { return w.state === ElWindowState.FULL_SCREEN; });
        if (fullScreenWindows.length > 0) {
            this.blockScrollStrategy.enable();
        }
        else {
            this.blockScrollStrategy.disable();
        }
        if (fullScreenWindows.some(function (w) { return w.config.hasBackdrop; })) {
            this.overlayRef.backdropElement.removeAttribute('hidden');
        }
        else {
            this.overlayRef.backdropElement.setAttribute('hidden', '');
        }
    };
    ElWindowService = __decorate([
        Injectable(),
        __param(4, Inject(EL_WINDOW_CONFIG)),
        __param(6, Inject(EL_DOCUMENT)),
        __metadata("design:paramtypes", [ComponentFactoryResolver,
            ElOverlayService,
            ElOverlayPositionBuilder,
            ElBlockScrollStrategyAdapter,
            ElWindowConfig,
            ComponentFactoryResolver, Object])
    ], ElWindowService);
    return ElWindowService;
}());
export { ElWindowService };
//# sourceMappingURL=window.service.js.map