"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = require("react");
var Utilities_1 = require("../../Utilities");
var FocusZone_1 = require("../../FocusZone");
var DateMath_1 = require("../../utilities/dateMath/DateMath");
var stylesImport = require("./Calendar.scss");
var styles = stylesImport;
var DAYS_IN_WEEK = 7;
var CalendarDay = (function (_super) {
    __extends(CalendarDay, _super);
    function CalendarDay(props) {
        var _this = _super.call(this, props) || this;
        var navigatedDate = props.navigatedDate, selectedDate = props.selectedDate, today = props.today;
        _this.state = {
            activeDescendantId: Utilities_1.getId('DatePickerDay-active'),
            weeks: _this._getWeeks(navigatedDate, selectedDate, today)
        };
        _this._onSelectNextMonth = _this._onSelectNextMonth.bind(_this);
        _this._onSelectPrevMonth = _this._onSelectPrevMonth.bind(_this);
        return _this;
    }
    CalendarDay.prototype.componentWillReceiveProps = function (nextProps) {
        var navigatedDate = nextProps.navigatedDate, selectedDate = nextProps.selectedDate, today = nextProps.today;
        this.setState({
            weeks: this._getWeeks(navigatedDate, selectedDate, today)
        });
    };
    CalendarDay.prototype.render = function () {
        var _this = this;
        var _a = this.state, activeDescendantId = _a.activeDescendantId, weeks = _a.weeks;
        var _b = this.props, firstDayOfWeek = _b.firstDayOfWeek, strings = _b.strings, navigatedDate = _b.navigatedDate, onSelectDate = _b.onSelectDate;
        var dayPickerId = Utilities_1.getId('DatePickerDay-dayPicker');
        var monthAndYearId = Utilities_1.getId('DatePickerDay-monthAndYear');
        return (React.createElement("div", { className: Utilities_1.css('ms-DatePicker-dayPicker', styles.dayPicker), id: dayPickerId },
            React.createElement("div", { className: Utilities_1.css('ms-DatePicker-header', styles.header) },
                React.createElement("div", { "aria-live": 'polite', "aria-relevant": 'text', "aria-atomic": 'true', id: monthAndYearId },
                    React.createElement("div", { className: Utilities_1.css('ms-DatePicker-month', styles.month) }, strings.months[navigatedDate.getMonth()]),
                    React.createElement("div", { className: Utilities_1.css('ms-DatePicker-year', styles.year) }, navigatedDate.getFullYear()))),
            React.createElement("div", { className: Utilities_1.css('ms-DatePicker-monthComponents', styles.monthComponents) },
                React.createElement("div", { className: Utilities_1.css('ms-DatePicker-navContainer', styles.navContainer) },
                    React.createElement("span", { className: Utilities_1.css('ms-DatePicker-prevMonth js-prevMonth', styles.prevMonth), onClick: this._onSelectPrevMonth, onKeyDown: this._onPrevMonthKeyDown, "aria-controls": dayPickerId, "aria-label": strings.prevMonthAriaLabel, role: 'button', tabIndex: 0 },
                        React.createElement("i", { className: Utilities_1.css('ms-Icon', { 'ms-Icon--ChevronLeft': !Utilities_1.getRTL(), 'ms-Icon--ChevronRight': Utilities_1.getRTL() }) })),
                    React.createElement("span", { className: Utilities_1.css('ms-DatePicker-nextMonth js-nextMonth', styles.nextMonth), onClick: this._onSelectNextMonth, onKeyDown: this._onKeyDown.bind(this, this._onSelectNextMonth), "aria-controls": dayPickerId, "aria-label": strings.nextMonthAriaLabel, role: 'button', tabIndex: 0 },
                        React.createElement("i", { className: Utilities_1.css('ms-Icon', { 'ms-Icon--ChevronLeft': Utilities_1.getRTL(), 'ms-Icon--ChevronRight': !Utilities_1.getRTL() }) }))),
                React.createElement("div", { className: Utilities_1.css('ms-DatePicker-headerToggleView js-showMonthPicker', styles.headerToggleView) })),
            React.createElement(FocusZone_1.FocusZone, null,
                React.createElement("table", { className: Utilities_1.css('ms-DatePicker-table', styles.table), role: 'grid', "aria-readonly": 'true', "aria-multiselectable": 'false', "aria-labelledby": monthAndYearId, "aria-activedescendant": activeDescendantId },
                    React.createElement("thead", null,
                        React.createElement("tr", null, strings.shortDays.map(function (val, index) {
                            return React.createElement("th", { className: Utilities_1.css('ms-DatePicker-weekday', styles.weekday), scope: 'col', key: index, title: strings.days[(index + firstDayOfWeek) % DAYS_IN_WEEK] }, strings.shortDays[(index + firstDayOfWeek) % DAYS_IN_WEEK]);
                        }))),
                    React.createElement("tbody", null, weeks.map(function (week, weekIndex) {
                        return React.createElement("tr", { key: weekIndex }, week.map(function (day, dayIndex) {
                            return React.createElement("td", { role: 'presentation', key: day.key },
                                React.createElement("div", { className: Utilities_1.css('ms-DatePicker-day', styles.day, (_a = {},
                                        _a['ms-DatePicker-day--infocus ' + styles.dayIsFocused] = day.isInMonth,
                                        _a['ms-DatePicker-day--outfocus ' + styles.dayIsUnfocused] = !day.isInMonth,
                                        _a['ms-DatePicker-day--today ' + styles.dayIsToday] = day.isToday,
                                        _a['ms-DatePicker-day--highlighted ' + styles.dayIsHighlighted] = day.isSelected,
                                        _a)), role: 'gridcell', onClick: day.onSelected, onKeyDown: function (ev) {
                                        return _this._navigateMonthEdge(ev, day.originalDate, weekIndex, dayIndex);
                                    }, "aria-selected": day.isSelected, "aria-label": day.originalDate.toLocaleDateString ? day.originalDate.toLocaleDateString() : day.originalDate.getDate(), id: DateMath_1.compareDates(navigatedDate, day.originalDate) ? activeDescendantId : null, "data-is-focusable": true, ref: DateMath_1.compareDates(navigatedDate, day.originalDate) ? 'navigatedDay' : null, key: DateMath_1.compareDates(navigatedDate, day.originalDate) ? 'navigatedDay' : null }, day.date));
                            var _a;
                        }));
                    }))))));
    };
    CalendarDay.prototype.focus = function () {
        if (this.refs.navigatedDay) {
            this.refs.navigatedDay.tabIndex = 0;
            this.refs.navigatedDay.focus();
        }
    };
    CalendarDay.prototype._navigateMonthEdge = function (ev, date, weekIndex, dayIndex) {
        if (weekIndex === 0 && ev.which === Utilities_1.KeyCodes.up) {
            this.props.onNavigateDate(DateMath_1.addWeeks(date, -1), true);
            ev.preventDefault();
        }
        else if (weekIndex === (this.state.weeks.length - 1) && ev.which === Utilities_1.KeyCodes.down) {
            this.props.onNavigateDate(DateMath_1.addWeeks(date, 1), true);
            ev.preventDefault();
        }
        else if (dayIndex === 0 && ev.which === Utilities_1.getRTLSafeKeyCode(Utilities_1.KeyCodes.left)) {
            this.props.onNavigateDate(DateMath_1.addDays(date, -1), true);
            ev.preventDefault();
        }
        else if (dayIndex === (DAYS_IN_WEEK - 1) && ev.which === Utilities_1.getRTLSafeKeyCode(Utilities_1.KeyCodes.right)) {
            this.props.onNavigateDate(DateMath_1.addDays(date, 1), true);
            ev.preventDefault();
        }
    };
    CalendarDay.prototype._onKeyDown = function (callback, ev) {
        if (ev.which === Utilities_1.KeyCodes.enter || ev.which === Utilities_1.KeyCodes.space) {
            callback();
        }
    };
    CalendarDay.prototype._onSelectDate = function (selectedDate) {
        var _a = this.props, onSelectDate = _a.onSelectDate, dateRangeType = _a.dateRangeType, firstDayOfWeek = _a.firstDayOfWeek, navigatedDate = _a.navigatedDate, autoNavigateOnSelection = _a.autoNavigateOnSelection;
        var dateRange = DateMath_1.getDateRangeArray(selectedDate, dateRangeType, firstDayOfWeek);
        if (onSelectDate != null) {
            onSelectDate(selectedDate, dateRange);
        }
        // Navigate to next or previous month if needed
        if (autoNavigateOnSelection && selectedDate.getMonth() !== navigatedDate.getMonth()) {
            var compareResult = DateMath_1.compareDatePart(selectedDate, navigatedDate);
            if (compareResult < 0) {
                this._onSelectPrevMonth();
            }
            else if (compareResult > 0) {
                this._onSelectNextMonth();
            }
        }
    };
    CalendarDay.prototype._onSelectNextMonth = function () {
        this.props.onNavigateDate(DateMath_1.addMonths(this.props.navigatedDate, 1), false);
    };
    CalendarDay.prototype._onSelectPrevMonth = function () {
        this.props.onNavigateDate(DateMath_1.addMonths(this.props.navigatedDate, -1), false);
    };
    CalendarDay.prototype._onPrevMonthKeyDown = function (ev) {
        if (ev.which === Utilities_1.KeyCodes.tab && ev.shiftKey) {
            if (this.props.onDismiss) {
                ev.preventDefault();
                ev.stopPropagation();
                this.props.onDismiss();
            }
        }
        else {
            this._onKeyDown(this._onSelectPrevMonth, ev);
        }
    };
    CalendarDay.prototype._getWeeks = function (navigatedDate, selectedDate, todayDate) {
        var _a = this.props, firstDayOfWeek = _a.firstDayOfWeek, dateRangeType = _a.dateRangeType;
        var date = new Date(navigatedDate.getFullYear(), navigatedDate.getMonth(), 1);
        var today = todayDate || new Date();
        var weeks = [];
        var week;
        // Cycle the date backwards to get to the first day of the week.
        while (date.getDay() !== firstDayOfWeek) {
            date.setDate(date.getDate() - 1);
        }
        // a flag to indicate whether all days of the week are in the month
        var isAllDaysOfWeekOutOfMonth = false;
        var selectedDates = DateMath_1.getDateRangeArray(selectedDate, dateRangeType, firstDayOfWeek);
        for (var weekIndex = 0; !isAllDaysOfWeekOutOfMonth; weekIndex++) {
            week = [];
            isAllDaysOfWeekOutOfMonth = true;
            for (var dayIndex = 0; dayIndex < DAYS_IN_WEEK; dayIndex++) {
                var originalDate = new Date(date.toString());
                var dayInfo = {
                    key: date.toString(),
                    date: date.getDate(),
                    originalDate: originalDate,
                    isInMonth: date.getMonth() === navigatedDate.getMonth(),
                    isToday: DateMath_1.compareDates(today, date),
                    isSelected: DateMath_1.isInDateRangeArray(date, selectedDates),
                    onSelected: this._onSelectDate.bind(this, originalDate)
                };
                week.push(dayInfo);
                if (dayInfo.isInMonth) {
                    isAllDaysOfWeekOutOfMonth = false;
                }
                date.setDate(date.getDate() + 1);
            }
            if (!isAllDaysOfWeekOutOfMonth) {
                weeks.push(week);
            }
        }
        return weeks;
    };
    return CalendarDay;
}(Utilities_1.BaseComponent));
__decorate([
    Utilities_1.autobind
], CalendarDay.prototype, "_onPrevMonthKeyDown", null);
exports.CalendarDay = CalendarDay;

//# sourceMappingURL=CalendarDay.js.map
