import PortalPlugin from 'portal-vue';
import Vue from 'vue';
import { BackdropMode } from '../../mixins/portal/portal';
import uuid from '../uuid/uuid';
var BACKDROP_ID = 'mBackdropID';
var BACKDROP_CLASS_NAME = 'm-backdrop';
var BACKDROP_STYLE_TRANSITION = 'opacity ease';
var BACKDROP_STYLE_TRANSITION_SLOW_DURATION = 600;
var BACKDROP_STYLE_TRANSITION_FAST_DURATION = 300;
var BACKDROP_STYLE_POSITION = 'fixed';
var BACKDROP_STYLE_POSITION_VALUE = '0';
var BACKDROP_STYLE_BACKGROUND = '#000';
var BACKDROP_STYLE_OPACITY = '0';
var BACKDROP_STYLE_OPACITY_VISIBLE = '0.7';
var BACKDROP_STYLE_OPACITY_NOT_VISIBLE = '0';
var Z_INDEZ_DEFAULT = 100;
var DONE_EVENT_DURATION = 100;
var Modul = /** @class */ (function () {
    function Modul(options) {
        var _this = this;
        this.options = options;
        this.htmlEl = document.querySelector('html');
        this.bodyEl = document.querySelector('body');
        this.event = new Vue();
        this.scrollPosition = 0;
        this.stopScrollPosition = 0;
        this.scrollDown = false;
        this.scrollUp = true;
        this.windowZIndex = Z_INDEZ_DEFAULT;
        this.windowStack = [];
        this.windowStackMap = {};
        this.lastScrollPosition = 0;
        this.internalScrollActive = true;
        this.scrollPosition = window.pageYOffset;
        window.addEventListener('click', function (e) { return _this.onClick(e); });
        window.addEventListener('scroll', function (e) { return _this.onScroll(e); });
        window.addEventListener('resize', function (e) { return _this.onResize(e); });
    }
    /**
     * @deprecated Don't use this function to emit events between two components
     */
    Modul.prototype.updateAfterResize = function () {
        this.event.$emit('updateAfterResize');
    };
    Modul.prototype.pushElement = function (element, backdropMode, viewportIsSmall) {
        var stackId = uuid.generate();
        var backdropIndex = undefined;
        var scrollId = undefined;
        if (backdropMode !== BackdropMode.None) {
            this.scrollActive = false;
            scrollId = uuid.generate();
        }
        if (backdropMode === BackdropMode.BackdropFast || backdropMode === BackdropMode.BackdropSlow) {
            backdropIndex = this.ensureBackdrop(viewportIsSmall);
        }
        var index = this.windowStack.push(stackId) - 1;
        this.windowStackMap[stackId] = {
            stackIndex: index,
            backdropIndex: backdropIndex,
            backdropIsFast: backdropMode === BackdropMode.BackdropFast,
            scrollId: scrollId
        };
        this.windowZIndex++;
        element.style.zIndex = String(this.windowZIndex);
        return stackId;
    };
    Modul.prototype.popElement = function (stackId) {
        if (stackId && this.windowStack) {
            if (this.peekElement() === stackId) {
                this.windowZIndex--;
                this.windowStack.pop();
            }
            else {
                var stackElement_1 = this.windowStackMap[stackId];
                if (stackElement_1 && stackElement_1.stackIndex !== undefined) {
                    this.windowStack[stackElement_1.stackIndex] = undefined;
                }
            }
            while (this.windowStack.length > 0 && this.windowStack[this.windowStack.length - 1] === undefined) {
                this.windowZIndex--;
                this.windowStack.pop();
            }
            var stackElement = this.windowStackMap[stackId];
            if (stackElement && (stackElement.backdropIndex || stackElement.scrollId)) {
                this.removeBackdrop(!stackElement.backdropIsFast);
            }
            if (this.windowZIndex < Z_INDEZ_DEFAULT) {
                Vue.prototype.$log.warn('$modul: Invalid window ref count');
                this.windowZIndex = Z_INDEZ_DEFAULT;
            }
            delete this.windowStackMap[stackId];
        }
    };
    Modul.prototype.peekElement = function () {
        return this.windowStack.length > 0 ? this.windowStack[this.windowStack.length - 1] : undefined;
    };
    Modul.prototype.onClick = function (event) {
        this.event.$emit('click', event);
    };
    Modul.prototype.onScroll = function (event) {
        var _this = this;
        if (this.scrollActive) {
            this.scrollPosition = window.pageYOffset;
            if (this.lastScrollPosition > this.scrollPosition) {
                this.scrollUp = true;
                this.scrollDown = false;
            }
            else {
                this.scrollUp = false;
                this.scrollDown = true;
            }
            this.lastScrollPosition = this.scrollPosition;
            this.event.$emit('scroll', event);
            clearTimeout(this.doneScrollEvent);
            this.doneScrollEvent = setTimeout(function () {
                _this.event.$emit('scrollDone', event);
            }, DONE_EVENT_DURATION);
        }
    };
    Modul.prototype.onResize = function (event) {
        var _this = this;
        this.event.$emit('resize', event);
        clearTimeout(this.doneResizeEvent);
        this.doneResizeEvent = setTimeout(function () {
            _this.event.$emit('resizeDone', event);
        }, DONE_EVENT_DURATION);
    };
    Modul.prototype.ensureBackdrop = function (viewportIsSmall) {
        var _this = this;
        if (!this.backdropElement) {
            var element = document.createElement('div');
            var id = BACKDROP_ID + '-' + uuid.generate();
            element.setAttribute('id', id);
            element.setAttribute('class', BACKDROP_CLASS_NAME);
            element.setAttribute('aria-hidden', 'true');
            // tslint:disable-next-line: deprecation
            element.style.webkitTransition = BACKDROP_STYLE_TRANSITION;
            element.style.transition = BACKDROP_STYLE_TRANSITION;
            element.style.position = BACKDROP_STYLE_POSITION;
            element.style.top = BACKDROP_STYLE_POSITION_VALUE;
            element.style.right = BACKDROP_STYLE_POSITION_VALUE;
            element.style.bottom = BACKDROP_STYLE_POSITION_VALUE;
            element.style.left = BACKDROP_STYLE_POSITION_VALUE;
            element.style.zIndex = String(this.windowZIndex);
            element.style.background = BACKDROP_STYLE_BACKGROUND;
            element.style.opacity = BACKDROP_STYLE_OPACITY;
            this.bodyEl.appendChild(element);
            this.backdropElement = document.querySelector('#' + id);
            var duration = String(BACKDROP_STYLE_TRANSITION_FAST_DURATION / 1000) + 's';
            // tslint:disable-next-line: deprecation
            this.backdropElement.style.webkitTransitionDuration = duration;
            this.backdropElement.style.transitionDuration = duration;
            setTimeout(function () {
                if (_this.backdropElement) {
                    _this.backdropElement.style.opacity = BACKDROP_STYLE_OPACITY_VISIBLE;
                }
            }, 5);
        }
        else {
            this.backdropElement.style.zIndex = String(this.windowZIndex);
        }
        return this.windowZIndex;
    };
    Modul.prototype.removeBackdrop = function (slow) {
        var lastBackdropIndex = undefined;
        var lastScrollId = undefined;
        for (var i = this.windowStack.length - 1; i >= 0; i--) {
            var stackId = this.windowStack[i];
            if (stackId) {
                if (!lastBackdropIndex && this.windowStackMap[stackId].backdropIndex) {
                    lastBackdropIndex = this.windowStackMap[stackId].backdropIndex;
                }
                if (!lastScrollId && this.windowStackMap[stackId].scrollId) {
                    lastScrollId = this.windowStackMap[stackId].scrollId;
                }
                if (lastBackdropIndex && lastScrollId) {
                    break;
                }
            }
        }
        if (!lastScrollId && lastBackdropIndex) {
            throw new Error('Backdrop should always hide scroll bar');
        }
        if (!lastScrollId && !this.backdropElement) {
            this.scrollActive = true;
        }
        else if (!lastBackdropIndex) {
            var speed = slow ? BACKDROP_STYLE_TRANSITION_SLOW_DURATION : BACKDROP_STYLE_TRANSITION_FAST_DURATION;
            if (this.backdropElement) {
                var duration = String(speed / 1000) + 's';
                // tslint:disable-next-line: deprecation
                this.backdropElement.style.webkitTransitionDuration = duration;
                this.backdropElement.style.transitionDuration = duration;
                this.backdropElement.style.opacity = BACKDROP_STYLE_OPACITY_NOT_VISIBLE;
                var b_1 = this.backdropElement;
                this.backdropElement = undefined;
                if (!lastScrollId) {
                    this.scrollActive = true;
                }
                setTimeout(function () {
                    if (b_1 && b_1.parentNode) {
                        b_1.parentNode.removeChild(b_1);
                    }
                }, speed);
            }
        }
        else if (this.backdropElement) {
            this.backdropElement.style.zIndex = String(lastBackdropIndex);
        }
        else {
            throw new Error('backdropElement cannot be null');
        }
    };
    Object.defineProperty(Modul.prototype, "scrollActive", {
        get: function () {
            return this.internalScrollActive;
        },
        set: function (scrollActive) {
            if (scrollActive) {
                this.htmlEl.style.removeProperty('position');
                this.htmlEl.style.removeProperty('top');
                this.htmlEl.style.removeProperty('right');
                this.htmlEl.style.removeProperty('left');
                this.htmlEl.style.removeProperty('bottom');
                this.htmlEl.style.removeProperty('height');
                this.bodyEl.style.removeProperty('margin-top');
                window.scrollTo(0, this.stopScrollPosition);
                if (this.htmlEl.style.length === 0) {
                    this.htmlEl.removeAttribute('style');
                }
                if (this.bodyEl.style.length === 0) {
                    this.bodyEl.removeAttribute('style');
                }
            }
            else {
                this.stopScrollPosition = this.scrollPosition;
                this.htmlEl.style.position = 'fixed';
                this.htmlEl.style.top = '0';
                this.htmlEl.style.right = '0';
                this.htmlEl.style.left = '0';
                this.htmlEl.style.bottom = '0';
                this.htmlEl.style.height = '100%';
                this.bodyEl.style.marginTop = "-" + this.stopScrollPosition + "px";
            }
            this.internalScrollActive = scrollActive;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(Modul.prototype, "CSPNonce", {
        get: function () {
            return this.options !== undefined ? this.options.CSPNonce : undefined;
        },
        enumerable: false,
        configurable: true
    });
    return Modul;
}());
export { Modul };
var ModulPlugin = {
    install: function (v, options) {
        Vue.use(PortalPlugin);
        var modul = new Modul(options);
        (v.prototype).$modul = modul;
    }
};
export default ModulPlugin;
//# sourceMappingURL=modul.js.map