(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs'), require('rxjs/operators'), require('@angular/cdk/keycodes'), require('@angular/animations'), require('@angular/cdk/portal'), require('@angular/core'), require('@ng-tangram/components/core'), require('@angular/cdk/overlay'), require('@angular/common')) :
    typeof define === 'function' && define.amd ? define('@ng-tangram/components/contextmenu', ['exports', 'rxjs', 'rxjs/operators', '@angular/cdk/keycodes', '@angular/animations', '@angular/cdk/portal', '@angular/core', '@ng-tangram/components/core', '@angular/cdk/overlay', '@angular/common'], factory) :
    (global = global || self, factory((global.nt = global.nt || {}, global.nt.components = global.nt.components || {}, global.nt.components.contextmenu = {}), global.rxjs, global.rxjs.operators, global.ng.cdk.keycodes, global.ng.animations, global.ng.cdk.portal, global.ng.core, global.nt.components.core, global.ng.cdk.overlay, global.ng.common));
}(this, (function (exports, rxjs, operators, keycodes, animations, portal, core, core$1, overlay, common) { 'use strict';

    var uniqueId = 0;
    var NtContextMenuRef = (function () {
        function NtContextMenuRef(_overlayRef, _containerInstance, location, id) {
            var _this = this;
            if (id === void 0) { id = "nt-contextmenu-" + uniqueId++; }
            this._overlayRef = _overlayRef;
            this._containerInstance = _containerInstance;
            this.id = id;
            this._afterOpen = new rxjs.Subject();
            this._afterClosed = new rxjs.Subject();
            this._beforeClose = new rxjs.Subject();
            this._locationChanges = rxjs.Subscription.EMPTY;
            NtContextMenuRef.currentRef = this;
            _containerInstance.animationStateChanged
                .pipe(operators.filter(function (event) { return event.phaseName === 'done' && event.toState === 'enter'; }), operators.take(1))
                .subscribe(function () {
                _this._afterOpen.next();
                _this._afterOpen.complete();
            });
            _containerInstance.animationStateChanged
                .pipe(operators.filter(function (event) { return event.phaseName === 'done' && event.toState === 'exit'; }), operators.take(1))
                .subscribe(function () {
                _this._overlayRef.dispose();
                _this._locationChanges.unsubscribe();
                _this._afterClosed.next();
                _this._afterClosed.complete();
                _this.templateInstance = null;
            });
            _overlayRef.keydownEvents()
                .pipe(operators.filter(function (event) { return event.keyCode === keycodes.ESCAPE; }))
                .subscribe(function () { return _this.close(); });
            if (location) {
                this._locationChanges = location.subscribe(function () { return _this.close(); });
            }
        }
        NtContextMenuRef.prototype.close = function () {
            var _this = this;
            this._containerInstance.animationStateChanged
                .pipe(operators.filter(function (event) { return event.phaseName === 'start'; }), operators.take(1))
                .subscribe(function () {
                _this._beforeClose.next();
                _this._beforeClose.complete();
                _this._overlayRef.detachBackdrop();
            });
            this._containerInstance.exit();
        };
        NtContextMenuRef.prototype.afterOpen = function () {
            return this._afterOpen.asObservable();
        };
        NtContextMenuRef.prototype.afterClosed = function () {
            return this._afterClosed.asObservable();
        };
        NtContextMenuRef.prototype.beforeClose = function () {
            return this._beforeClose.asObservable();
        };
        NtContextMenuRef.prototype.backdropClick = function () {
            return this._overlayRef.backdropClick();
        };
        NtContextMenuRef.prototype.keydownEvents = function () {
            return this._overlayRef.keydownEvents();
        };
        NtContextMenuRef.prototype._getPositionStrategy = function () {
            return this._overlayRef.getConfig().positionStrategy;
        };
        return NtContextMenuRef;
    }());

    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 = (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 NtContextMenuComponent = (function (_super) {
        __extends(NtContextMenuComponent, _super);
        function NtContextMenuComponent() {
            var _this = _super.call(this) || this;
            _this.state = 'enter';
            _this.animationStateChanged = new core.EventEmitter();
            return _this;
        }
        NtContextMenuComponent.prototype.attachComponentPortal = function (portal) {
            if (this._portalOutlet.hasAttached()) {
                throw new Error('Attempting to attach context menu content after content is already attached');
            }
            return this._portalOutlet.attachComponentPortal(portal);
        };
        NtContextMenuComponent.prototype.attachTemplatePortal = function (portal) {
            if (this._portalOutlet.hasAttached()) {
                throw new Error('Attempting to attach context menu content after content is already attached');
            }
            return this._portalOutlet.attachTemplatePortal(portal);
        };
        NtContextMenuComponent.prototype.onAnimationDone = function (event) {
            this.animationStateChanged.emit(event);
        };
        NtContextMenuComponent.prototype.onAnimationStart = function (event) {
            this.animationStateChanged.emit(event);
        };
        NtContextMenuComponent.prototype.exit = function () {
            this.state = 'exit';
        };
        NtContextMenuComponent.prototype._onInteractionEvent = function (event) {
            event.stopPropagation();
            return false;
        };
        __decorate([
            core.ViewChild(portal.CdkPortalOutlet, { static: true })
        ], NtContextMenuComponent.prototype, "_portalOutlet", void 0);
        NtContextMenuComponent = __decorate([
            core.Component({
                selector: 'nt-contextmenu',
                template: "\n    <div class=\"nt-overlay-container start-bottom-start-top\">\n      <div class=\"nt-overlay-shadow\"></div>\n      <div class=\"nt-overlay-pane\">\n        <ng-template cdkPortalOutlet></ng-template>\n      </div>\n    </div>\n  ",
                encapsulation: core.ViewEncapsulation.None,
                animations: [
                    animations.trigger('fade', [
                        animations.transition('void => *', core$1.fadeIn(.05)),
                        animations.transition('* => exit', core$1.fadeOut(.1))
                    ])
                ],
                host: {
                    'class': 'nt-contextmenu',
                    '(contextmenu)': '_onInteractionEvent($event)',
                    '[@fade]': 'state',
                    '(@fade.start)': 'onAnimationStart($event)',
                    '(@fade.done)': 'onAnimationDone($event)',
                }
            })
        ], NtContextMenuComponent);
        return NtContextMenuComponent;
    }(portal.BasePortalOutlet));

    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 __param = (this && this.__param) || function (paramIndex, decorator) {
        return function (target, key) { decorator(target, key, paramIndex); }
    };
    var NtContextMenuDirective = (function () {
        function NtContextMenuDirective(_location, _elementRef, _overlay, _overlayContainer) {
            this._location = _location;
            this._elementRef = _elementRef;
            this._overlay = _overlay;
            this._overlayContainer = _overlayContainer;
        }
        Object.defineProperty(NtContextMenuDirective.prototype, "template", {
            get: function () { return this._template; },
            set: function (value) {
                if (value instanceof core.TemplateRef) {
                    this._template = value;
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NtContextMenuDirective.prototype, "data", {
            get: function () { return this._data; },
            set: function (value) { this._data = value; },
            enumerable: true,
            configurable: true
        });
        NtContextMenuDirective.prototype._open = function (event) {
            if (NtContextMenuRef.currentRef) {
                NtContextMenuRef.currentRef.close();
            }
            if (event) {
                var overlayRef = this._createOverlay(event.offsetX, event.offsetY, event.target);
                var menuContainerRef = this._attachModalContainer(overlayRef);
                var menuRef = this._attachModalContent(this.template, menuContainerRef, overlayRef);
            }
            return false;
        };
        NtContextMenuDirective.prototype._createOverlay = function (x, y, element) {
            var elementRef = this._elementRef;
            if (element && element !== elementRef.nativeElement) {
                elementRef = new core.ElementRef(element);
            }
            var overlayConfig = this._getOverlayConfig(x, y, elementRef);
            return this._overlay.create(overlayConfig);
        };
        NtContextMenuDirective.prototype._attachModalContainer = function (overlayRef) {
            var containerPortal = new portal.ComponentPortal(NtContextMenuComponent, null);
            var containerRef = overlayRef.attach(containerPortal);
            return containerRef.instance;
        };
        NtContextMenuDirective.prototype._attachModalContent = function (content, menuContainer, overlayRef) {
            var menuRef = new NtContextMenuRef(overlayRef, menuContainer, this._location);
            var overlayClose = function () {
                menuRef.close();
                return false;
            };
            overlayRef.backdropClick().subscribe(overlayClose);
            if (overlayRef.backdropElement) {
                overlayRef.backdropElement.oncontextmenu = overlayClose;
            }
            menuContainer.attachTemplatePortal(new portal.TemplatePortal(content, null, { $implicit: this.data, menuRef: menuRef }));
            return menuRef;
        };
        NtContextMenuDirective.prototype._getOverlayConfig = function (x, y, elementRef) {
            var position = {
                originX: 'start', originY: 'top',
                overlayX: 'start', overlayY: 'top'
            };
            var positionStrategy = this._overlay
                .position()
                .flexibleConnectedTo(elementRef)
                .withPositions([position])
                .withDefaultOffsetX(x)
                .withDefaultOffsetY(y);
            var overlayConfig = new overlay.OverlayConfig({
                scrollStrategy: this._overlay.scrollStrategies.block(),
                positionStrategy: positionStrategy,
                hasBackdrop: true
            });
            return overlayConfig;
        };
        NtContextMenuDirective.ctorParameters = function () { return [
            { type: common.Location, decorators: [{ type: core.Optional }] },
            { type: core.ElementRef },
            { type: overlay.Overlay },
            { type: overlay.OverlayContainer }
        ]; };
        __decorate$1([
            core.Input()
        ], NtContextMenuDirective.prototype, "template", null);
        __decorate$1([
            core.Input()
        ], NtContextMenuDirective.prototype, "data", null);
        NtContextMenuDirective = __decorate$1([
            core.Directive({
                selector: '[ntContextMenu]',
                host: {
                    '(contextmenu)': '_open($event)'
                }
            }),
            __param(0, core.Optional())
        ], NtContextMenuDirective);
        return NtContextMenuDirective;
    }());

    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 NtContextMenuModule = (function () {
        function NtContextMenuModule() {
        }
        NtContextMenuModule = __decorate$2([
            core.NgModule({
                imports: [
                    common.CommonModule,
                    portal.PortalModule,
                    overlay.OverlayModule
                ],
                exports: [NtContextMenuDirective],
                declarations: [
                    NtContextMenuComponent,
                    NtContextMenuDirective
                ]
            })
        ], NtContextMenuModule);
        return NtContextMenuModule;
    }());

    exports.NtContextMenuComponent = NtContextMenuComponent;
    exports.NtContextMenuDirective = NtContextMenuDirective;
    exports.NtContextMenuModule = NtContextMenuModule;
    exports.NtContextMenuRef = NtContextMenuRef;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=contextmenu.umd.js.map
