import { __assign } from "tslib";
import { addDays, addWeeks, compareDates, findAvailableDate } from '@fluentui/date-time-utilities';
import { css, getRTLSafeKeyCode, KeyCodes } from '@uifabric-vue/utilities';
import Vue from 'vue';
import { withCalendarProps } from '../Calendar/useCalendar';
import { withCalendarGridRowProps } from './useCalendarDayGrid';
export var CalendarGridDayCell = Vue.extend({
    name: 'CalendarGridDayCell',
    props: __assign(__assign(__assign({}, withCalendarProps()), withCalendarGridRowProps()), { day: { type: Object, required: true }, dayIndex: { type: Number, required: true } }),
    data: function () {
        return {
            isHovering: false,
            isPressing: false,
        };
    },
    computed: {
        cornerStyle: function () {
            var _a, _b;
            return (_b = (_a = this.weekCorners) === null || _a === void 0 ? void 0 : _a[this.weekIndex + '_' + this.dayIndex]) !== null && _b !== void 0 ? _b : '';
        },
        isNavigatedDate: function () {
            var _a = this, navigatedDate = _a.navigatedDate, day = _a.day;
            return compareDates(navigatedDate, day.originalDate);
        },
        ariaLabel: function () {
            var _a = this, day = _a.day, strings = _a.strings;
            return [
                day.originalDate.getDate(),
                strings.months[day.originalDate.getMonth()],
                day.originalDate.getFullYear(),
                day.isMarked && strings.dayMarkedAriaLabel,
            ].filter(function (e) { return e; }).join(', ');
        },
    },
    methods: {
        navigateMonthEdge: function (ev, date) {
            var _a = this, restrictedDates = _a.restrictedDates, minDate = _a.minDate, maxDate = _a.maxDate, weeks = _a.weeks;
            var targetDate;
            var direction = 1; // by default search forward
            if (ev.which === KeyCodes.up) {
                targetDate = addWeeks(date, -1);
                direction = -1;
            }
            else if (ev.which === KeyCodes.down) {
                targetDate = addWeeks(date, 1);
            }
            else if (ev.which === getRTLSafeKeyCode(KeyCodes.left)) {
                targetDate = addDays(date, -1);
                direction = -1;
            }
            else if (ev.which === getRTLSafeKeyCode(KeyCodes.right)) {
                targetDate = addDays(date, 1);
            }
            if (!targetDate) {
                // if we couldn't find a target date at all, do nothing
                return;
            }
            var findAvailableDateOptions = {
                initialDate: date,
                targetDate: targetDate,
                direction: direction,
                restrictedDates: restrictedDates,
                minDate: minDate,
                maxDate: maxDate,
            };
            // target date is restricted, search in whatever direction until finding the next possible date,
            // stopping at boundaries
            var nextDate = findAvailableDate(findAvailableDateOptions);
            if (!nextDate) {
                // if no dates available in initial direction, try going backwards
                findAvailableDateOptions.direction = -direction;
                nextDate = findAvailableDate(findAvailableDateOptions);
            }
            // if the nextDate is still inside the same focusZone area, let the focusZone handle setting the focus so we
            // don't jump the view unnecessarily
            var isInCurrentView = weeks &&
                nextDate &&
                weeks.slice(1, weeks.length - 1).some(function (week) {
                    return week.some(function (dayToCompare) {
                        return compareDates(dayToCompare.originalDate, nextDate);
                    });
                });
            if (isInCurrentView) {
                return;
            }
            // else, fire navigation on the date to change the view to show it
            if (nextDate) {
                this.$emit('onNavigateDate', nextDate, true);
                ev.preventDefault();
            }
        },
        onMouseOverDay: function (ev) {
            this.isHovering = true;
        },
        onMouseOutDay: function (ev) {
            this.isHovering = false;
            this.isPressing = false;
        },
        onMouseDownDay: function (ev) {
            this.isPressing = true;
        },
        onMouseUpDay: function (ev) {
            this.isPressing = false;
        },
        onDayKeyDown: function (ev, day) {
            if (ev.which === KeyCodes.enter) {
                this.$emit('onSelectDate', day.originalDate);
            }
            else {
                this.navigateMonthEdge(ev, day.originalDate);
            }
        },
    },
    render: function (h) {
        var _this = this;
        var _a = this, allFocusable = _a.allFocusable, ariaHidden = _a.ariaHidden, ariaLabel = _a.ariaLabel, classNames = _a.classNames, day = _a.day, dateTimeFormatter = _a.dateTimeFormatter, weekCorners = _a.weekCorners, activeDescendantId = _a.activeDescendantId, cornerStyle = _a.cornerStyle, isNavigatedDate = _a.isNavigatedDate;
        return h('td', {
            class: css(classNames.dayCell, weekCorners && cornerStyle, day.isSelected && classNames.daySelected, day.isSelected && 'ms-CalendarDay-daySelected', !day.isInBounds && classNames.dayOutsideBounds, !day.isInMonth && classNames.dayOutsideNavigatedMonth, this.isHovering && 'ms-CalendarDay-hoverStyle', this.isPressing && 'ms-CalendarDay-pressedStyle'),
            attrs: {
                role: 'gridcell',
                tabIndex: isNavigatedDate ? 0 : undefined,
                'aria-hidden': ariaHidden,
                'aria-disabled': !ariaHidden && !day.isInBounds,
                'aria-readonly': true,
                'aria-current': day.isSelected ? 'date' : undefined,
                'aria-selected': day.isInBounds ? day.isSelected : undefined,
                'data-is-focusable': !ariaHidden && (allFocusable || (day.isInBounds ? true : undefined)),
            },
            on: __assign(__assign({}, day.isInBounds && !ariaHidden && { click: day.onSelected }), !ariaHidden && {
                mouseover: this.onMouseOverDay,
                mouseout: this.onMouseOutDay,
                mousedown: this.onMouseDownDay,
                mouseup: this.onMouseUpDay,
                keydown: function (e) { return _this.onDayKeyDown(e, day); },
            }),
        }, [
            h('button', {
                key: day.key + 'button',
                class: css(classNames.dayButton, day.isToday && classNames.dayIsToday, day.isToday && 'ms-CalendarDay-dayIsToday'),
                attrs: {
                    'aria-hidden': ariaHidden,
                    'aria-label': ariaLabel,
                    id: isNavigatedDate ? activeDescendantId : undefined,
                    disabled: !ariaHidden && !day.isInBounds,
                    type: 'button',
                    tabIndex: -1,
                    'data-is-focusable': false,
                },
                // ref
            }, [
                h('span', { attrs: { 'aria-hidden': 'true' } }, dateTimeFormatter.formatDay(day.originalDate)),
                day.isMarked && h('div', { attrs: { 'aria-hidden': 'true' }, class: classNames.dayMarker }),
            ]),
        ]);
    },
});
//# sourceMappingURL=CalendarGridDayCell.js.map