import { InjectionToken, EventEmitter, ChangeDetectorRef, ElementRef, Renderer2, Inject, PLATFORM_ID, Optional, Input, Output, Component, ViewEncapsulation, ChangeDetectionStrategy, Directive, NgModule } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { trigger, transition } from '@angular/animations';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { isPlatformBrowser, CommonModule } from '@angular/common';
import { fromOutsideClick, slideX, slideY } from '@ng-tangram/components/core';

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 __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
const NT_DRAWER_CONTAINER = new InjectionToken('nt-drawer-container');
let uniqueId = 0;
let NtDrawerComponent = class NtDrawerComponent {
    constructor(_changeDetectorRef, _element, _renderer, _platformId, container) {
        this._changeDetectorRef = _changeDetectorRef;
        this._element = _element;
        this._renderer = _renderer;
        this._platformId = _platformId;
        this.id = `nt-drawer-${uniqueId++}`;
        this._destory = new Subject();
        this._backdrop = false;
        this.state = 'closed';
        this.afterOpen = new EventEmitter();
        this.afterClosed = new EventEmitter();
        this.beforeOpen = new EventEmitter();
        this.beforeClosed = new EventEmitter();
        if (isPlatformBrowser(_platformId)) {
            this._initContainerAndStyles(container);
        }
        this._changePlacementValueAndStyle('left');
    }
    get backdrop() { return this._backdrop; }
    set backdrop(value) {
        this._backdrop = coerceBooleanProperty(value);
        if (this._backdrop) {
            this._createBackdropOverlay();
        }
        else {
            this._removeBackdropOverlay();
        }
    }
    get placement() { return this._placement; }
    set placement(value) {
        this._changePlacementValueAndStyle(value);
    }
    ngAfterViewInit() { }
    ngOnDestroy() {
        if (isPlatformBrowser(this._platformId)) {
            this._renderer.removeClass(this._container, `${this.id}-container`);
        }
        this._destory.next();
        this._destory.complete();
        this._unsubscribeOutsideClickEvent();
    }
    open() {
        this.state = this.placement;
    }
    close() {
        this.state = 'closed';
    }
    onAnimationDone(event) {
        if (event.fromState === 'void') {
            return;
        }
        if (event.toState !== 'closed') {
            this._subscribeOutsideClickEvent();
            this.afterOpen.emit();
        }
        else {
            this.afterClosed.emit();
        }
    }
    onAnimationStart(event) {
        if (event.fromState === 'void') {
            return;
        }
        if (event.toState === 'closed') {
            this._unsubscribeOutsideClickEvent();
            this._disattachBackdropOverlay();
            this.beforeClosed.emit();
        }
        else {
            this._attachBackdropOverlay();
            this.beforeOpen.emit();
        }
    }
    _changePlacementValueAndStyle(placement) {
        if (this._placement) {
            this._renderer.removeClass(this._element.nativeElement, this._placement);
        }
        this._renderer.addClass(this._element.nativeElement, this._placement = placement);
    }
    _initContainerAndStyles(container) {
        this._container = container ? container.element : document.body;
        if (this._container !== document.body) {
            this._renderer.addClass(this._element.nativeElement, 'nested');
        }
        this._renderer.addClass(this._container, `${this.id}-container`);
    }
    _createBackdropOverlay() {
        this._backdropElement = this._renderer.createElement('div');
        this._renderer.addClass(this._backdropElement, 'nt-drawer-backdrop');
        this._renderer.addClass(this._backdropElement, `${this.id}-backdrop`);
    }
    _removeBackdropOverlay() {
        this._disattachBackdropOverlay();
        this._backdropElement = null;
    }
    _attachBackdropOverlay() {
        if (this.backdrop && this._backdropElement) {
            this._renderer.appendChild(this._container, this._backdropElement);
            this._renderer.addClass(this._container, 'nt-drawer-scrollblock');
        }
    }
    _disattachBackdropOverlay() {
        if (this._backdropElement) {
            this._renderer.removeChild(this._container, this._backdropElement);
            this._renderer.removeClass(this._container, 'nt-drawer-scrollblock');
        }
    }
    _subscribeOutsideClickEvent() {
        this._outsideClickSubscription = fromOutsideClick([this._element.nativeElement], this._container)
            .pipe(takeUntil(this._destory))
            .subscribe(_ => this.close());
    }
    _unsubscribeOutsideClickEvent() {
        if (this._outsideClickSubscription) {
            this._outsideClickSubscription.unsubscribe();
            this._outsideClickSubscription = null;
        }
    }
};
NtDrawerComponent.ctorParameters = () => [
    { type: ChangeDetectorRef },
    { type: ElementRef },
    { type: Renderer2 },
    { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] },
    { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NT_DRAWER_CONTAINER,] }] }
];
__decorate([
    Input()
], NtDrawerComponent.prototype, "backdrop", null);
__decorate([
    Input()
], NtDrawerComponent.prototype, "placement", null);
__decorate([
    Output()
], NtDrawerComponent.prototype, "afterOpen", void 0);
__decorate([
    Output()
], NtDrawerComponent.prototype, "afterClosed", void 0);
__decorate([
    Output()
], NtDrawerComponent.prototype, "beforeOpen", void 0);
__decorate([
    Output()
], NtDrawerComponent.prototype, "beforeClosed", void 0);
NtDrawerComponent = __decorate([
    Component({
        selector: 'nt-drawer',
        template: `<ng-content></ng-content>`,
        encapsulation: ViewEncapsulation.None,
        changeDetection: ChangeDetectionStrategy.OnPush,
        animations: [
            trigger('slide', [
                transition('closed => left', slideX({ a: '-100%', b: 0 }, .4)),
                transition('closed => right', slideX({ a: '100%', b: 0 }, .4)),
                transition('closed => top', slideY({ a: '-100%', b: 0 }, .4)),
                transition('closed => bottom', slideY({ a: '100%', b: 0 }, .4)),
                transition('left => closed', slideX({ a: 0, b: '-100%' }, .4)),
                transition('right => closed', slideX({ a: 0, b: '100%' }, .4)),
                transition('top => closed', slideY({ a: 0, b: '-100%' }, .4)),
                transition('bottom => closed', slideY({ a: 0, b: '100%' }, .4))
            ])
        ],
        host: {
            'class': 'nt-drawer',
            '[class.opened]': 'state !== "closed"',
            '[class.backdroped]': 'backdrop',
            '[@slide]': 'state',
            '(@slide.start)': 'onAnimationStart($event)',
            '(@slide.done)': 'onAnimationDone($event)',
        }
    }),
    __param(3, Inject(PLATFORM_ID)),
    __param(4, Optional()), __param(4, Inject(NT_DRAWER_CONTAINER))
], NtDrawerComponent);

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 NtDrawerContainerDirective_1;
let NtDrawerContainerDirective = NtDrawerContainerDirective_1 = class NtDrawerContainerDirective {
    constructor(_element) {
        this.element = _element.nativeElement;
    }
};
NtDrawerContainerDirective.ctorParameters = () => [
    { type: ElementRef }
];
NtDrawerContainerDirective = NtDrawerContainerDirective_1 = __decorate$1([
    Directive({
        selector: '[nt-drawer-container]',
        providers: [
            { provide: NT_DRAWER_CONTAINER, useExisting: NtDrawerContainerDirective_1 }
        ],
        host: {
            'class': 'nt-drawer-container'
        }
    })
], NtDrawerContainerDirective);

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;
};
let NtDrawerModule = class NtDrawerModule {
};
NtDrawerModule = __decorate$2([
    NgModule({
        imports: [
            CommonModule
        ],
        exports: [
            NtDrawerComponent,
            NtDrawerContainerDirective
        ],
        declarations: [
            NtDrawerComponent,
            NtDrawerContainerDirective
        ]
    })
], NtDrawerModule);

export { NT_DRAWER_CONTAINER, NtDrawerComponent, NtDrawerContainerDirective, NtDrawerModule };
//# sourceMappingURL=drawer.js.map
