import { __awaiter, __decorate, __extends, __generator } from "tslib";
import Component from 'vue-class-component';
import { Emit, Prop, Watch } from 'vue-property-decorator';
import { ModulVue } from '../../../utils/vue/vue';
import { BaseNavbar } from '../navbar';
import './../navbar-unscoped.scss';
import NavbarItemHelper from './navbar-item-helper';
import WithRender from './navbar-item.html?style=./navbar-item.scss';
// must be sync with selected css class
var FAKE_SELECTED_CLASS = 'm--is-fake-selected';
var MNavbarItem = /** @class */ (function (_super) {
    __extends(MNavbarItem, _super);
    function MNavbarItem() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.formatedLabel = '';
        // should be initialized to be reactive
        // tslint:disable-next-line:no-null-keyword
        _this.parentNavbar = null;
        return _this;
    }
    MNavbarItem.prototype.emitClick = function (event) { };
    MNavbarItem.prototype.emitMouseover = function (event) { };
    MNavbarItem.prototype.emitMouseleave = function (event) { };
    MNavbarItem.prototype.labelChanged = function () {
        this.setFormatedLabel();
    };
    MNavbarItem.prototype.isMultilineChanged = function () {
        this.setDimension();
        this.setFormatedLabel();
    };
    MNavbarItem.prototype.routeChanged = function () {
        var _this = this;
        this.$nextTick(function () {
            if (_this.parentNavbar && _this.parentNavbar.autoSelect && NavbarItemHelper.isRouterLinkActive(_this)) {
                _this.parentNavbar.updateValue(_this.value);
            }
        });
    };
    MNavbarItem.prototype.mounted = function () {
        this.formatedLabel = this.label;
        var parentNavbar;
        parentNavbar = this.getParent(function (p) { return p instanceof BaseNavbar || // these will fail with Jest, but should pass in prod mode
            p.$options.name === 'MNavbar'; } // these are necessary for Jest, but the first two should pass in prod mode
        );
        if (parentNavbar) {
            this.parentNavbar = parentNavbar;
            this.setDimension();
            this.setFormatedLabel();
            if (this.parentNavbar.autoSelect && NavbarItemHelper.isRouterLinkActive(this)) {
                this.parentNavbar.updateValue(this.value);
            }
        }
        else {
            console.error('m-navbar-item need to be inside m-navbar');
        }
        this.$modul.event.$on('resize', this.setFormatedLabel);
        this.$modul.event.$on('resize', this.setDimension);
    };
    MNavbarItem.prototype.beforeDestroy = function () {
        this.$modul.event.$off('resize', this.setDimension);
        this.$modul.event.$off('resize', this.setFormatedLabel);
    };
    Object.defineProperty(MNavbarItem.prototype, "shouldNotWrap", {
        get: function () {
            return Boolean(this.label) && this.label.length < 15;
        },
        enumerable: false,
        configurable: true
    });
    MNavbarItem.prototype.setFormatedLabel = function () {
        return __awaiter(this, void 0, void 0, function () {
            var itemValue, itemComputedStyle, fontSize;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        this.formatedLabel = this.label;
                        if (!this.label || !this.isMultiline) {
                            return [2 /*return*/];
                        }
                        return [4 /*yield*/, this.$nextTick()];
                    case 1:
                        _a.sent();
                        if (this.label) {
                            if (this.label.length < 15) {
                                return [2 /*return*/];
                            }
                            else if (this.label.length > 30) {
                                this.splitAndWrap();
                                return [2 /*return*/];
                            }
                        }
                        itemValue = this.$refs.itemValue;
                        if (!itemValue) {
                            return [2 /*return*/];
                        }
                        itemComputedStyle = window.getComputedStyle(itemValue);
                        fontSize = parseFloat(itemComputedStyle.getPropertyValue('font-size'));
                        if (itemValue.clientHeight / fontSize <= 3) {
                            return [2 /*return*/];
                        }
                        this.splitAndWrap();
                        return [2 /*return*/];
                }
            });
        });
    };
    Object.defineProperty(MNavbarItem.prototype, "isSelected", {
        get: function () {
            return !!this.parentNavbar && !this.disabled && this.value === this.parentNavbar.model;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MNavbarItem.prototype, "isMultiline", {
        get: function () {
            return !this.multiline && this.parentNavbar ? this.parentNavbar.multiline : this.multiline;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MNavbarItem.prototype, "isRouterLink", {
        get: function () {
            return Boolean(this.url) && !this.disabled;
        },
        enumerable: false,
        configurable: true
    });
    MNavbarItem.prototype.onClick = function (event) {
        if (!this.disabled && this.parentNavbar) {
            this.parentNavbar.onClick(event, this.value);
            if (this.value !== this.parentNavbar.model) {
                this.parentNavbar.updateValue(this.value);
            }
            this.emitClick(event);
        }
    };
    MNavbarItem.prototype.onMouseover = function (event) {
        if (!this.disabled && this.parentNavbar) {
            this.parentNavbar.onMouseover(event, this.value);
            this.emitMouseover(event);
        }
    };
    MNavbarItem.prototype.onMouseleave = function (event) {
        if (!this.disabled && this.parentNavbar) {
            this.parentNavbar.onMouseleave(event, this.value);
            this.emitMouseleave(event);
        }
    };
    MNavbarItem.prototype.setDimension = function () {
        if (this.label || !this.isMultiline) {
            return;
        }
        var itemEl = this.$refs.item;
        if (itemEl && itemEl.style) {
            itemEl.style.removeProperty('width');
            itemEl.style.removeProperty('max-width');
            itemEl.style.removeProperty('white-space');
            if (this.isMultiline && ((itemEl.innerText === undefined ? '' : itemEl.innerText).trim().length > 15)) {
                var itemElComputedStyle = window.getComputedStyle(itemEl);
                var fontSize = parseFloat(itemElComputedStyle.getPropertyValue('font-size'));
                var paddingH = parseInt(itemElComputedStyle.getPropertyValue('padding-top'), 10) + parseInt(itemElComputedStyle.getPropertyValue('padding-bottom'), 10);
                // must subtract the padding, create a infinite loop
                var itemElHeight = itemEl.clientHeight - paddingH;
                var lines = Math.floor(itemElHeight / fontSize);
                if (lines > 2) {
                    // use selected class to reserve space for when selected
                    this.$el.classList.add(FAKE_SELECTED_CLASS);
                    // create a infinite loop if the parent has 'align-items: stretch'
                    this.$parent.$refs.list.style.alignItems = 'flex-start';
                    do {
                        itemEl.style.width = itemEl.clientWidth + 1 + 'px'; // increment width
                        // update values
                        itemElHeight = itemEl.clientHeight - paddingH;
                        lines = Math.floor(itemElHeight / fontSize);
                    } while (lines > 2);
                    itemEl.style.width = itemEl.clientWidth + 2 + 'px'; // Add 2px for never to fall on more than two lines
                    // reset styles once completed
                    this.$el.classList.remove(FAKE_SELECTED_CLASS);
                    this.$parent.$refs.list.style.removeProperty('align-items');
                }
            }
            else {
                itemEl.style.whiteSpace = 'nowrap';
            }
        }
    };
    MNavbarItem.prototype.splitAndWrap = function () {
        var split = this.label.split(' ');
        split.splice(Math.round(split.length / 2), 0, '</br>');
        this.formatedLabel = '<span style="all: inherit; white-space: nowrap;">'
            + split.join(' ')
            + '</span>';
    };
    __decorate([
        Prop()
    ], MNavbarItem.prototype, "value", void 0);
    __decorate([
        Prop()
    ], MNavbarItem.prototype, "label", void 0);
    __decorate([
        Prop()
    ], MNavbarItem.prototype, "disabled", void 0);
    __decorate([
        Prop()
    ], MNavbarItem.prototype, "url", void 0);
    __decorate([
        Prop()
    ], MNavbarItem.prototype, "ariaHaspopup", void 0);
    __decorate([
        Prop()
    ], MNavbarItem.prototype, "ariaExpanded", void 0);
    __decorate([
        Prop()
    ], MNavbarItem.prototype, "ariaControls", void 0);
    __decorate([
        Prop()
    ], MNavbarItem.prototype, "ariaCurrent", void 0);
    __decorate([
        Prop()
    ], MNavbarItem.prototype, "multiline", void 0);
    __decorate([
        Emit('click')
    ], MNavbarItem.prototype, "emitClick", null);
    __decorate([
        Emit('mouseover')
    ], MNavbarItem.prototype, "emitMouseover", null);
    __decorate([
        Emit('mouseleave')
    ], MNavbarItem.prototype, "emitMouseleave", null);
    __decorate([
        Watch('label')
    ], MNavbarItem.prototype, "labelChanged", null);
    __decorate([
        Watch('isMultiline')
    ], MNavbarItem.prototype, "isMultilineChanged", null);
    __decorate([
        Watch('$route')
    ], MNavbarItem.prototype, "routeChanged", null);
    MNavbarItem = __decorate([
        WithRender,
        Component
    ], MNavbarItem);
    return MNavbarItem;
}(ModulVue));
export { MNavbarItem };
//# sourceMappingURL=navbar-item.js.map