import { OverlayConfig, Overlay, OverlayModule } from '@angular/cdk/overlay';
import { CdkPortalOutlet, BasePortalOutlet, ComponentPortal, TemplatePortal, PortalInjector, PortalModule } from '@angular/cdk/portal';
import { Location, CommonModule } from '@angular/common';
import { Component, EventEmitter, ViewChild, ViewEncapsulation, InjectionToken, TemplateRef, Optional, Inject, Injector, Injectable, NgModule } from '@angular/core';
import { trigger, transition } from '@angular/animations';
import { fadeInY, fadeOutY } from '@ng-tangram/components/core';
import { Subject, Subscription } from 'rxjs';
import { filter, take } from 'rxjs/operators';
import { ESCAPE } from '@angular/cdk/keycodes';

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 NtModalBodyComponent = (function () {
    function NtModalBodyComponent() {
    }
    NtModalBodyComponent = __decorate([
        Component({
            selector: 'nt-modal-body',
            template: "<ng-content></ng-content>",
            host: {
                'class': 'nt-modal-body'
            }
        })
    ], NtModalBodyComponent);
    return NtModalBodyComponent;
}());

var __decorate$1 = (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 NtModalFooterComponent = (function () {
    function NtModalFooterComponent() {
    }
    NtModalFooterComponent = __decorate$1([
        Component({
            selector: 'nt-modal-footer',
            template: "<ng-content></ng-content>",
            host: {
                'class': 'nt-modal-footer'
            }
        })
    ], NtModalFooterComponent);
    return NtModalFooterComponent;
}());

var __decorate$2 = (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 NtModalHeaderComponent = (function () {
    function NtModalHeaderComponent() {
    }
    NtModalHeaderComponent = __decorate$2([
        Component({
            selector: 'nt-modal-header',
            template: "<ng-content></ng-content>",
            host: {
                class: 'nt-modal-header'
            }
        })
    ], NtModalHeaderComponent);
    return NtModalHeaderComponent;
}());

var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate$3 = (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;
};
function throwNtModalContentAlreadyAttachedError() {
    throw Error('Attempting to attach modal content after content is already attached');
}
var NtModalComponent = (function (_super) {
    __extends(NtModalComponent, _super);
    function NtModalComponent() {
        var _this = _super.call(this) || this;
        _this.state = 'enter';
        _this.animationStateChanged = new EventEmitter();
        return _this;
    }
    Object.defineProperty(NtModalComponent.prototype, "config", {
        get: function () { return this._config; },
        set: function (value) { this._config = value; },
        enumerable: true,
        configurable: true
    });
    NtModalComponent.prototype.attachComponentPortal = function (portal) {
        if (this._portalOutlet.hasAttached()) {
            throwNtModalContentAlreadyAttachedError();
        }
        return this._portalOutlet.attachComponentPortal(portal);
    };
    NtModalComponent.prototype.attachTemplatePortal = function (portal) {
        if (this._portalOutlet.hasAttached()) {
            throwNtModalContentAlreadyAttachedError();
        }
        return this._portalOutlet.attachTemplatePortal(portal);
    };
    NtModalComponent.prototype.onAnimationDone = function (event) {
        this.animationStateChanged.emit(event);
    };
    NtModalComponent.prototype.onAnimationStart = function (event) {
        this.animationStateChanged.emit(event);
    };
    NtModalComponent.prototype.exit = function () {
        this.state = 'exit';
    };
    __decorate$3([
        ViewChild(CdkPortalOutlet, { static: true })
    ], NtModalComponent.prototype, "_portalOutlet", void 0);
    NtModalComponent = __decorate$3([
        Component({
            selector: 'nt-modal',
            template: "\n    <ng-template cdkPortalOutlet></ng-template>\n    <button *ngIf=\"config.closable\" (click)=\"exit()\" class=\"close-button\" type=\"button\">\n      <span aria-hidden=\"true\">&times;</span>\n    </button>\n  ",
            encapsulation: ViewEncapsulation.None,
            animations: [
                trigger('fade', [
                    transition('void => *', fadeInY({ a: '-10%', b: 0 }, .2)),
                    transition('* => exit', fadeOutY({ a: 0, b: '-10%' }, .2))
                ])
            ],
            host: {
                'class': 'reveal',
                '[class.reveal-transparent]': '_config.transparent',
                '[style.width]': '_config.width',
                '[style.height]': '_config.height',
                '[@fade]': 'state',
                '(@fade.start)': 'onAnimationStart($event)',
                '(@fade.done)': 'onAnimationDone($event)',
            }
        })
    ], NtModalComponent);
    return NtModalComponent;
}(BasePortalOutlet));

var NtModalConfig = (function () {
    function NtModalConfig() {
        this.top = '80px';
        this.width = '600px';
        this.height = 'auto';
        this.maxWidth = '80vw';
        this.closable = true;
        this.data = {};
        this.panelClass = 'tm-file-preview-modal-panel';
        this.hasBackdrop = true;
        this.backdropClass = 'dark-backdrop';
        this.centerVertically = false;
        this.transparent = false;
    }
    return NtModalConfig;
}());

var uniqueId = 0;
var NtModalRef = (function () {
    function NtModalRef(_overlayRef, _containerInstance, location, id) {
        var _this = this;
        if (id === void 0) { id = "nt-modal-" + uniqueId++; }
        this._overlayRef = _overlayRef;
        this._containerInstance = _containerInstance;
        this.id = id;
        this.closable = this._containerInstance.config.closable;
        this._afterOpen = new Subject();
        this._afterClosed = new Subject();
        this._beforeClose = new Subject();
        this._locationChanges = Subscription.EMPTY;
        _containerInstance.animationStateChanged
            .pipe(filter(function (event) { return event.phaseName === 'done' && event.toState === 'enter'; }), take(1))
            .subscribe(function () {
            _this._afterOpen.next();
            _this._afterOpen.complete();
        });
        _containerInstance.animationStateChanged
            .pipe(filter(function (event) { return event.phaseName === 'done' && event.toState === 'exit'; }), take(1))
            .subscribe(function () {
            _this._overlayRef.dispose();
            _this._locationChanges.unsubscribe();
            _this._afterClosed.next(_this._result);
            _this._afterClosed.complete();
            _this.componentInstance = null;
        });
        _overlayRef.keydownEvents()
            .pipe(filter(function (event) { return event.keyCode === ESCAPE && !!_this.closable; }))
            .subscribe(function () { return _this.close(); });
        if (location) {
            this._locationChanges = location.subscribe(function () { return _this.close(); });
        }
    }
    NtModalRef.prototype.close = function (modalResult) {
        var _this = this;
        this._result = modalResult;
        this._containerInstance.animationStateChanged
            .pipe(filter(function (event) { return event.phaseName === 'start'; }), take(1))
            .subscribe(function () {
            _this._beforeClose.next(modalResult);
            _this._beforeClose.complete();
            _this._overlayRef.detachBackdrop();
        });
        this._containerInstance.exit();
    };
    NtModalRef.prototype.afterOpen = function () {
        return this._afterOpen.asObservable();
    };
    NtModalRef.prototype.afterClosed = function () {
        return this._afterClosed.asObservable();
    };
    NtModalRef.prototype.beforeClose = function () {
        return this._beforeClose.asObservable();
    };
    NtModalRef.prototype.backdropClick = function () {
        return this._overlayRef.backdropClick();
    };
    NtModalRef.prototype.keydownEvents = function () {
        return this._overlayRef.keydownEvents();
    };
    NtModalRef.prototype.updateSize = function (width, height) {
        if (width === void 0) { width = 'auto'; }
        if (height === void 0) { height = 'auto'; }
        this._getPositionStrategy().width(width).height(height);
        this._overlayRef.updatePosition();
        return this;
    };
    NtModalRef.prototype._getPositionStrategy = function () {
        return this._overlayRef.getConfig().positionStrategy;
    };
    return NtModalRef;
}());

var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __decorate$4 = (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 __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var NT_MODAL_DATA = new InjectionToken('nt-modal-data');
var NT_MODAL_DEFAULT_CONFIG = new InjectionToken('nt-model-default-config');
var NtModal = (function () {
    function NtModal(_location, _defaultConfig, _overlay, _injector) {
        this._location = _location;
        this._defaultConfig = _defaultConfig;
        this._overlay = _overlay;
        this._injector = _injector;
        this._openModalsAtThisLevel = [];
        this._afterAllClosedAtThisLevel = new Subject();
        this._afterOpenAtThisLevel = new Subject();
    }
    NtModal.prototype.open = function (content, config) {
        var _this = this;
        if (config === void 0) { config = {}; }
        config = __assign(__assign({}, this._defaultConfig || new NtModalConfig()), config);
        var overlayRef = this._createOverlay(config);
        var modalContainerRef = this._attachModalContainer(overlayRef, config);
        var modalRef = this._attachModalContent(content, modalContainerRef, overlayRef, config);
        this._openModalsAtThisLevel.push(modalRef);
        modalRef.afterClosed().subscribe(function () { return _this._removeOpenModal(modalRef); });
        this._afterOpenAtThisLevel.next(modalRef);
        return modalRef;
    };
    NtModal.prototype._createOverlay = function (config) {
        var overlayConfig = this._getOverlayConfig(config);
        return this._overlay.create(overlayConfig);
    };
    NtModal.prototype._attachModalContainer = function (overlayRef, config) {
        var containerPortal = new ComponentPortal(NtModalComponent, null);
        var containerRef = overlayRef.attach(containerPortal);
        containerRef.instance.config = config;
        return containerRef.instance;
    };
    NtModal.prototype._attachModalContent = function (content, modalContainer, overlayRef, config) {
        var modalRef = new NtModalRef(overlayRef, modalContainer, this._location, config.id);
        if (config.hasBackdrop) {
            overlayRef.backdropClick().subscribe(function () {
                if (modalRef.closable) {
                    modalRef.close();
                }
            });
        }
        if (content instanceof TemplateRef) {
            modalContainer.attachTemplatePortal(new TemplatePortal(content, null, { $implicit: config.data, modalRef: modalRef }));
        }
        else {
            var injector = this._createInjector(config, modalRef, modalContainer);
            var contentRef = modalContainer.attachComponentPortal(new ComponentPortal(content, undefined, injector));
            modalRef.componentInstance = contentRef.instance;
        }
        return modalRef;
    };
    NtModal.prototype._removeOpenModal = function (modalRef) {
        var index = this._openModalsAtThisLevel.indexOf(modalRef);
        if (index > -1) {
            this._openModalsAtThisLevel.splice(index, 1);
            if (!this._openModalsAtThisLevel.length) {
                this._afterAllClosedAtThisLevel.next();
            }
        }
    };
    NtModal.prototype._createInjector = function (config, modalRef, modalContainer) {
        var injector = config && config.viewContainerRef && config.viewContainerRef.injector;
        var injectionTokens = new WeakMap();
        injectionTokens.set(NtModalRef, modalRef);
        injectionTokens.set(NtModalComponent, modalContainer);
        injectionTokens.set(NT_MODAL_DATA, config.data);
        return new PortalInjector(injector || this._injector, injectionTokens);
    };
    NtModal.prototype._getOverlayConfig = function (config) {
        var positionStrategy = this._overlay.position()
            .global()
            .centerHorizontally();
        var overlayConfig = new OverlayConfig({
            hasBackdrop: config.hasBackdrop,
            backdropClass: config.backdropClass,
            panelClass: config.panelClass,
            scrollStrategy: this._overlay.scrollStrategies.block(),
            minWidth: config.minWidth,
            minHeight: config.minHeight,
            maxWidth: config.maxWidth,
            maxHeight: config.maxHeight,
            positionStrategy: config.centerVertically
                ? positionStrategy.centerVertically()
                : positionStrategy.top(config.top)
        });
        return overlayConfig;
    };
    NtModal.ctorParameters = function () { return [
        { type: Location, decorators: [{ type: Optional }] },
        { type: NtModalConfig, decorators: [{ type: Optional }, { type: Inject, args: [NT_MODAL_DEFAULT_CONFIG,] }] },
        { type: Overlay },
        { type: Injector }
    ]; };
    NtModal = __decorate$4([
        Injectable(),
        __param(0, Optional()),
        __param(1, Optional()), __param(1, Inject(NT_MODAL_DEFAULT_CONFIG))
    ], NtModal);
    return NtModal;
}());

var __decorate$5 = (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 EXPORTS_DECLARATIONS = [
    NtModalComponent,
    NtModalHeaderComponent,
    NtModalBodyComponent,
    NtModalFooterComponent
];
var NtModalModule = (function () {
    function NtModalModule() {
    }
    NtModalModule = __decorate$5([
        NgModule({
            imports: [
                CommonModule,
                PortalModule,
                OverlayModule
            ],
            declarations: EXPORTS_DECLARATIONS,
            exports: EXPORTS_DECLARATIONS,
            entryComponents: [NtModalComponent],
            providers: [NtModal]
        })
    ], NtModalModule);
    return NtModalModule;
}());

export { NT_MODAL_DATA, NT_MODAL_DEFAULT_CONFIG, NtModal, NtModalBodyComponent, NtModalComponent, NtModalConfig, NtModalFooterComponent, NtModalHeaderComponent, NtModalModule, NtModalRef, throwNtModalContentAlreadyAttachedError };
//# sourceMappingURL=modal.js.map
