import { __awaiter, __decorate, __extends, __generator, __spreadArrays } from "tslib";
import Component from 'vue-class-component';
import { Emit, Model, Prop, Ref, Watch } from 'vue-property-decorator';
import { InputLabel } from '../../mixins/input-label/input-label';
import { InputState } from '../../mixins/input-state/input-state';
import { InputWidth } from '../../mixins/input-width/input-width';
import { MediaQueries } from '../../mixins/media-queries/media-queries';
import { FormatMode } from '../../utils/i18n/i18n';
import uuid from '../../utils/uuid/uuid';
import { ModulVue } from '../../utils/vue/vue';
import { MULTI_SELECT_NAME } from '../component-names';
import { MI18n } from '../i18n/i18n';
import { MIcon } from '../icon/icon';
import { MInputStyle } from '../input-style/input-style';
import { MValidationMessage } from '../validation-message/validation-message';
import MChipDelete from './../chip/chip-delete/chip-delete';
import { MBaseSelect } from './../select/base-select/base-select';
import { MSelectItem } from './../select/select-item/select-item';
import WithRender from './multi-select.html?style=./multi-select.scss';
var MMultiSelect = /** @class */ (function (_super) {
    __extends(MMultiSelect, _super);
    function MMultiSelect() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.inputAriaDescribedby = uuid.generate();
        _this.selectedValueId = uuid.generate();
        _this.internalValue = [];
        _this.internalFocus = false;
        _this.open = false;
        _this.internalOptions = [];
        _this.allSelectedCheckboxIsChecked = false;
        return _this;
    }
    MMultiSelect.prototype.emitClose = function () { };
    MMultiSelect.prototype.onBlur = function ($event) {
        this.internalFocus = false;
    };
    MMultiSelect.prototype.emitOpen = function () {
        return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) {
            return [2 /*return*/];
        }); });
    };
    MMultiSelect.prototype.onSelect = function (option, index, $event) {
        var positionInModel = this.model.indexOf(option);
        if (this.linkSelectAll && index === 0) {
            this.onToggleAll();
        }
        else {
            if (positionInModel === -1) {
                this.model = __spreadArrays(this.model, [(this.internalOptions[index])]);
            }
            else {
                this.onDelete(option);
            }
            this.update();
        }
        if ($event.type === 'click') {
            this.refBaseSelect.focusedIndex = -1;
        }
    };
    Object.defineProperty(MMultiSelect.prototype, "model", {
        get: function () {
            return this.internalValue;
        },
        set: function (value) {
            var _this = this;
            this.internalValue = value;
            if (this.linkSelectAll && this.internalValue.some(function (v) { return v === _this.internalOptions[0]; })) {
                this.$emit('input', this.internalValue.filter(function (v) { return v !== _this.internalOptions[0]; }));
            }
            else {
                this.$emit('input', this.internalValue);
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MMultiSelect.prototype, "selectedItems", {
        get: function () {
            return this.value || [];
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MMultiSelect.prototype, "numberOfItemsSelected", {
        get: function () {
            return this.selectedItems.length;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MMultiSelect.prototype, "isEmpty", {
        get: function () {
            return !this.hasValue && !this.open && !Boolean(this.placeholder);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MMultiSelect.prototype, "hasValue", {
        get: function () {
            return !!(this.model && this.model.length > 0);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MMultiSelect.prototype, "allSelected", {
        get: function () {
            return this.options && this.options.length === this.selectedItems.length;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MMultiSelect.prototype, "chipsDisplayMode", {
        get: function () {
            if (this.allSelected) {
                return 1;
            }
            else if (this.numberOfItemsSelected > this.maxVisibleChips) {
                return 0;
            }
            return -1;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MMultiSelect.prototype, "textNumberOfSelectedItems", {
        get: function () {
            return this.$i18n.translate('m-multi-select:all-selected', [this.numberOfItemsSelected], undefined, undefined, false, FormatMode.Default);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MMultiSelect.prototype, "textNumberOfUnselectedItemsLeft", {
        get: function () {
            return this.$i18n.translate('m-multi-select:more', [this.numberOfItemsSelected - this.maxVisibleChips], undefined, undefined, false, FormatMode.Default);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MMultiSelect.prototype, "hiddenTextSelectedValue", {
        get: function () {
            var text = this.$i18n.translate('m-multi-select:selected-items', [this.numberOfItemsSelected], this.numberOfItemsSelected);
            if (this.numberOfItemsSelected) {
                text += ": " + this.selectedItems.join(', ');
            }
            return text;
        },
        enumerable: false,
        configurable: true
    });
    MMultiSelect.prototype.onPortalAfterClose = function () {
        this.focusInput();
    };
    MMultiSelect.prototype.onClickOnItem = function () {
        this.focusInput();
    };
    MMultiSelect.prototype.toggle = function () {
        this.refBaseSelect.togglePopup();
    };
    MMultiSelect.prototype.onInputStyleClick = function (callbackToggle) {
        callbackToggle();
        if (this.open) {
            this.focusInput();
        }
    };
    MMultiSelect.prototype.focusInput = function () {
        if (this.refInput && document.activeElement !== this.refInput) {
            this.refInput.focus();
        }
    };
    MMultiSelect.prototype.onDelete = function (option) {
        this.model = this.model.filter(function (m) { return m !== option; });
        this.update();
        this.focusInput();
    };
    MMultiSelect.prototype.onDeleteAll = function () {
        this.model = [];
        this.update();
        this.focusInput();
    };
    MMultiSelect.prototype.onFocus = function ($event) {
        this.internalFocus = this.as().active;
        if (!this.internalFocus) {
            return;
        }
        this.$emit('focus', $event);
    };
    MMultiSelect.prototype.onKeydownDown = function ($event) {
        if (!this.internalOptions) {
            return;
        }
        this.refBaseSelect.onKeydownDown($event);
    };
    MMultiSelect.prototype.onKeydownUp = function ($event) {
        if (!this.internalOptions) {
            return;
        }
        this.refBaseSelect.onKeydownUp($event);
    };
    MMultiSelect.prototype.onKeydownEnter = function ($event) {
        if (!this.internalOptions) {
            return;
        }
        if (!this.open) {
            this.open = true;
            return;
        }
        if (this.refBaseSelect.focusedIndex > -1) {
            this.refBaseSelect.emitSelectItem(this.refBaseSelect.items[this.refBaseSelect.focusedIndex], this.refBaseSelect.focusedIndex, $event);
        }
    };
    MMultiSelect.prototype.onKeydownSpace = function ($event) {
        if (this.internalOptions) {
            if (!this.open) {
                this.open = true;
            }
            this.refBaseSelect.onKeydownSpace($event);
        }
    };
    MMultiSelect.prototype.update = function () {
        this.refBaseSelect.update();
    };
    MMultiSelect.prototype.onToggleAll = function () {
        if (this.selectedItems.length >= this.options.length) {
            this.model = [];
        }
        else {
            this.model = __spreadArrays(this.internalOptions);
        }
        this.update();
    };
    MMultiSelect.prototype.getChipLabel = function (item) {
        var ellipsis = item.toString().length > this.defaultChipCharsTrunk ? '...' : '';
        return "" + item.toString().substring(0, this.defaultChipCharsTrunk) + ellipsis;
    };
    MMultiSelect.prototype.created = function () {
        if (!Array.isArray(this.value)) {
            this.$log.error('MMultiSelect - The model must be an array');
        }
    };
    MMultiSelect.prototype.mounted = function () {
        if (this.focus) {
            this.focusChanged(this.focus);
        }
    };
    MMultiSelect.prototype.onOptionsChange = function () {
        if (!this.options) {
            return;
        }
        if (this.linkSelectAll) {
            this.internalOptions = __spreadArrays(['linkSelectAll'], this.options);
            return;
        }
        this.internalOptions = __spreadArrays(this.options);
    };
    MMultiSelect.prototype.onValueChange = function (value) {
        var _this = this;
        if (this.linkSelectAll && !this.value.some(function (v) { return v === _this.internalOptions[0]; })) {
            this.internalValue = __spreadArrays([this.internalOptions[0]], value);
        }
        else {
            this.internalValue = value;
        }
    };
    MMultiSelect.prototype.focusChanged = function (focus) {
        this.internalFocus = focus && this.as().active;
        if (!this.refInput) {
            return;
        }
        if (this.internalFocus) {
            this.focusInput();
        }
        else {
            this.refInput.blur();
        }
    };
    __decorate([
        Model('input'),
        Prop({
            validator: function (value) { return Array.isArray(value); }
        })
    ], MMultiSelect.prototype, "value", void 0);
    __decorate([
        Prop({
            validator: function (value) { return Array.isArray(value); }
        })
    ], MMultiSelect.prototype, "options", void 0);
    __decorate([
        Prop()
    ], MMultiSelect.prototype, "focus", void 0);
    __decorate([
        Prop({
            default: false
        })
    ], MMultiSelect.prototype, "linkSelectAll", void 0);
    __decorate([
        Prop({
            default: 5
        })
    ], MMultiSelect.prototype, "maxVisibleChips", void 0);
    __decorate([
        Prop({
            default: 12
        })
    ], MMultiSelect.prototype, "defaultChipCharsTrunk", void 0);
    __decorate([
        Prop()
    ], MMultiSelect.prototype, "placeholder", void 0);
    __decorate([
        Prop({ default: function () { return MULTI_SELECT_NAME + "-" + uuid.generate(); } })
    ], MMultiSelect.prototype, "id", void 0);
    __decorate([
        Ref('input')
    ], MMultiSelect.prototype, "refInput", void 0);
    __decorate([
        Ref('baseSelect')
    ], MMultiSelect.prototype, "refBaseSelect", void 0);
    __decorate([
        Emit('close')
    ], MMultiSelect.prototype, "emitClose", null);
    __decorate([
        Emit('blur')
    ], MMultiSelect.prototype, "onBlur", null);
    __decorate([
        Emit('open')
    ], MMultiSelect.prototype, "emitOpen", null);
    __decorate([
        Emit('select-item')
    ], MMultiSelect.prototype, "onSelect", null);
    __decorate([
        Watch('options', { immediate: true })
    ], MMultiSelect.prototype, "onOptionsChange", null);
    __decorate([
        Watch('value', { immediate: true })
    ], MMultiSelect.prototype, "onValueChange", null);
    __decorate([
        Watch('focus')
    ], MMultiSelect.prototype, "focusChanged", null);
    MMultiSelect = __decorate([
        WithRender,
        Component({
            components: {
                MBaseSelect: MBaseSelect,
                MSelectItem: MSelectItem,
                MChipDelete: MChipDelete,
                MI18n: MI18n,
                MValidationMessage: MValidationMessage,
                MIcon: MIcon,
                MInputStyle: MInputStyle
            },
            mixins: [
                InputState, InputWidth, InputLabel, MediaQueries
            ]
        })
    ], MMultiSelect);
    return MMultiSelect;
}(ModulVue));
export { MMultiSelect };
var MultiSelectPlugin = {
    install: function (v, options) {
        v.component(MULTI_SELECT_NAME, MMultiSelect);
    }
};
export default MultiSelectPlugin;
//# sourceMappingURL=multi-select.js.map