var _a;
import { __decorate, __extends } from "tslib";
import Component from 'vue-class-component';
import { Emit, Model, Prop, Watch } from 'vue-property-decorator';
import { MPopupDirective } from '../../directives/popup/popup';
import { InputLabel } from '../../mixins/input-label/input-label';
import { InputState } from '../../mixins/input-state/input-state';
import { InputMaxWidth, InputWidth } from '../../mixins/input-width/input-width';
import { MediaQueries } from '../../mixins/media-queries/media-queries';
import { FormatMode } from '../../utils/i18n/i18n';
import { KeyCode } from '../../utils/keycode/keycode';
import MediaQueriesPlugin from '../../utils/media-queries/media-queries';
import uuid from '../../utils/uuid/uuid';
import { ModulVue } from '../../utils/vue/vue';
import { MCalendarButton } from '../calendar/calendar-button/calendar-button';
import { TIMEPICKER_NAME } from '../component-names';
import { MIconButton } from '../icon-button/icon-button';
import { MInputMask } from '../input-mask/input-mask';
import { MInputStyle } from '../input-style/input-style';
import { MLink } from '../link/link';
import { MPopup } from '../popup/popup';
import { MValidationMessage } from '../validation-message/validation-message';
import { POPUP_NAME as DIRECTIVE_POPUP_NAME } from './../../directives/directive-names';
import { InputManagement } from './../../mixins/input-management/input-management';
import WithRender from './timepicker.html?style=./timepicker.scss';
var MAXIMUM_HOURS = 23;
var MAXIMUM_MINUTES = 59;
var MINUTE_SECONDS = 60;
var validateTimeString = function (value) {
    var regex = /(\d\d):(\d\d)/g;
    return !(value || '').length || value.match(regex) ? true : false;
};
var MTimepicker = /** @class */ (function (_super) {
    __extends(MTimepicker, _super);
    function MTimepicker() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.validationMessageId = uuid.generate();
        _this.open = false;
        _this.i18nButton = _this.$i18n.translate('m-timepicker:button-ok');
        _this.i18nPlaceHolder = _this.$i18n.translate('m-timepicker:placeholder');
        _this.i18nOutOfBoundsError = _this.$i18n.translate('m-timepicker:out-of-bounds-error', { min: _this.min, max: _this.max }, undefined, undefined, undefined, FormatMode.Sprintf);
        _this.hours = [];
        _this.minutes = [];
        _this.internalTime = '';
        _this.internalHour = NaN;
        _this.internalMinute = NaN;
        _this.internalFilteredMinutes = [];
        _this.internalFilteredHours = [];
        _this.isMousedown = false;
        _this.internalTimeErrorMessage = '';
        return _this;
    }
    Object.defineProperty(MTimepicker.prototype, "currentTime", {
        get: function () {
            return this.internalTime;
        },
        set: function (value) {
            var hourParts = (value || '').split(':');
            var newValue = hourParts.length > 1 ? hourParts[0] + ":" + hourParts[1] : '';
            var oldTime = this.internalTime;
            // When the user type in something we close de popup.
            this.open = false;
            if (this.value && this.skipInputValidation) {
                this.internalTime = this.getFormatTime(newValue);
            }
            else if (this.value && this.validateTime(value) && validateTimeString(value)) {
                this.updatePopupTime(newValue);
                if (newValue !== oldTime) {
                    this.internalTime = this.getFormatTime(newValue);
                }
            }
            else {
                this.resetPopupTime();
                this.internalTime = newValue;
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTimepicker.prototype, "currentHour", {
        get: function () {
            return this.internalHour;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTimepicker.prototype, "currentMinute", {
        get: function () {
            return this.internalMinute;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTimepicker.prototype, "currentfilteredHours", {
        get: function () {
            var _this = this;
            return this.internalFilteredHours = this.hours.filter(function (x) { return (x >= _this.timeStringToNumber(_this.min).hour) && (x <= _this.timeStringToNumber(_this.max).hour); });
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTimepicker.prototype, "currentFilteredMinutes", {
        get: function () {
            var _this = this;
            return this.internalFilteredMinutes.filter(function (x) { return (x % _this.step === 0); });
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTimepicker.prototype, "currentStep", {
        get: function () {
            return this.step * MINUTE_SECONDS;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTimepicker.prototype, "timeError", {
        get: function () {
            return this.internalTimeErrorMessage !== '' || this.as().hasError;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTimepicker.prototype, "isFocus", {
        // override from Input-management
        get: function () {
            return this.as().internalIsFocus || this.open;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTimepicker.prototype, "timeErrorMessage", {
        get: function () {
            if (this.hideInternalErrorMessage) {
                return '';
            }
            return this.internalTimeErrorMessage || this.as().errorMessage;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTimepicker.prototype, "inputMaskOptions", {
        get: function () {
            return {
                time: true,
                timePattern: ['h', 'm']
            };
        },
        enumerable: false,
        configurable: true
    });
    MTimepicker.prototype.emitChange = function (_time) { };
    MTimepicker.prototype.emitClick = function (_event) { };
    MTimepicker.prototype.emitOpen = function () { };
    MTimepicker.prototype.emitClose = function () { };
    MTimepicker.prototype.updateInternalTime = function (value) {
        this.internalTime = this.getFormatTime(value);
    };
    MTimepicker.prototype.togglePopup = function (event) {
        if (this.as().active) {
            this.open = !this.open;
        }
        // stop event propagation to parent.
        event.stopPropagation();
    };
    // override from InputManagement
    MTimepicker.prototype.onClick = function (event) {
        this.as().internalIsFocus = this.as().active;
        if (this.as().internalIsFocus) {
            this.as().focusInput();
        }
        this.emitClick(event);
    };
    MTimepicker.prototype.onScroll = function (event) {
        var _this = this;
        if (this.isMousedown) {
            return;
        }
        clearTimeout(this.scrollTimeout);
        this.scrollTimeout = setTimeout(function () {
            // tslint:disable-next-line: deprecation
            if (event.srcElement) {
                // tslint:disable-next-line: deprecation
                _this.setPositionScroll(event.srcElement);
            }
        }, 300);
    };
    MTimepicker.prototype.onSelectHour = function (hour) {
        var _this = this;
        this.internalHour = hour;
        // change available minutes in function of min/max value
        if (hour === this.timeStringToNumber(this.min).hour) {
            this.internalFilteredMinutes = this.minutes.filter(function (x) { return (x >= _this.timeStringToNumber(_this.min).minute); });
        }
        else if (hour === this.timeStringToNumber(this.max).hour) {
            this.internalFilteredMinutes = this.minutes.filter(function (x) { return (x <= _this.timeStringToNumber(_this.max).minute); });
        }
        else {
            this.internalFilteredMinutes = this.minutes;
        }
    };
    MTimepicker.prototype.onSelectHourKeyup = function ($event, hour) {
        // tslint:disable-next-line: deprecation
        if ($event.keyCode === KeyCode.M_ENTER || $event.keyCode === KeyCode.M_RETURN) {
            this.onSelectHour(hour);
        }
    };
    MTimepicker.prototype.onSelectMinute = function (minute) {
        this.internalMinute = minute;
        if (isNaN(this.internalHour)) {
            return;
        }
        this.emitChange(this.formatTimeString());
        this.open = false;
        if (this.as().isMqMinS) {
            this.as().focusInput();
        }
    };
    MTimepicker.prototype.onSelectMinuteKeyup = function (event, minute) {
        // tslint:disable-next-line: deprecation
        if (event.keyCode === KeyCode.M_ENTER || event.keyCode === KeyCode.M_RETURN) {
            this.onSelectMinute(minute);
        }
    };
    MTimepicker.prototype.onMousedown = function (event) {
        this.isMousedown = true;
    };
    MTimepicker.prototype.onMouseup = function (event) {
        this.isMousedown = false;
        // tslint:disable-next-line: deprecation
        if (event.srcElement) {
            // tslint:disable-next-line: deprecation
            this.setPositionScroll(event.srcElement);
        }
    };
    MTimepicker.prototype.onOk = function () {
        if (!isNaN(this.internalHour) && !isNaN(this.internalMinute)) {
            this.emitChange(this.formatTimeString());
        }
        this.open = false;
        this.as().focusInput();
    };
    MTimepicker.prototype.onOpen = function () {
        var _this = this;
        requestAnimationFrame(function () {
            _this.scrollToSelection(_this.$refs.hours);
            _this.scrollToSelection(_this.$refs.minutes);
        });
        this.emitOpen();
    };
    MTimepicker.prototype.onClose = function () {
        if (isNaN(this.internalHour) || isNaN(this.internalMinute)) {
            this.resetPopupTime();
        }
        else {
            this.updatePopupTime(this.internalTime);
        }
        this.emitClose();
    };
    MTimepicker.prototype.created = function () {
        this.internalTime = this.getFormatTime(this.value);
        this.updatePopupTime(this.internalTime);
    };
    MTimepicker.prototype.mounted = function () {
        // create hours
        for (var i = -1; i < MAXIMUM_HOURS; i++) {
            this.hours.push(i + 1);
        }
        // create minutes
        for (var i = -1; i < MAXIMUM_MINUTES; i++) {
            this.minutes.push(i + 1);
        }
        this.internalFilteredMinutes = this.minutes;
    };
    MTimepicker.prototype.updatePopupTime = function (value) {
        if (value) {
            this.internalHour = this.timeStringToNumber(value).hour;
            this.internalMinute = this.timeStringToNumber(value).minute;
        }
        else {
            this.resetPopupTime();
        }
    };
    MTimepicker.prototype.resetPopupTime = function () {
        this.internalHour = NaN;
        this.internalMinute = NaN;
    };
    MTimepicker.prototype.getFormatTime = function (time) {
        if (!time) {
            return '';
        }
        var hourParts = time.split(':');
        return hourParts.length > 1 ? hourParts[0] + ":" + hourParts[1] : '';
    };
    MTimepicker.prototype.timeStringToNumber = function (value) {
        var timeString = value.split(':');
        var timeObject = {
            hour: parseInt(timeString[0], 10),
            minute: parseInt(timeString[1], 10)
        };
        return timeObject;
    };
    MTimepicker.prototype.validateTime = function (value) {
        this.internalTimeErrorMessage = '';
        if (!this.skipInputValidation && validateTimeString(value)) {
            if (this.validateTimeRange(value)) {
                this.internalTimeErrorMessage = '';
                return true;
            }
            else {
                this.internalTimeErrorMessage = this.i18nOutOfBoundsError;
                return false;
            }
        }
        return true;
    };
    MTimepicker.prototype.validateTimeRange = function (value) {
        return !value.length || (this.validateHour(value) && this.validateMinute(value));
    };
    MTimepicker.prototype.validateHour = function (value) {
        return this.timeStringToNumber(value).hour >= this.timeStringToNumber(this.min).hour &&
            this.timeStringToNumber(value).hour <= this.timeStringToNumber(this.max).hour;
    };
    MTimepicker.prototype.validateMinute = function (value) {
        var time = this.timeStringToNumber(value);
        var timeMin = this.timeStringToNumber(this.min);
        var timeMax = this.timeStringToNumber(this.max);
        if (time.hour === timeMin.hour) {
            return time.minute >= timeMin.minute;
        }
        else if (time.hour === timeMax.hour) {
            return time.minute <= timeMax.minute;
        }
        return true;
    };
    MTimepicker.prototype.formatTimeString = function () {
        return this.formatNumber(this.internalHour) + ':' + this.formatNumber(this.internalMinute);
    };
    MTimepicker.prototype.formatNumber = function (value) {
        return value < 10 ? '0' + value : value.toString();
    };
    MTimepicker.prototype.scrollToSelection = function (container) {
        var selectedElement = container.querySelector('.m--is-selected');
        setTimeout(function () {
            if (selectedElement) {
                container.scrollTop = selectedElement['offsetTop'] - container.clientHeight / 2 + selectedElement.clientHeight / 2;
            }
        }, 10);
    };
    MTimepicker.prototype.setPositionScroll = function (el) {
        el.scrollTop = Math.round(el.scrollTop / 44) * 44;
    };
    __decorate([
        Model('change'),
        Prop({ default: '' })
    ], MTimepicker.prototype, "value", void 0);
    __decorate([
        Prop({ default: '00:00' })
    ], MTimepicker.prototype, "min", void 0);
    __decorate([
        Prop({ default: '23:59' })
    ], MTimepicker.prototype, "max", void 0);
    __decorate([
        Prop({ default: 5 })
    ], MTimepicker.prototype, "step", void 0);
    __decorate([
        Prop({ default: InputMaxWidth.Small })
    ], MTimepicker.prototype, "maxWidth", void 0);
    __decorate([
        Prop({ default: false })
    ], MTimepicker.prototype, "hideInternalErrorMessage", void 0);
    __decorate([
        Prop({ default: false })
    ], MTimepicker.prototype, "skipInputValidation", void 0);
    __decorate([
        Prop({ default: function () { return "mTimepicker-" + uuid.generate(); } })
    ], MTimepicker.prototype, "id", void 0);
    __decorate([
        Emit('change')
    ], MTimepicker.prototype, "emitChange", null);
    __decorate([
        Emit('click')
    ], MTimepicker.prototype, "emitClick", null);
    __decorate([
        Emit('open')
    ], MTimepicker.prototype, "emitOpen", null);
    __decorate([
        Emit('close')
    ], MTimepicker.prototype, "emitClose", null);
    __decorate([
        Watch('value')
    ], MTimepicker.prototype, "updateInternalTime", null);
    MTimepicker = __decorate([
        WithRender,
        Component({
            components: {
                MPopup: MPopup,
                MIconButton: MIconButton,
                MValidationMessage: MValidationMessage,
                MLink: MLink,
                MInputStyle: MInputStyle,
                MInputMask: MInputMask,
                MCalendarButton: MCalendarButton
            },
            directives: (_a = {},
                _a[DIRECTIVE_POPUP_NAME] = MPopupDirective,
                _a),
            mixins: [
                InputState,
                InputManagement,
                InputWidth,
                InputLabel,
                MediaQueries
            ]
        })
    ], MTimepicker);
    return MTimepicker;
}(ModulVue));
export { MTimepicker };
var TimepickerPlugin = {
    install: function (v) {
        v.use(MediaQueriesPlugin);
        v.component(TIMEPICKER_NAME, MTimepicker);
    }
};
export default TimepickerPlugin;
//# sourceMappingURL=timepicker.js.map