import { __decorate, __extends } from "tslib";
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import { Enums } from '../../../../utils/enums/enums';
import { KeyCode } from '../../../../utils/keycode/keycode';
import uuid from '../../../../utils/uuid/uuid';
import { MIconButton } from '../../../icon-button/icon-button';
import { MLink, MLinkMode } from '../../../link/link';
import { MCalendarButton } from '../../calendar-button/calendar-button';
import { CalendarType } from '../../calendar-state/state/calendar-state';
import ModulDate, { DatePrecision } from './../../../../utils/modul-date/modul-date';
import { MAbstractCalendarRenderer } from './../abstract-calendar-renderer';
import WithRender from './base-calendar.html';
import './base-calendar.scss';
var TRANSLATION_ROOT = 'm-calendar' + ':';
var TRANSLATION_MONTHS = TRANSLATION_ROOT + 'month';
var TRANSLATION_WEEKDAYS = TRANSLATION_ROOT + 'weekday';
var TRANSLATION_SUFFIXE = '.short';
var MonthsNames;
(function (MonthsNames) {
    MonthsNames["JANUARY"] = "january";
    MonthsNames["FEBRUARY"] = "february";
    MonthsNames["MARCH"] = "march";
    MonthsNames["APRIL"] = "april";
    MonthsNames["MAY"] = "may";
    MonthsNames["JUNE"] = "june";
    MonthsNames["JULY"] = "july";
    MonthsNames["AUGUST"] = "august";
    MonthsNames["SEPTEMBER"] = "september";
    MonthsNames["OCTOBER"] = "october";
    MonthsNames["NOVEMBER"] = "november";
    MonthsNames["DECEMBER"] = "december";
})(MonthsNames || (MonthsNames = {}));
var WeekdayNames;
(function (WeekdayNames) {
    WeekdayNames["SUNDAY"] = "sunday";
    WeekdayNames["MONDAY"] = "monday";
    WeekdayNames["TUESDAY"] = "tuesday";
    WeekdayNames["WEDNESDAY"] = "wednesday";
    WeekdayNames["THURSDAY"] = "thursday";
    WeekdayNames["FRIDAY"] = "friday";
    WeekdayNames["SATURDAY"] = "saturday";
})(WeekdayNames || (WeekdayNames = {}));
export var MBaseCalendarView;
(function (MBaseCalendarView) {
    MBaseCalendarView["DAYS"] = "days";
    MBaseCalendarView["YEARS_MONTHS"] = "years-months";
})(MBaseCalendarView || (MBaseCalendarView = {}));
export var MBaseCalendarType;
(function (MBaseCalendarType) {
    MBaseCalendarType["FULL_DATE"] = "full-date";
    MBaseCalendarType["YEARS_MONTHS"] = "years-months";
})(MBaseCalendarType || (MBaseCalendarType = {}));
var MBaseCalendar = /** @class */ (function (_super) {
    __extends(MBaseCalendar, _super);
    function MBaseCalendar() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.mBaseCalendarView = MBaseCalendarView;
        _this.previousMonthLabel = _this.$i18n.translate('m-calendar:previous.month');
        _this.nextMonthLabel = _this.$i18n.translate('m-calendar:next.month');
        _this.previousYearLabel = _this.$i18n.translate('m-calendar:previous.year');
        _this.nextYearLabel = _this.$i18n.translate('m-calendar:next.year');
        _this.id = "m-simple-calendar-" + uuid.generate();
        _this.modeLinkCurrentMonthAndYear = MLinkMode.Button;
        _this.animReady = false;
        _this.internalCurrentView = MBaseCalendarView.DAYS;
        return _this;
    }
    MBaseCalendar.prototype.visibleChanged = function (visible) {
        var isInYearView = this.isTypeYearsMonths || this.initialView === MBaseCalendarView.YEARS_MONTHS;
        if (visible && isInYearView) {
            this.scrollToCurrentYear();
        }
    };
    MBaseCalendar.prototype.created = function () {
        this.currentView = this.initialView; // Set currentView value in created() to hide animation when the component is diplayed for the firt time
    };
    MBaseCalendar.prototype.onToogleView = function () {
        this.currentView === MBaseCalendarView.DAYS ? this.currentView = MBaseCalendarView.YEARS_MONTHS : this.currentView = MBaseCalendarView.DAYS;
    };
    MBaseCalendar.prototype.onYearMonthSelect = function (year, month) {
        var _this = this;
        if (!month.isDisabled) {
            month.isCurrent = true;
            if (this.isTypeYearsMonths) {
                _super.prototype.onYearMonthSelect.call(this, year, month);
            }
            else {
                _super.prototype.onYearSelect.call(this, year);
                _super.prototype.onMonthSelect.call(this, month);
                // Delay to show the user selection
                setTimeout(function () {
                    _this.currentView = MBaseCalendarView.DAYS;
                }, 300);
            }
        }
    };
    MBaseCalendar.prototype.onYearMonthSelectKeyup = function ($event, year, month) {
        // tslint:disable-next-line: deprecation
        if ($event.keyCode === KeyCode.M_ENTER || $event.keyCode === KeyCode.M_RETURN) {
            this.onYearMonthSelect(year, month);
        }
    };
    MBaseCalendar.prototype.onYearNext = function (event) {
        _super.prototype.onYearNext.call(this, event);
    };
    MBaseCalendar.prototype.onYearPrevious = function (event) {
        _super.prototype.onYearPrevious.call(this, event);
    };
    MBaseCalendar.prototype.onMonthNext = function (event) {
        _super.prototype.onMonthNext.call(this, event);
    };
    MBaseCalendar.prototype.onMonthPrevious = function (event) {
        _super.prototype.onMonthPrevious.call(this, event);
    };
    MBaseCalendar.prototype.onDaySelect = function (day) {
        _super.prototype.onDaySelect.call(this, day);
    };
    MBaseCalendar.prototype.onDayMouseEnter = function (day) {
        _super.prototype.onDayMouseEnter.call(this, day);
    };
    MBaseCalendar.prototype.onKeyUp = function ($event, day) {
        // tslint:disable-next-line: deprecation
        if ($event.keyCode === KeyCode.M_ENTER || $event.keyCode === KeyCode.M_RETURN) {
            _super.prototype.onDaySelect.call(this, day);
        }
        // tslint:disable-next-line: deprecation
        if ($event.keyCode === KeyCode.M_TAB) {
            _super.prototype.onDayKeyboardTab.call(this, day);
        }
    };
    MBaseCalendar.prototype.onDayMouseLeave = function (day) {
        _super.prototype.onDayMouseLeave.call(this, day);
    };
    MBaseCalendar.prototype.isDateInFuture = function (day) {
        return !!this.calendar.type && this.calendar.type === CalendarType.DATE_RANGE
            && !!this.calendar.value && !!this.calendar.value.begin
            && day.date.isAfter(new ModulDate(this.calendar.value.begin));
    };
    MBaseCalendar.prototype.isInsideRange = function (day) {
        return !!this.calendar.type && this.calendar.type === CalendarType.DATE_RANGE
            && !!this.calendar.value && !!this.calendar.value.begin
            && !!this.calendar.value && !!this.calendar.value.end
            && day.isHighlighted;
    };
    MBaseCalendar.prototype.isSelectionStart = function (day) {
        return day.isSelectionStart && !this.hideDay(day);
    };
    MBaseCalendar.prototype.isSelectionEnd = function (day) {
        return day.isSelectionEnd && !this.hideDay(day);
    };
    MBaseCalendar.prototype.hideDay = function (day) {
        return (day.isInNextMonth || day.isInPreviousMonth) && !this.showMonthBeforeAfter;
    };
    MBaseCalendar.prototype.buildRef = function (refPrefix, year, month, day) {
        var refName = refPrefix + "-" + this.padString(year, 4) + "-" + this.padString(month, 2);
        if (refPrefix === MBaseCalendarView.DAYS) {
            return refName + "-" + this.padString(day, 2);
        }
        return refName;
    };
    MBaseCalendar.prototype.monthIndexToShortName = function (index) {
        return this.monthsNames[index];
    };
    MBaseCalendar.prototype.scrollToCurrentYear = function () {
        var _this = this;
        this.$nextTick(function () {
            var yearsMonthsViewEl = _this.$refs.yearsMonthsView;
            var spacingBeforeCurrentYear = 16;
            if (yearsMonthsViewEl) {
                yearsMonthsViewEl.scrollTop = yearsMonthsViewEl.querySelector('[data-current-year="true"]').offsetTop - spacingBeforeCurrentYear || 0;
            }
        });
    };
    Object.defineProperty(MBaseCalendar.prototype, "currentView", {
        get: function () {
            return this.internalCurrentView;
        },
        set: function (view) {
            if (this.isTypeYearsMonths) {
                this.internalCurrentView = MBaseCalendarView.YEARS_MONTHS;
            }
            else {
                this.internalCurrentView = view;
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "isTypeYearsMonths", {
        get: function () {
            return this.type === MBaseCalendarType.YEARS_MONTHS;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "currentYear", {
        get: function () {
            return this.calendar.dates.current.fullYear();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "currentMonth", {
        get: function () {
            return this.calendar.dates.current.month();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "currentMonthName", {
        get: function () {
            return this.monthsNamesLong[this.currentMonth];
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "weekdaysLabels", {
        get: function () {
            return this.daysNames;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "years", {
        get: function () {
            return this.calendar.years;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "yearsMonths", {
        get: function () {
            return this.calendar.yearsMonths;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "months", {
        get: function () {
            return this.calendar.months;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "days", {
        get: function () {
            return this.calendar.days;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "isYearsMonthsView", {
        get: function () {
            return this.currentView === MBaseCalendarView.YEARS_MONTHS;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "isDaysView", {
        get: function () {
            return this.currentView === MBaseCalendarView.DAYS;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "isMinYear", {
        get: function () {
            return this.currentYear === Math.min.apply(Math, this.calendar.years.map(function (year) { return year.year; }));
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "isMaxYear", {
        get: function () {
            return this.currentYear === Math.max.apply(Math, this.calendar.years.map(function (year) { return year.year; }));
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "isMinMonth", {
        get: function () {
            return this.calendar.dates.current.isSameOrBefore(this.calendar.dates.min, DatePrecision.MONTH);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "isMaxMonth", {
        get: function () {
            return this.calendar.dates.current.isSameOrAfter(this.calendar.dates.max, DatePrecision.MONTH);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "isMaxRow", {
        get: function () {
            if (this.isTypeYearsMonths) {
                return false;
            }
            var numberOfDays = this.calendar.days.length;
            return numberOfDays / 7 > 5 ? true : false;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseCalendar.prototype, "isButtonToogleViewDisabled", {
        get: function () {
            return this.isMinMonth && this.isMaxYear || this.isTypeYearsMonths;
        },
        enumerable: false,
        configurable: true
    });
    MBaseCalendar.prototype.padString = function (value, length) {
        if (length === void 0) { length = 2; }
        return ('000' + value).slice(-1 * length);
    };
    __decorate([
        Prop({
            default: MBaseCalendarView.DAYS,
            validator: function (value) { return Enums.toValueArray(MBaseCalendarView).includes(value); }
        })
    ], MBaseCalendar.prototype, "initialView", void 0);
    __decorate([
        Prop({ default: true })
    ], MBaseCalendar.prototype, "showMonthBeforeAfter", void 0);
    __decorate([
        Prop({
            default: function () {
                return Object.keys(MonthsNames).map(function (key) {
                    return Vue.prototype.$i18n.translate(TRANSLATION_MONTHS + "." + MonthsNames[key] + TRANSLATION_SUFFIXE);
                });
            }
        })
    ], MBaseCalendar.prototype, "monthsNames", void 0);
    __decorate([
        Prop({
            default: function () {
                return Object.keys(MonthsNames).map(function (key) {
                    return Vue.prototype.$i18n.translate(TRANSLATION_MONTHS + "." + MonthsNames[key]);
                });
            }
        })
    ], MBaseCalendar.prototype, "monthsNamesLong", void 0);
    __decorate([
        Prop({
            default: function () {
                return Object.keys(WeekdayNames).map(function (key) {
                    return Vue.prototype.$i18n.translate(TRANSLATION_WEEKDAYS + "." + WeekdayNames[key] + TRANSLATION_SUFFIXE);
                });
            }
        })
    ], MBaseCalendar.prototype, "daysNames", void 0);
    __decorate([
        Prop({
            default: MBaseCalendarType.FULL_DATE,
            validator: function (value) { return Enums.toValueArray(MBaseCalendarType).includes(value); }
        })
    ], MBaseCalendar.prototype, "type", void 0);
    __decorate([
        Prop({ default: true })
    ], MBaseCalendar.prototype, "visible", void 0);
    __decorate([
        Watch('visible', { immediate: true })
    ], MBaseCalendar.prototype, "visibleChanged", null);
    MBaseCalendar = __decorate([
        WithRender,
        Component({
            components: {
                MLink: MLink,
                MIconButton: MIconButton,
                MCalendarButton: MCalendarButton
            }
        })
    ], MBaseCalendar);
    return MBaseCalendar;
}(MAbstractCalendarRenderer));
export default MBaseCalendar;
//# sourceMappingURL=base-calendar.js.map