define(["require", "exports", "tslib", "react", "../../utilities/dateValues/DateValues", "./CalendarDay", "./CalendarMonth", "../../utilities/dateMath/DateMath", "../../Utilities", "./Calendar.scss"], function (require, exports, tslib_1, React, DateValues_1, CalendarDay_1, CalendarMonth_1, DateMath_1, Utilities_1, stylesImport) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var styles = stylesImport;
    var leftArrow = 'Up';
    var rightArrow = 'Down';
    var closeIcon = 'CalculatorMultiply';
    var iconStrings = {
        leftNavigation: leftArrow,
        rightNavigation: rightArrow,
        closeIcon: closeIcon
    };
    var defaultWorkWeekDays = [DateValues_1.DayOfWeek.Monday, DateValues_1.DayOfWeek.Tuesday, DateValues_1.DayOfWeek.Wednesday, DateValues_1.DayOfWeek.Thursday, DateValues_1.DayOfWeek.Friday];
    var dateTimeFormatterCallbacks = {
        formatMonthDayYear: function (date, strings) {
            return strings.months[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear();
        },
        formatMonthYear: function (date, strings) { return strings.months[date.getMonth()] + ' ' + date.getFullYear(); },
        formatDay: function (date) { return date.getDate().toString(); },
        formatYear: function (date) { return date.getFullYear().toString(); }
    };
    var Calendar = /** @class */ (function (_super) {
        tslib_1.__extends(Calendar, _super);
        function Calendar(props) {
            var _this = _super.call(this, props) || this;
            _this._dayPicker = React.createRef();
            _this._monthPicker = React.createRef();
            _this._navigateDayPickerDay = function (date) {
                _this.setState({
                    navigatedDayDate: date,
                    navigatedMonthDate: date
                });
            };
            _this._navigateMonthPickerDay = function (date) {
                _this.setState({
                    navigatedMonthDate: date
                });
            };
            _this._onNavigateDayDate = function (date, focusOnNavigatedDay) {
                _this._navigateDayPickerDay(date);
                _this._focusOnUpdate = focusOnNavigatedDay;
            };
            _this._onNavigateMonthDate = function (date, focusOnNavigatedDay) {
                if (!focusOnNavigatedDay) {
                    _this._navigateMonthPickerDay(date);
                    _this._focusOnUpdate = focusOnNavigatedDay;
                    return;
                }
                var monthPickerOnly = !_this.props.showMonthPickerAsOverlay && !_this.props.isDayPickerVisible;
                if (monthPickerOnly) {
                    _this._onSelectDate(date);
                }
                _this._navigateDayPickerDay(date);
            };
            _this._onSelectDate = function (date, selectedDateRangeArray) {
                var onSelectDate = _this.props.onSelectDate;
                _this.setState({
                    selectedDate: date
                });
                if (onSelectDate) {
                    onSelectDate(date, selectedDateRangeArray);
                }
            };
            _this._onHeaderSelect = function (focus) {
                _this.setState({
                    isDayPickerVisible: !_this.state.isDayPickerVisible,
                    isMonthPickerVisible: !_this.state.isMonthPickerVisible
                });
                if (focus) {
                    _this._focusOnUpdate = true;
                }
            };
            _this._onGotoToday = function () {
                var _a = _this.props, dateRangeType = _a.dateRangeType, firstDayOfWeek = _a.firstDayOfWeek, today = _a.today, workWeekDays = _a.workWeekDays, selectDateOnClick = _a.selectDateOnClick;
                if (selectDateOnClick) {
                    // When using Defaultprops, TypeScript doesn't know that React is going to inject defaults
                    // so we use exclamation mark as a hint to the type checker (see link below)
                    // https://decembersoft.com/posts/error-ts2532-optional-react-component-props-in-typescript/
                    var dates = DateMath_1.getDateRangeArray(today, dateRangeType, firstDayOfWeek, workWeekDays);
                    _this._onSelectDate(today, dates);
                }
                _this._navigateDayPickerDay(today);
                _this._focusOnUpdate = true;
            };
            _this._onGotoTodayClick = function (ev) {
                _this._onGotoToday();
            };
            _this._onGotoTodayKeyDown = function (ev) {
                if (ev.which === Utilities_1.KeyCodes.enter) {
                    ev.preventDefault();
                    _this._onGotoToday();
                }
            };
            _this._onDatePickerPopupKeyDown = function (ev) {
                switch (ev.which) {
                    case Utilities_1.KeyCodes.enter:
                        ev.preventDefault();
                        break;
                    case Utilities_1.KeyCodes.backspace:
                        ev.preventDefault();
                        break;
                    case Utilities_1.KeyCodes.escape:
                        _this._handleEscKey(ev);
                        break;
                    default:
                        break;
                }
            };
            _this._handleEscKey = function (ev) {
                if (_this.props.onDismiss) {
                    _this.props.onDismiss();
                }
            };
            var currentDate = props.value && !isNaN(props.value.getTime()) ? props.value : props.today || new Date();
            _this.state = {
                selectedDate: currentDate,
                navigatedDayDate: currentDate,
                navigatedMonthDate: currentDate,
                /** When showMonthPickerAsOverlay is active it overrides isMonthPickerVisible/isDayPickerVisible props
                 (These props permanently set the visibility of their respective calendars). */
                isMonthPickerVisible: _this.props.showMonthPickerAsOverlay ? false : _this.props.isMonthPickerVisible,
                isDayPickerVisible: _this.props.showMonthPickerAsOverlay ? true : _this.props.isDayPickerVisible
            };
            _this._focusOnUpdate = false;
            return _this;
        }
        // tslint:disable-next-line function-name
        Calendar.prototype.UNSAFE_componentWillReceiveProps = function (nextProps) {
            var autoNavigateOnSelection = nextProps.autoNavigateOnSelection, value = nextProps.value, _a = nextProps.today, today = _a === void 0 ? new Date() : _a;
            // Make sure auto-navigation is supported for programmatic changes to selected date, i.e.,
            // if selected date is updated via props, we may need to modify the navigated date
            var overrideNavigatedDate = autoNavigateOnSelection && !DateMath_1.compareDates(value, this.props.value);
            if (overrideNavigatedDate) {
                this.setState({
                    navigatedMonthDate: value,
                    navigatedDayDate: value
                });
            }
            this.setState({
                selectedDate: value || today
            });
        };
        Calendar.prototype.componentDidUpdate = function () {
            if (this._focusOnUpdate) {
                this.focus();
                this._focusOnUpdate = false;
            }
        };
        Calendar.prototype.render = function () {
            var _a;
            var rootClass = 'ms-DatePicker';
            var _b = this.props, firstDayOfWeek = _b.firstDayOfWeek, dateRangeType = _b.dateRangeType, strings = _b.strings, showMonthPickerAsOverlay = _b.showMonthPickerAsOverlay, autoNavigateOnSelection = _b.autoNavigateOnSelection, showGoToToday = _b.showGoToToday, highlightCurrentMonth = _b.highlightCurrentMonth, highlightSelectedMonth = _b.highlightSelectedMonth, navigationIcons = _b.navigationIcons, minDate = _b.minDate, maxDate = _b.maxDate, restrictedDates = _b.restrictedDates, className = _b.className, showCloseButton = _b.showCloseButton, allFocusable = _b.allFocusable, yearPickerHidden = _b.yearPickerHidden, today = _b.today;
            var nativeProps = Utilities_1.getNativeProps(this.props, Utilities_1.divProperties, ['value']);
            var _c = this.state, selectedDate = _c.selectedDate, navigatedDayDate = _c.navigatedDayDate, navigatedMonthDate = _c.navigatedMonthDate, isMonthPickerVisible = _c.isMonthPickerVisible, isDayPickerVisible = _c.isDayPickerVisible;
            var onHeaderSelect = showMonthPickerAsOverlay ? this._onHeaderSelect : undefined;
            var monthPickerOnly = !showMonthPickerAsOverlay && !isDayPickerVisible;
            var overlayedWithButton = showMonthPickerAsOverlay && showGoToToday;
            var goTodayEnabled = showGoToToday;
            if (goTodayEnabled && navigatedDayDate && navigatedMonthDate && today) {
                goTodayEnabled =
                    navigatedDayDate.getFullYear() !== today.getFullYear() ||
                        navigatedDayDate.getMonth() !== today.getMonth() ||
                        navigatedMonthDate.getFullYear() !== today.getFullYear() ||
                        navigatedMonthDate.getMonth() !== today.getMonth();
            }
            return (React.createElement("div", { className: Utilities_1.css(rootClass, styles.root, className), role: "application" },
                React.createElement("div", tslib_1.__assign({}, nativeProps, { className: Utilities_1.css('ms-DatePicker-picker ms-DatePicker-picker--opened ms-DatePicker-picker--focused', styles.picker, styles.pickerIsOpened, styles.pickerIsFocused, isMonthPickerVisible && 'ms-DatePicker-monthPickerVisible ' + styles.monthPickerVisible, isMonthPickerVisible && isDayPickerVisible && 'ms-DatePicker-calendarsInline ' + styles.calendarsInline, monthPickerOnly && 'ms-DatePicker-monthPickerOnly ' + styles.monthPickerOnly, showMonthPickerAsOverlay && 'ms-DatePicker-monthPickerAsOverlay ' + styles.monthPickerAsOverlay) }),
                    React.createElement("div", { className: Utilities_1.css('ms-DatePicker-holder ms-slideDownIn10', styles.holder, overlayedWithButton && styles.holderWithButton), onKeyDown: this._onDatePickerPopupKeyDown },
                        React.createElement("div", { className: Utilities_1.css('ms-DatePicker-frame', styles.frame) },
                            React.createElement("div", { className: Utilities_1.css('ms-DatePicker-wrap', styles.wrap, showGoToToday && styles.goTodaySpacing) },
                                isDayPickerVisible && (React.createElement(CalendarDay_1.CalendarDay, { selectedDate: selectedDate, navigatedDate: navigatedDayDate, today: this.props.today, onSelectDate: this._onSelectDate, onNavigateDate: this._onNavigateDayDate, onDismiss: this.props.onDismiss, firstDayOfWeek: firstDayOfWeek, dateRangeType: dateRangeType, autoNavigateOnSelection: autoNavigateOnSelection, strings: strings, onHeaderSelect: onHeaderSelect, navigationIcons: navigationIcons, showWeekNumbers: this.props.showWeekNumbers, firstWeekOfYear: this.props.firstWeekOfYear, dateTimeFormatter: this.props.dateTimeFormatter, showSixWeeksByDefault: this.props.showSixWeeksByDefault, minDate: minDate, maxDate: maxDate, restrictedDates: restrictedDates, workWeekDays: this.props.workWeekDays, componentRef: this._dayPicker, showCloseButton: showCloseButton, allFocusable: allFocusable })),
                                isDayPickerVisible && isMonthPickerVisible && React.createElement("div", { className: styles.divider }),
                                isMonthPickerVisible && (React.createElement(CalendarMonth_1.CalendarMonth, { navigatedDate: navigatedMonthDate, selectedDate: navigatedDayDate, strings: strings, onNavigateDate: this._onNavigateMonthDate, today: this.props.today, highlightCurrentMonth: highlightCurrentMonth, highlightSelectedMonth: highlightSelectedMonth, onHeaderSelect: onHeaderSelect, navigationIcons: navigationIcons, dateTimeFormatter: this.props.dateTimeFormatter, minDate: minDate, maxDate: maxDate, componentRef: this._monthPicker, yearPickerHidden: yearPickerHidden || showMonthPickerAsOverlay })),
                                showGoToToday && (React.createElement("button", { role: "button", className: Utilities_1.css('ms-DatePicker-goToday js-goToday', styles.goToday, (_a = {},
                                        _a[styles.goTodayInlineMonth] = isMonthPickerVisible,
                                        _a[styles.goToTodayIsDisabled] = !goTodayEnabled,
                                        _a)), onClick: this._onGotoTodayClick, onKeyDown: this._onGotoTodayKeyDown, tabIndex: 0, disabled: !goTodayEnabled, type: "button" }, strings.goToToday))))))));
        };
        Calendar.prototype.focus = function () {
            if (this.state.isDayPickerVisible && this._dayPicker.current) {
                this._dayPicker.current.focus();
            }
            else if (this.state.isMonthPickerVisible && this._monthPicker.current) {
                this._monthPicker.current.focus();
            }
        };
        Calendar.defaultProps = {
            onSelectDate: undefined,
            onDismiss: undefined,
            isMonthPickerVisible: true,
            isDayPickerVisible: true,
            showMonthPickerAsOverlay: false,
            value: undefined,
            today: new Date(),
            firstDayOfWeek: DateValues_1.DayOfWeek.Sunday,
            dateRangeType: DateValues_1.DateRangeType.Day,
            autoNavigateOnSelection: false,
            showGoToToday: true,
            strings: null,
            highlightCurrentMonth: false,
            highlightSelectedMonth: false,
            navigationIcons: iconStrings,
            showWeekNumbers: false,
            firstWeekOfYear: DateValues_1.FirstWeekOfYear.FirstDay,
            dateTimeFormatter: dateTimeFormatterCallbacks,
            showSixWeeksByDefault: false,
            workWeekDays: defaultWorkWeekDays,
            showCloseButton: false,
            allFocusable: false
        };
        return Calendar;
    }(Utilities_1.BaseComponent));
    exports.Calendar = Calendar;
});
//# sourceMappingURL=Calendar.js.map