var _a;
import { __awaiter, __decorate, __extends, __generator } from "tslib";
import Component from 'vue-class-component';
import { Emit, Prop, Watch } from 'vue-property-decorator';
import { ElementQueries } from '../../mixins/element-queries/element-queries';
import { ModulVue } from '../../utils/vue/vue';
import { ICON_BUTTON_NAME, NAVBAR_ITEM_NAME, NAVBAR_NAME } from '../component-names';
import { MIconButton } from '../icon-button/icon-button';
import { MNavbarItem } from './navbar-item/navbar-item';
import WithRender from './navbar.html?style=./navbar.scss';
var OVERFLOWOFFSET = 20;
var BaseNavbar = /** @class */ (function (_super) {
    __extends(BaseNavbar, _super);
    function BaseNavbar() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    return BaseNavbar;
}(ModulVue));
export { BaseNavbar };
export var MNavbarSkin;
(function (MNavbarSkin) {
    MNavbarSkin["NavMain"] = "nav-main";
    MNavbarSkin["NavSub"] = "nav-sub";
    MNavbarSkin["NavSoft"] = "nav-soft";
    MNavbarSkin["TabLight"] = "tab-light";
    MNavbarSkin["TabLightMain"] = "tab-light-main";
    MNavbarSkin["TabDark"] = "tab-dark";
    MNavbarSkin["TabDarkMain"] = "tab-dark-main";
    MNavbarSkin["TabArrow"] = "tab-arrow";
    MNavbarSkin["TabUnderline"] = "tab-underline";
    MNavbarSkin["TabSoft"] = "tab-soft";
    MNavbarSkin["Plain"] = "plain";
})(MNavbarSkin || (MNavbarSkin = {}));
export var MNavbarMaxWidth;
(function (MNavbarMaxWidth) {
    MNavbarMaxWidth["XLarge"] = "1400px";
    MNavbarMaxWidth["Large"] = "1200px";
    MNavbarMaxWidth["Regular"] = "1000px";
    MNavbarMaxWidth["Small"] = "800px";
    MNavbarMaxWidth["Text"] = "720px";
})(MNavbarMaxWidth || (MNavbarMaxWidth = {}));
var MNavbar = /** @class */ (function (_super) {
    __extends(MNavbar, _super);
    function MNavbar() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.animReady = false;
        _this.internalValue = '';
        _this.showArrowLeft = false;
        _this.showArrowRight = false;
        _this.computedHeight = 0;
        return _this;
    }
    MNavbar.prototype.emitClick = function (event, value) { };
    MNavbar.prototype.emitMouseover = function (event, value) { };
    MNavbar.prototype.emitMouseleave = function (event, value) { };
    MNavbar.prototype.onModelChangement = function () {
        if (this.isTabUnderlineSkin || this.isTabArrowSkin) {
            if (this.model.toString()) {
                this.updateSelectedIndicatorPosition();
            }
        }
    };
    MNavbar.prototype.onMultilineChanged = function () {
        var _this = this;
        // Wait for navbar-item height calculation -> setimension()
        setTimeout(function () {
            _this.setupScrolllH();
        });
    };
    MNavbar.prototype.setAndUpdate = function (value) {
        this.internalValue = value;
        this.scrollToSelected();
    };
    MNavbar.prototype.created = function () {
        if (this.skin === MNavbarSkin.TabLight) {
            this.$log.warn('MNavbarSkin.TabLight is deprecated, please use MNavbarSkin.TabLightMain instead.');
        }
        else if (this.skin === MNavbarSkin.TabDark) {
            this.$log.warn('MNavbarSkin.TabDark is deprecated, please use MNavbarSkin.TabDarkMain instead.');
        }
        this.internalValue = undefined;
    };
    MNavbar.prototype.mounted = function () {
        var _this = this;
        this.watchResizes();
        this.$refs.wrap.addEventListener('scroll', this.setDisplayNavigationButtons);
        this.observer = new MutationObserver(function (mutations) {
            if (mutations.some(function (mutation) { return mutation.type === 'childList'; })) {
                _this.watchResizes();
            }
            if (_this.skin === MNavbarSkin.TabUnderline || _this.skin === MNavbarSkin.TabArrow) {
                _this.updateSelectedIndicatorPosition();
            }
        });
        this.observer.observe(this.$refs.list, { subtree: true, childList: true, characterData: true });
        if (this.skin === MNavbarSkin.TabUnderline || this.skin === MNavbarSkin.TabArrow) {
            if (this.selected) {
                this.updateSelectedIndicatorPosition();
            }
        }
    };
    MNavbar.prototype.beforeDestroy = function () {
        this.as().$off('resize', this.setupScrolllH);
        this.$refs.wrap.removeEventListener('scroll', this.setDisplayNavigationButtons);
        if (this.observer) {
            this.observer.disconnect();
        }
    };
    Object.defineProperty(MNavbar.prototype, "model", {
        get: function () {
            return this.selected === undefined ? this.internalValue : this.selected;
        },
        set: function (value) {
            this.setAndUpdate(value);
            this.$emit('update:selected', value);
        },
        enumerable: true,
        configurable: true
    });
    MNavbar.prototype.updateValue = function (value) {
        this.model = value;
    };
    MNavbar.prototype.onMouseover = function (event, value) {
        this.emitMouseover(event, value);
    };
    MNavbar.prototype.onMouseleave = function (event, value) {
        this.emitMouseleave(event, value);
    };
    MNavbar.prototype.onClick = function (event, value) {
        this.emitClick(event, value);
    };
    Object.defineProperty(MNavbar.prototype, "hasArrowRight", {
        get: function () {
            return this.showArrowRight && this.navigationArrow;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MNavbar.prototype, "hasArrowLeft", {
        get: function () {
            return this.showArrowLeft && this.navigationArrow;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MNavbar.prototype, "buttonSkin", {
        get: function () {
            return this.skin === MNavbarSkin.NavMain || this.skin === MNavbarSkin.NavSub || this.skin === MNavbarSkin.NavSoft || this.skin === MNavbarSkin.TabDark || this.skin === MNavbarSkin.TabDarkMain ? 'dark' : 'light';
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MNavbar.prototype, "buttonRipple", {
        get: function () {
            return this.skin === MNavbarSkin.TabUnderline || this.skin === MNavbarSkin.TabArrow || this.skin === MNavbarSkin.TabSoft;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MNavbar.prototype, "isTabLightSkin", {
        get: function () {
            return this.skin === MNavbarSkin.TabLight || this.skin === MNavbarSkin.TabLightMain;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MNavbar.prototype, "isTabUnderlineSkin", {
        get: function () {
            return this.skin === MNavbarSkin.TabUnderline;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MNavbar.prototype, "isTabArrowSkin", {
        get: function () {
            return this.skin === MNavbarSkin.TabArrow;
        },
        enumerable: true,
        configurable: true
    });
    MNavbar.prototype.watchResizes = function () {
        var _this = this;
        this.as().$off('resize', this.setupScrolllH);
        this.$children.forEach(function (child) {
            child.$off('resize', _this.setupScrolllH);
        });
        this.setupScrolllH();
        this.as().$on('resize', this.setupScrolllH);
        this.$children.forEach(function (child) {
            child.$on('resize', _this.setupScrolllH);
        });
    };
    MNavbar.prototype.setSelectedIndicatorPosition = function (element, ref) {
        var positionX = element.$el.offsetLeft;
        var width = element.$el.clientWidth;
        var localRef = this.$refs[ref];
        localRef.style.transform = 'translate3d(' + positionX + 'px, 0, 0)';
        localRef.style.width = width + 'px';
    };
    MNavbar.prototype.setupScrolllH = function () {
        var _this = this;
        var contentsEl = this.$refs.contents;
        var wrapEl = this.$refs.wrap;
        var listEl = this.$refs.list;
        if (wrapEl.scrollWidth > wrapEl.clientWidth) {
            this.computedHeight = listEl.clientHeight;
            wrapEl.style.height = this.computedHeight + OVERFLOWOFFSET + 'px';
            contentsEl.style.height = this.computedHeight + 'px';
            this.scrollToSelected();
        }
        else {
            this.showArrowLeft = false;
            this.showArrowRight = false;
            wrapEl.style.removeProperty('height');
            contentsEl.style.removeProperty('height');
        }
        if (!this.animReady) {
            setTimeout(function () {
                _this.animReady = true;
            });
        }
    };
    MNavbar.prototype.scrollToSelected = function () {
        return __awaiter(this, void 0, void 0, function () {
            var navbarItems;
            var _this = this;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.navbarItems()];
                    case 1:
                        navbarItems = _a.sent();
                        if (!navbarItems) {
                            return [2 /*return*/];
                        }
                        navbarItems.elements.forEach(function (element) {
                            // Allow time to make sure an item is selected
                            setTimeout(function () {
                                var wrapEl = _this.$refs.wrap;
                                if (element && element.$props.value === _this.model && wrapEl) {
                                    var buttonLeftWidth = _this.$refs.buttonLeft && _this.hasArrowLeft ? _this.$refs.buttonLeft.clientWidth : 0;
                                    var buttonRightWidth = _this.$refs.buttonRight && _this.hasArrowRight ? _this.$refs.buttonRight.clientWidth : 0;
                                    var scrollPositionAlignLeft = element.$el.offsetLeft - buttonLeftWidth;
                                    // Check if selected element is visible in navbar
                                    if (wrapEl && wrapEl.clientWidth > (element.$el.offsetLeft - wrapEl.scrollLeft + buttonRightWidth)) {
                                        // Check if the selected element exceeds on the left side
                                        if ((element.$el.offsetLeft - buttonLeftWidth - wrapEl.scrollLeft) < 0) {
                                            wrapEl.scrollLeft = scrollPositionAlignLeft;
                                            // Check if the selected element exceeds on the right side
                                        }
                                        else if (wrapEl.clientWidth < (element.$el.offsetLeft - wrapEl.scrollLeft + element.$el.clientWidth + buttonRightWidth)) {
                                            wrapEl.scrollLeft = wrapEl.scrollLeft + element.$el.clientWidth + buttonRightWidth - (wrapEl.scrollLeft + wrapEl.clientWidth - element.$el.offsetLeft);
                                        }
                                    }
                                    else if (wrapEl) {
                                        wrapEl.scrollLeft = scrollPositionAlignLeft;
                                    }
                                    if (_this.skin === MNavbarSkin.TabUnderline || _this.skin === MNavbarSkin.TabArrow) {
                                        _this.setSelectedIndicatorPosition(element, _this.skin);
                                    }
                                    _this.setDisplayNavigationButtons();
                                }
                            });
                        });
                        return [2 /*return*/];
                }
            });
        });
    };
    MNavbar.prototype.setDisplayNavigationButtons = function () {
        var spaceBeforeDisplayingButton = this.isTabLightSkin ? 5 : 0;
        var wrapEl = this.$refs.wrap;
        if (wrapEl) {
            var maxScrollLeft = Math.round(wrapEl.scrollWidth - wrapEl.clientWidth - spaceBeforeDisplayingButton);
            this.showArrowRight = Math.round(wrapEl.scrollLeft) < maxScrollLeft;
            this.showArrowLeft = wrapEl.scrollLeft > spaceBeforeDisplayingButton;
        }
    };
    MNavbar.prototype.updateSelectedIndicatorPosition = function () {
        return __awaiter(this, void 0, void 0, function () {
            var navbarItems;
            var _this = this;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.navbarItems()];
                    case 1:
                        navbarItems = _a.sent();
                        if (!navbarItems) {
                            return [2 /*return*/];
                        }
                        navbarItems.elements.forEach(function (element) {
                            if (element && element.$props.value === _this.model) {
                                _this.setSelectedIndicatorPosition(element, _this.skin);
                            }
                        });
                        return [2 /*return*/];
                }
            });
        });
    };
    MNavbar.prototype.navbarItems = function () {
        return __awaiter(this, void 0, void 0, function () {
            var navbarItems, interval, countIntervalIteration, getNavbarItems;
            var _this = this;
            return __generator(this, function (_a) {
                navbarItems = this.$children.filter(function (element) { return element instanceof MNavbarItem; });
                countIntervalIteration = 0;
                getNavbarItems = function (navbarItems) {
                    clearInterval(interval);
                    var firstElement = navbarItems[0].$el;
                    var lastElement = navbarItems[navbarItems.length - 1].$el;
                    return {
                        elements: navbarItems,
                        firstElement: firstElement,
                        lastElement: lastElement
                    };
                };
                return [2 /*return*/, new Promise(function (resolve, reject) {
                        if (navbarItems.length < 1) {
                            interval = window.setInterval(function () {
                                navbarItems = _this.$children.filter(function (element) { return element instanceof MNavbarItem; });
                                if (navbarItems.length > 0) {
                                    return resolve(getNavbarItems(navbarItems));
                                }
                                if (countIntervalIteration > 8) {
                                    clearInterval(interval);
                                }
                                countIntervalIteration++;
                            }, 300);
                        }
                        else {
                            return resolve(getNavbarItems(navbarItems));
                        }
                    })];
            });
        });
    };
    MNavbar.prototype.scrollLeft = function () {
        return __awaiter(this, void 0, void 0, function () {
            var wrapEl, outbound, navbarItems;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        wrapEl = this.$refs.wrap;
                        return [4 /*yield*/, this.navbarItems()];
                    case 1:
                        navbarItems = _a.sent();
                        if (!navbarItems) {
                            return [2 /*return*/];
                        }
                        // find the previus element outside visible area
                        navbarItems.elements.forEach(function (element) {
                            if (element.$el.offsetLeft < wrapEl.scrollLeft) {
                                outbound = element;
                            }
                        });
                        if (outbound) {
                            wrapEl.scrollLeft = outbound.$el.offsetLeft - this.$refs.buttonLeft.clientWidth;
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    MNavbar.prototype.scrollRight = function () {
        return __awaiter(this, void 0, void 0, function () {
            var wrapEl, cRight, navbarItems, outbound, threshold;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        wrapEl = this.$refs.wrap;
                        cRight = wrapEl.scrollLeft + wrapEl.clientWidth;
                        return [4 /*yield*/, this.navbarItems()];
                    case 1:
                        navbarItems = _a.sent();
                        if (!navbarItems) {
                            return [2 /*return*/];
                        }
                        outbound = navbarItems.elements.find(function (element) { return element.$el.offsetLeft + element.$el.clientWidth > cRight; });
                        if (outbound) {
                            threshold = cRight - outbound.$el.offsetLeft;
                            // move the container scroll
                            wrapEl.scrollLeft += (outbound.$el.clientWidth + this.$refs.buttonRight.clientWidth) - threshold;
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    __decorate([
        Prop()
    ], MNavbar.prototype, "selected", void 0);
    __decorate([
        Prop({
            default: MNavbarSkin.NavMain,
            validator: function (value) {
                return value === MNavbarSkin.NavMain ||
                    value === MNavbarSkin.NavSub ||
                    value === MNavbarSkin.NavSoft ||
                    value === MNavbarSkin.TabLight ||
                    value === MNavbarSkin.TabLightMain ||
                    value === MNavbarSkin.TabDark ||
                    value === MNavbarSkin.TabDarkMain ||
                    value === MNavbarSkin.TabArrow ||
                    value === MNavbarSkin.TabUnderline ||
                    value === MNavbarSkin.TabSoft ||
                    value === MNavbarSkin.Plain;
            }
        })
    ], MNavbar.prototype, "skin", void 0);
    __decorate([
        Prop()
    ], MNavbar.prototype, "disabled", void 0);
    __decorate([
        Prop({ default: true })
    ], MNavbar.prototype, "navigationArrow", void 0);
    __decorate([
        Prop({ default: MNavbarMaxWidth.Large })
    ], MNavbar.prototype, "maxWidth", void 0);
    __decorate([
        Prop({ default: true })
    ], MNavbar.prototype, "multiline", void 0);
    __decorate([
        Prop()
    ], MNavbar.prototype, "titleButtonLeft", void 0);
    __decorate([
        Prop()
    ], MNavbar.prototype, "titleButtonRight", void 0);
    __decorate([
        Prop({ default: false })
    ], MNavbar.prototype, "autoSelect", void 0);
    __decorate([
        Emit('click')
    ], MNavbar.prototype, "emitClick", null);
    __decorate([
        Emit('mouseover')
    ], MNavbar.prototype, "emitMouseover", null);
    __decorate([
        Emit('mouseleave')
    ], MNavbar.prototype, "emitMouseleave", null);
    __decorate([
        Watch('model', { immediate: true })
    ], MNavbar.prototype, "onModelChangement", null);
    __decorate([
        Watch('multiline')
    ], MNavbar.prototype, "onMultilineChanged", null);
    __decorate([
        Watch('selected')
    ], MNavbar.prototype, "setAndUpdate", null);
    MNavbar = __decorate([
        WithRender,
        Component({
            components: (_a = {},
                _a[ICON_BUTTON_NAME] = MIconButton,
                _a),
            mixins: [ElementQueries]
        })
    ], MNavbar);
    return MNavbar;
}(BaseNavbar));
export { MNavbar };
var NavbarPlugin = {
    install: function (v, options) {
        v.component(NAVBAR_ITEM_NAME, MNavbarItem);
        v.component(NAVBAR_NAME, MNavbar);
    }
};
export default NavbarPlugin;
//# sourceMappingURL=navbar.js.map