"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        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 extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = __importDefault(require("react"));
var prop_types_1 = __importDefault(require("prop-types"));
var react_bootstrap_1 = require("react-bootstrap");
var classnames_1 = __importDefault(require("classnames"));
var Icon_1 = require("../../Icon");
var lodash_1 = __importDefault(require("lodash"));
var datePickerHelpers_1 = require("./datePickerHelpers");
var FormControl_1 = require("../FormControl");
var react_outside_click_handler_1 = __importDefault(require("react-outside-click-handler"));
var constants_1 = require("../../../../utils/constants");
var utils_1 = require("../../../../utils");
var functions_1 = require("../../../utils/functions");
var index_en_US_1 = __importDefault(require("../../../../lang/common/index-en_US"));
var toFnWithDate = function (str) { return function (_a) {
    var date = _a.date;
    return utils_1.translate(str, { date: date });
}; };
var instanceCounter = 0;
var WAIT_TIME_OUT_WHEN_BLUR = 150;
var DatePickerBase = /** @class */ (function (_super) {
    __extends(DatePickerBase, _super);
    function DatePickerBase(props, ctx) {
        var _this = _super.call(this, props, ctx) || this;
        _this.calendarContainer = null;
        _this.onKeyDown = lodash_1.default.throttle(function (event) {
            switch (event.key) {
                case constants_1.KeyNames.ArrowDown:
                    _this.onInputKeyDownArrowDown();
                    break;
                case constants_1.KeyNames.Escape:
                case constants_1.KeyNames.Tab:
                    _this.closeDayPicker();
                    break;
                default:
                    break;
            }
        });
        _this.onCalendarKeyUp = lodash_1.default.throttle(function (event) {
            if (event.key === constants_1.KeyNames.Escape) {
                _this.closeDayPicker();
                _this.focusToInput();
            }
        });
        /** prevent dayPicker being closed after react-dates trigger blur on monthChange, yearChange */
        _this.isPreventCloseDayPickerOnBlur = false;
        _this.onInputKeyDownArrowDown = function () {
            _this.showDayPicker();
            _this.focusOnDateCell();
        };
        _this.focusOnDateCell = function () {
            return _this.setStatePromise({ isDayPickerFocused: false }).then(function () {
                return _this.setStatePromise({ isDayPickerFocused: true });
            });
        };
        _this.blurDateCell = function () {
            return _this.setStatePromise({ isDayPickerFocused: false });
        };
        _this.setStatePromise = function (state) {
            return new Promise(function (resolve) {
                _this.setState(state, resolve);
            });
        };
        _this.showDayPicker = function () {
            if (!_this.state.isDayPickerVisible) {
                _this.setState({
                    isDayPickerVisible: true,
                    isDayPickerFocused: false
                });
            }
        };
        _this.handleFocusInput = function () {
            var isInputFocusedFromOutside = _this.state.isInputFocusedFromOutside;
            if (isInputFocusedFromOutside) {
                _this.showDayPicker();
            }
        };
        _this.handleToggleDayPickerDisplay = function (e) {
            if (!lodash_1.default.isEmpty(e)) {
                e.stopPropagation();
            }
            var isDayPickerVisible = _this.state.isDayPickerVisible;
            if (isDayPickerVisible) {
                _this.closeDayPicker();
            }
            else {
                _this.showDayPicker();
            }
        };
        _this.isFocusedInsideDayPickerContainer = function () { return datePickerHelpers_1.isElementFocused(_this.calendarContainer); };
        _this.focusToInput = function () { return _this.focus(); };
        _this.handleBlurDatePickerControl = function () {
            functions_1.wait(WAIT_TIME_OUT_WHEN_BLUR).then(function () {
                if (!_this.isPreventCloseDayPickerOnBlur && !_this.isFocusedInsideDayPickerContainer()) {
                    _this.toggleIsInputFocusedFromOutside(true);
                    _this.closeDayPicker();
                }
            });
        };
        _this.toggleIsInputFocusedFromOutside = function (isInputFocusedFromOutside) {
            return _this.setStatePromise({ isInputFocusedFromOutside: isInputFocusedFromOutside });
        };
        _this.handleMouseDownPreventCloseDayPicker = function () {
            _this.isPreventCloseDayPickerOnBlur = true;
        };
        _this.handleCloseDayPickerOnBlur = function () {
            _this.isPreventCloseDayPickerOnBlur = false;
        };
        _this.setContainerRef = function (el) { return (_this.calendarContainer = el); };
        _this.handleOutsideClick = function () {
            _this.toggleIsInputFocusedFromOutside(true);
            _this.closeDayPicker();
        };
        /** @abstract */
        _this.getDisplayValue = function () { return null; };
        /** @abstract */
        _this.handleMouseUpDayPickerContainer = function () { };
        _this.handlePreventDefault = function (e) { return e.preventDefault(); };
        _this.state = {
            isDayPickerFocused: false,
            isDayPickerVisible: false,
            isPreventDayPickerClosed: false,
            isInputFocusedFromOutside: true
        };
        _this.instanceId = instanceCounter++;
        return _this;
    }
    DatePickerBase.prototype.componentDidMount = function () {
        var _this = this;
        this.setState({ isInputFocusedFromOutside: true });
        this.calendarContainer.addEventListener('keydown', function (event) {
            if (_this.state.isDayPickerVisible && event.key === constants_1.KeyNames.Escape) {
                event.stopPropagation();
            }
        });
    };
    DatePickerBase.prototype.closeDayPicker = function () {
        return this.setStatePromise({
            isDayPickerVisible: false,
            isDayPickerFocused: false
        });
    };
    /** @abstract */
    DatePickerBase.prototype.getDatePickerContainerClassName = function () {
        return '';
    };
    /** @abstract */
    DatePickerBase.prototype.renderDatePicker = function () {
        return null;
    };
    /** @abstract */
    DatePickerBase.prototype.getPhrases = function () {
        var _a = this.props.dayPickerPhrase, calendarLabel = _a.calendarLabel, closeDatePicker = _a.closeDatePicker, focusStartDate = _a.focusStartDate, clearDate = _a.clearDate, clearDates = _a.clearDates, jumpToPrevMonth = _a.jumpToPrevMonth, jumpToNextMonth = _a.jumpToNextMonth, keyboardShortcuts = _a.keyboardShortcuts, showKeyboardShortcutsPanel = _a.showKeyboardShortcutsPanel, hideKeyboardShortcutsPanel = _a.hideKeyboardShortcutsPanel, openThisPanel = _a.openThisPanel, enterKey = _a.enterKey, leftArrowRightArrow = _a.leftArrowRightArrow, upArrowDownArrow = _a.upArrowDownArrow, pageUpPageDown = _a.pageUpPageDown, homeEnd = _a.homeEnd, escape = _a.escape, questionMark = _a.questionMark, selectFocusedDate = _a.selectFocusedDate, moveFocusByOneDay = _a.moveFocusByOneDay, moveFocusByOneWeek = _a.moveFocusByOneWeek, moveFocusByOneMonth = _a.moveFocusByOneMonth, moveFocustoStartAndEndOfWeek = _a.moveFocustoStartAndEndOfWeek, returnFocusToInput = _a.returnFocusToInput, keyboardNavigationInstructions = _a.keyboardNavigationInstructions, chooseAvailableDate = _a.chooseAvailableDate, chooseAvailableStartDate = _a.chooseAvailableStartDate, chooseAvailableEndDate = _a.chooseAvailableEndDate, dateIsUnavailable = _a.dateIsUnavailable, dateIsSelected = _a.dateIsSelected;
        var phrases = {
            calendarLabel: calendarLabel,
            closeDatePicker: closeDatePicker,
            focusStartDate: focusStartDate,
            clearDate: clearDate,
            clearDates: clearDates,
            jumpToPrevMonth: jumpToPrevMonth,
            jumpToNextMonth: jumpToNextMonth,
            keyboardShortcuts: keyboardShortcuts,
            showKeyboardShortcutsPanel: showKeyboardShortcutsPanel,
            hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel,
            openThisPanel: openThisPanel,
            enterKey: enterKey,
            leftArrowRightArrow: leftArrowRightArrow,
            upArrowDownArrow: upArrowDownArrow,
            pageUpPageDown: pageUpPageDown,
            homeEnd: homeEnd,
            escape: escape,
            questionMark: questionMark,
            selectFocusedDate: selectFocusedDate,
            moveFocusByOneDay: moveFocusByOneDay,
            moveFocusByOneWeek: moveFocusByOneWeek,
            moveFocusByOneMonth: moveFocusByOneMonth,
            moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek,
            returnFocusToInput: returnFocusToInput,
            keyboardNavigationInstructions: keyboardNavigationInstructions,
            chooseAvailableDate: toFnWithDate(chooseAvailableDate),
            chooseAvailableStartDate: toFnWithDate(chooseAvailableStartDate),
            chooseAvailableEndDate: toFnWithDate(chooseAvailableEndDate),
            dateIsUnavailable: toFnWithDate(dateIsUnavailable),
            dateIsSelected: toFnWithDate(dateIsSelected)
        };
        lodash_1.default.forEach(phrases, function (value, key) {
            if (value === undefined) {
                phrases[key] = DatePickerBase.defaultProps[key];
            }
        });
        return phrases;
    };
    DatePickerBase.prototype.render = function () {
        var _a = this.props, testAutomationId = _a.testAutomationId, disabled = _a.disabled, inputProps = _a.inputProps, dayPickerPhrase = _a.dayPickerPhrase, ariaLabel = _a.ariaLabel;
        var keyboardNavigationInstructions = dayPickerPhrase.keyboardNavigationInstructions;
        var ariaDescribeId = "date-picker-input-describe-message-" + this.instanceId;
        return (react_1.default.createElement(react_outside_click_handler_1.default, { onOutsideClick: this.handleOutsideClick },
            react_1.default.createElement("div", { ref: this.setContainerRef, "data-test-automation-id": testAutomationId, className: classnames_1.default('rc-datepicker', { 'rc-datepicker-disabled': disabled }), onMouseDown: this.handleMouseDownPreventCloseDayPicker, onKeyDown: this.handleCloseDayPickerOnBlur, onKeyUp: this.handleCloseDayPickerOnBlur, onBlur: this.handleBlurDatePickerControl },
                react_1.default.createElement(Icon_1.Icon, { name: "calendar", onClick: this.handleToggleDayPickerDisplay }),
                react_1.default.createElement(react_bootstrap_1.FormControl, __assign({ onKeyDown: this.onKeyDown, onFocus: this.handleFocusInput, type: "text", ref: "input", value: this.getDisplayValue(), onChange: this.handlePreventDefault, "aria-describedby": ariaDescribeId, "aria-label": ariaLabel }, inputProps)),
                react_1.default.createElement("p", { className: "sr-only", id: ariaDescribeId }, keyboardNavigationInstructions),
                react_1.default.createElement("div", { "data-test-automation-id": "datePickerContainer", className: "rc-datepicker-container " + this.getDatePickerContainerClassName(), onKeyUp: this.onCalendarKeyUp, onMouseUp: this.handleMouseUpDayPickerContainer }, this.renderDatePicker()))));
    };
    DatePickerBase.propTypes = __assign({}, FormControl_1.FormControl.propTypes, { inputProps: prop_types_1.default.object, ariaLabel: prop_types_1.default.string, disabled: prop_types_1.default.bool, testAutomationId: prop_types_1.default.string, dayPickerPhrase: prop_types_1.default.object });
    DatePickerBase.defaultProps = __assign({}, FormControl_1.FormControl.defaultProps, { ariaLabel: '', dayPickerPhrase: {
            get calendarLabel() {
                return index_en_US_1.default.DATEPICKER_PHRASE_CALENDAR_LABEL;
            },
            get closeDatePicker() {
                return index_en_US_1.default.DATEPICKER_PHRASE_CLOSE_DATE_PICKER;
            },
            get focusStartDate() {
                return index_en_US_1.default.DATEPICKER_PHRASE_FOCUS_START_DATE;
            },
            get clearDate() {
                return index_en_US_1.default.DATEPICKER_PHRASE_CLEAR_DATE;
            },
            get clearDates() {
                return index_en_US_1.default.DATEPICKER_PHRASE_CLEAR_DATES;
            },
            get jumpToPrevMonth() {
                return index_en_US_1.default.DATEPICKER_PHRASE_JUMP_TO_PREV_MONTH;
            },
            get jumpToNextMonth() {
                return index_en_US_1.default.DATEPICKER_PHRASE_JUMP_TO_NEXT_MONTH;
            },
            get keyboardShortcuts() {
                return index_en_US_1.default.DATEPICKER_PHRASE_KEYBOARD_SHORTCUTS;
            },
            get showKeyboardShortcutsPanel() {
                return index_en_US_1.default.DATEPICKER_PHRASE_SHOW_KEYBOARD_SHORTCUTS_PANEL;
            },
            get hideKeyboardShortcutsPanel() {
                return index_en_US_1.default.DATEPICKER_PHRASE_HIDE_KEYBOARD_SHORTCUTS_PANEL;
            },
            get openThisPanel() {
                return index_en_US_1.default.DATEPICKER_PHRASE_OPEN_THIS_PANEL;
            },
            get enterKey() {
                return index_en_US_1.default.DATEPICKER_PHRASE_ENTER_KEY;
            },
            get leftArrowRightArrow() {
                return index_en_US_1.default.DATEPICKER_PHRASE_LEFT_ARROW_RIGHT_ARROW;
            },
            get upArrowDownArrow() {
                return index_en_US_1.default.DATEPICKER_PHRASE_UP_ARROW_DOWN_ARROW;
            },
            get pageUpPageDown() {
                return index_en_US_1.default.DATEPICKER_PHRASE_PAGE_UP_PAGE_DOWN;
            },
            get homeEnd() {
                return index_en_US_1.default.DATEPICKER_PHRASE_HOME_END;
            },
            get escape() {
                return index_en_US_1.default.DATEPICKER_PHRASE_ESCAPE;
            },
            get questionMark() {
                return index_en_US_1.default.DATEPICKER_PHRASE_QUESTION_MARK;
            },
            get selectFocusedDate() {
                return index_en_US_1.default.DATEPICKER_PHRASE_SELECT_FOCUSED_DATE;
            },
            get moveFocusByOneDay() {
                return index_en_US_1.default.DATEPICKER_PHRASE_MOVE_FOCUS_BY_ONE_DAY;
            },
            get moveFocusByOneWeek() {
                return index_en_US_1.default.DATEPICKER_PHRASE_MOVE_FOCUS_BY_ONE_WEEK;
            },
            get moveFocusByOneMonth() {
                return index_en_US_1.default.DATEPICKER_PHRASE_MOVE_FOCUS_BY_ONE_MONTH;
            },
            get moveFocustoStartAndEndOfWeek() {
                return index_en_US_1.default.DATEPICKER_PHRASE_MOVE_FOCUSTO_START_AND_END_OF_WEEK;
            },
            get returnFocusToInput() {
                return index_en_US_1.default.DATEPICKER_PHRASE_RETURN_FOCUS_TO_INPUT;
            },
            get keyboardNavigationInstructions() {
                return index_en_US_1.default.DATEPICKER_PHRASE_KEYBOARD_NAVIGATION_INSTRUCTIONS;
            },
            get chooseAvailableDate() {
                return index_en_US_1.default.DATEPICKER_PHRASE_CHOOSE_AVAILABLE_DATE;
            },
            get chooseAvailableStartDate() {
                return index_en_US_1.default.DATEPICKER_PHRASE_CHOOSE_AVAILABLE_START_DATE;
            },
            get chooseAvailableEndDate() {
                return index_en_US_1.default.DATEPICKER_PHRASE_CHOOSE_AVAILABLE_ENDDATE;
            },
            get dateIsUnavailable() {
                return index_en_US_1.default.DATEPICKER_PHRASE_DATE_IS_UNAVAILABLE;
            },
            get dateIsSelected() {
                return index_en_US_1.default.DATEPICKER_PHRASE_DATE_IS_SELECTED;
            }
        } });
    return DatePickerBase;
}(FormControl_1.FormControl));
exports.DatePickerBase = DatePickerBase;
//# sourceMappingURL=DatePickerBase.js.map