var _a;
import { __awaiter, __decorate, __extends, __generator } 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 { Enums } from '../../utils/enums/enums';
import MediaQueriesPlugin from '../../utils/media-queries/media-queries';
import ModulDate, { DatePrecision } from '../../utils/modul-date/modul-date';
import uuid from '../../utils/uuid/uuid';
import { ModulVue } from '../../utils/vue/vue';
import { MCalendar } from '../calendar/calendar';
import { MBaseCalendarType, MBaseCalendarView } from '../calendar/calendar-renderer/base-calendar/base-calendar';
import { DATEPICKER_NAME } from '../component-names';
import { MI18n } from '../i18n/i18n';
import { MIconButton } from '../icon-button/icon-button';
import { MInputMask } from '../input-mask/input-mask';
import { MInputStyle } from '../input-style/input-style';
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 './datepicker.html?style=./datepicker.scss';
export var MDatepickerDefaultView;
(function (MDatepickerDefaultView) {
    MDatepickerDefaultView["Month"] = "month";
    MDatepickerDefaultView["Day"] = "day";
})(MDatepickerDefaultView || (MDatepickerDefaultView = {}));
var MDatepicker = /** @class */ (function (_super) {
    __extends(MDatepicker, _super);
    function MDatepicker() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.validationMessageId = uuid.generate();
        _this.internalOpen = false;
        _this.internalCalendarErrorMessage = '';
        _this.inputModel = '';
        _this.internalDateModel = '';
        return _this;
    }
    MDatepicker.prototype.created = function () {
        if (this.value instanceof Date) {
            this.$log.warn('Using a Date as value for datepicker is not recommended and will be deprecated in 1.0, the value should use a string with the format "YYYY-MM-DD". Using a Date object can lead to timezone issue in your projet see -> https://stackoverflow.com/questions/29174810/javascript-date-timezone-issue');
        }
    };
    Object.defineProperty(MDatepicker.prototype, "inputOptions", {
        get: function () {
            if (this.isTypeYearsMonths) {
                return {
                    numericOnly: true,
                    delimiters: ['-'],
                    blocks: [4, 2]
                };
            }
            return {
                numericOnly: true,
                delimiters: ['-', '-'],
                blocks: [4, 2, 2]
            };
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "isTypeYearsMonths", {
        get: function () {
            return this.type === MBaseCalendarType.YEARS_MONTHS;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "propPlaceholder", {
        get: function () {
            if (this.placeholder) {
                return this.placeholder;
            }
            return this.isTypeYearsMonths ? this.$i18n.translate('m-datepicker:placeholder-aaaa-mm') : this.$i18n.translate('m-datepicker:placeholder-aaaa-mm-jj');
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "formattedDate", {
        get: function () {
            return this.convertValueToModel(this.model);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "hasCalandarError", {
        get: function () {
            return this.internalCalendarErrorMessage !== '' || this.as().hasError;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "calandarErrorMessage", {
        get: function () {
            if (this.internalCalendarErrorMessage && !this.hideInternalErrorMessage) {
                return this.internalCalendarErrorMessage;
            }
            else {
                return this.as().errorMessage !== undefined ? this.as().errorMessage : '';
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "open", {
        get: function () {
            return this.internalOpen;
        },
        set: function (open) {
            if (this.as().active) {
                this.internalOpen = open;
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "minDateString", {
        get: function () {
            return this.convertValueToModel(this.min);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "maxDateString", {
        get: function () {
            return this.convertValueToModel(this.max);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "minModulDate", {
        get: function () {
            return new ModulDate(this.min);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "maxModulDate", {
        get: function () {
            return new ModulDate(this.max);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "maxInputLenght", {
        get: function () {
            return this.isTypeYearsMonths ? 7 : 10;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "isLessThanTablet", {
        get: function () {
            return this.as().isMqMaxS;
        },
        enumerable: false,
        configurable: true
    });
    MDatepicker.prototype.onOpen = function () {
        return __awaiter(this, void 0, void 0, function () {
            var inputMask;
            return __generator(this, function (_a) {
                inputMask = this.$refs.input;
                inputMask === null || inputMask === void 0 ? void 0 : inputMask.focusAndSelectAll();
                return [2 /*return*/];
            });
        });
    };
    MDatepicker.prototype.onClose = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                // emit blur if not focus and still open
                if (!this.as().internalIsFocus) {
                    this.emitBlur();
                }
                return [2 /*return*/];
            });
        });
    };
    MDatepicker.prototype.emitBlur = function () {
        if (!this.skipInputValidation) {
            this.showErrorMessage(this.inputModel);
        }
    };
    MDatepicker.prototype.emitClick = function (event) { };
    MDatepicker.prototype.emitKeydown = function (event) { };
    MDatepicker.prototype.onSkipInputValidationChangement = function (skipInputValidation) {
        this.inputDate(this.inputModel);
        this.showErrorMessage(this.inputModel);
    };
    MDatepicker.prototype.selectDate = function (selectedDate) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                this.internalCalendarErrorMessage = '';
                this.model = this.convertValueToModel(selectedDate);
                this.inputModel = this.internalDateModel;
                this.open = false;
                this.as().focusInput();
                return [2 /*return*/];
            });
        });
    };
    MDatepicker.prototype.inputDate = function (inputValue) {
        this.inputModel = inputValue;
        if (!inputValue || inputValue === '') {
            this.model = '';
            this.clearErrorMessage();
        }
        else {
            if (this.open) {
                this.open = false;
            }
            if (this.skipInputValidation) {
                this.model = inputValue;
            }
            else {
                if (inputValue.length === this.maxInputLenght && this.showErrorMessage(inputValue)) {
                    this.model = this.inputModel;
                }
                else {
                    this.model = '';
                }
            }
        }
    };
    // Model management
    // override from InputManagement
    MDatepicker.prototype.onValueChange = function (value) {
        if (this.internalDateModel !== this.convertModelToString(value)) {
            this.internalDateModel = this.convertModelToString(value);
            this.inputModel = this.internalDateModel ? this.internalDateModel : '';
            this.showErrorMessage(this.inputModel);
        }
    };
    Object.defineProperty(MDatepicker.prototype, "model", {
        get: function () {
            return this.internalDateModel;
        },
        // override from InputManagement
        set: function (value) {
            if (this.internalDateModel !== value) {
                this.internalDateModel = value;
                this.emitChange();
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MDatepicker.prototype, "hasValue", {
        // override from InputManagement
        get: function () {
            return !!(this.inputModel || '').toString().trim();
        },
        enumerable: false,
        configurable: true
    });
    MDatepicker.prototype.togglePopup = function (event) {
        if (this.as().active) {
            this.open = !this.open;
        }
        // stop event propagation to parent.
        event.stopPropagation();
    };
    MDatepicker.prototype.emitChange = function () {
        this.$emit('change', this.convertStringToModel(this.internalDateModel));
    };
    MDatepicker.prototype.onKeydown = function (event) {
        if (this.as().active) {
            if (event.key === 'Tab') {
                // close popop if open and tab key is pressed (accessibility)
                if (this.open) {
                    this.open = false;
                }
            }
            this.emitKeydown(event);
        }
    };
    Object.defineProperty(MDatepicker.prototype, "hasErrorMessage", {
        get: function () {
            return (!!this.as().errorMessage || this.as().errorMessage === ' '
                || !!(this.internalCalendarErrorMessage || '').trim()) &&
                !this.as().disabled && !this.as().waiting;
        },
        enumerable: false,
        configurable: true
    });
    // Focus management.
    // override from InputManagement
    MDatepicker.prototype.onFocus = function (event) {
        this.as().internalIsFocus = this.as().active;
        if (this.as().internalIsFocus) {
            this.$emit('focus', event);
        }
    };
    // override from InputManagement
    MDatepicker.prototype.onClick = function (event) {
        this.as().internalIsFocus = this.as().active;
        if (this.as().internalIsFocus) {
            this.as().focusInput();
        }
        this.emitClick(event);
    };
    // override from InputManagement
    MDatepicker.prototype.onBlur = function (event) {
        this.as().internalIsFocus = false;
        if (!this.open) { // do not emit blur if still open
            this.emitBlur();
        }
    };
    Object.defineProperty(MDatepicker.prototype, "isFocus", {
        // override from Input-management
        get: function () {
            return this.as().internalIsFocus || this.open;
        },
        enumerable: false,
        configurable: true
    });
    MDatepicker.prototype.convertValueToModel = function (input) {
        if (input) {
            try {
                return new ModulDate(input).toString();
            }
            catch (err) {
                return '';
            }
        }
        return '';
    };
    MDatepicker.prototype.validateDateFormat = function (dateString) {
        return Boolean(dateString) && !isNaN(Date.parse(dateString));
    };
    MDatepicker.prototype.convertStringToModel = function (newValue) {
        if (newValue && this.value instanceof Date) {
            return new Date(newValue);
        }
        else {
            return newValue;
        }
    };
    MDatepicker.prototype.convertModelToString = function (value) {
        if (value instanceof Date) {
            return new ModulDate(value.toISOString()).toString();
        }
        else {
            if (value) {
                return value;
            }
            else {
                return '';
            }
        }
    };
    MDatepicker.prototype.clearErrorMessage = function () {
        this.internalCalendarErrorMessage = '';
    };
    MDatepicker.prototype.showErrorMessage = function (inputValue) {
        if (inputValue === '' || inputValue === undefined || inputValue === null || this.skipInputValidation) {
            this.internalCalendarErrorMessage = '';
            return true;
        }
        else if (inputValue.length === this.maxInputLenght && this.validateDateFormat(inputValue)) {
            var newDate = new ModulDate(inputValue);
            if (newDate.isBetween(this.minModulDate, this.maxModulDate)) {
                this.internalCalendarErrorMessage = '';
                return true;
            }
            else {
                this.internalCalendarErrorMessage = this.$i18n.translate('m-datepicker:out-of-range-error');
                return false;
            }
        }
        else {
            this.internalCalendarErrorMessage = this.$i18n.translate('m-datepicker:format-error');
            return false;
        }
    };
    __decorate([
        Model('change'),
        Prop()
    ], MDatepicker.prototype, "value", void 0);
    __decorate([
        Prop()
    ], MDatepicker.prototype, "label", void 0);
    __decorate([
        Prop({
            default: MBaseCalendarView.DAYS,
            validator: function (value) { return Enums.toValueArray(MBaseCalendarView).includes(value); }
        })
    ], MDatepicker.prototype, "initialView", void 0);
    __decorate([
        Prop({
            default: MBaseCalendarType.FULL_DATE,
            validator: function (value) { return Enums.toValueArray(MBaseCalendarType).includes(value); }
        })
    ], MDatepicker.prototype, "type", void 0);
    __decorate([
        Prop({ default: function () { return new ModulDate().subtract(10, DatePrecision.YEAR); } })
    ], MDatepicker.prototype, "min", void 0);
    __decorate([
        Prop({ default: function () { return new ModulDate().add(10, DatePrecision.YEAR); } })
    ], MDatepicker.prototype, "max", void 0);
    __decorate([
        Prop()
    ], MDatepicker.prototype, "placeholder", void 0);
    __decorate([
        Prop({ default: InputMaxWidth.Small })
    ], MDatepicker.prototype, "maxWidth", void 0);
    __decorate([
        Prop({ default: false })
    ], MDatepicker.prototype, "hideInternalErrorMessage", void 0);
    __decorate([
        Prop({ default: false })
    ], MDatepicker.prototype, "skipInputValidation", void 0);
    __decorate([
        Prop()
    ], MDatepicker.prototype, "ariaDescribedby", void 0);
    __decorate([
        Prop({ default: function () { return "mDatepicker-" + uuid.generate(); } })
    ], MDatepicker.prototype, "id", void 0);
    __decorate([
        Emit('open')
    ], MDatepicker.prototype, "onOpen", null);
    __decorate([
        Emit('close')
    ], MDatepicker.prototype, "onClose", null);
    __decorate([
        Emit('blur')
    ], MDatepicker.prototype, "emitBlur", null);
    __decorate([
        Emit('click')
    ], MDatepicker.prototype, "emitClick", null);
    __decorate([
        Emit('keydown')
    ], MDatepicker.prototype, "emitKeydown", null);
    __decorate([
        Watch('skipInputValidation')
    ], MDatepicker.prototype, "onSkipInputValidationChangement", null);
    __decorate([
        Watch('value', { immediate: true })
    ], MDatepicker.prototype, "onValueChange", null);
    MDatepicker = __decorate([
        WithRender,
        Component({
            components: {
                MInputMask: MInputMask,
                MInputStyle: MInputStyle,
                MIconButton: MIconButton,
                MI18n: MI18n,
                MValidationMessage: MValidationMessage,
                MPopup: MPopup,
                MCalendar: MCalendar
            },
            directives: (_a = {},
                _a[DIRECTIVE_POPUP_NAME] = MPopupDirective,
                _a),
            mixins: [
                InputState,
                InputLabel,
                InputManagement,
                InputWidth,
                MediaQueries
            ]
        })
    ], MDatepicker);
    return MDatepicker;
}(ModulVue));
export { MDatepicker };
var DatepickerPlugin = {
    install: function (v) {
        v.use(MediaQueriesPlugin);
        v.component(DATEPICKER_NAME, MDatepicker);
    }
};
export default DatepickerPlugin;
//# sourceMappingURL=datepicker.js.map