"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var vdom_1 = require("@dojo/framework/core/vdom");
var icache_1 = require("@dojo/framework/core/middleware/icache");
var i18n_1 = require("@dojo/framework/core/middleware/i18n");
var focus_1 = require("@dojo/framework/core/middleware/focus");
var date_utils_1 = require("./date-utils");
var util_1 = require("../common/util");
var theme_1 = require("../middleware/theme");
var calendar_1 = require("../calendar");
var text_input_1 = require("../text-input");
var icon_1 = require("../icon");
var trigger_popup_1 = require("../trigger-popup");
var textInputCss = require("../theme/default/text-input.m.css");
var css = require("../theme/default/date-input.m.css");
var DateInput_1 = require("./nls/DateInput");
var icache = icache_1.createICacheMiddleware();
var factory = vdom_1.create({ theme: theme_1.default, icache: icache, i18n: i18n_1.i18n, focus: focus_1.focus })
    .properties()
    .children();
exports.default = factory(function DateInput(_a) {
    var properties = _a.properties, children = _a.children, _b = _a.middleware, theme = _b.theme, icache = _b.icache, i18n = _b.i18n, focus = _b.focus;
    var _c = properties(), initialValue = _c.initialValue, name = _c.name, onValue = _c.onValue, onValidate = _c.onValidate, _d = _c.dateParser, dateParser = _d === void 0 ? date_utils_1.parseDate : _d, _e = _c.dateFormatter, dateFormatter = _e === void 0 ? date_utils_1.formatDate : _e, controlledValue = _c.value, _f = _c.disabled, disabled = _f === void 0 ? false : _f, _g = _c.readOnly, readOnly = _g === void 0 ? false : _g, minInput = _c.min, maxInput = _c.max, themeProp = _c.theme, variant = _c.variant, classes = _c.classes, required = _c.required, kind = _c.kind;
    var messages = i18n.localize(DateInput_1.default).messages;
    var themedCss = theme.classes(css);
    var max = (Boolean(maxInput) && dateParser(maxInput)) || undefined;
    var min = (Boolean(minInput) && dateParser(minInput)) || undefined;
    if (initialValue !== undefined &&
        controlledValue === undefined &&
        icache.get('initialValue') !== initialValue) {
        var parsed = initialValue && dateParser(initialValue);
        if (parsed) {
            icache.set('inputValue', dateFormatter(parsed));
        }
        icache.set('initialValue', initialValue);
        icache.delete('callOnValue');
    }
    if (controlledValue !== undefined && icache.get('lastValue') !== controlledValue) {
        var parsed = controlledValue && dateParser(controlledValue);
        if (parsed) {
            icache.set('inputValue', dateFormatter(parsed));
            icache.set('value', parsed);
        }
        icache.set('lastValue', controlledValue);
    }
    var shouldFocus = focus.shouldFocus();
    var focusNode = icache.getOrSet('focusNode', 'input');
    var _h = tslib_1.__read(children(), 1), labelChild = _h[0];
    var label = util_1.isRenderResult(labelChild) ? labelChild : labelChild.label;
    function callOnValue() {
        var testValue = controlledValue === undefined ? icache.get('inputValue') : icache.get('nextValue');
        var isValid;
        var validationMessages = [];
        // if min & max create an impossible range, no need to validate anything else
        if (min && max && min > max) {
            validationMessages.push(messages.invalidProps);
            isValid = false;
        }
        else {
            var newDate = dateParser(testValue);
            if (newDate !== undefined) {
                if (min && newDate < min) {
                    validationMessages.push(messages.tooEarly);
                }
                else if (max && newDate > max) {
                    validationMessages.push(messages.tooLate);
                }
                else {
                    if (controlledValue === undefined) {
                        icache.set('value', newDate);
                        icache.set('inputValue', dateFormatter(newDate));
                    }
                    if (onValue) {
                        onValue(date_utils_1.formatDateISO(newDate));
                    }
                }
            }
            else if (testValue) {
                validationMessages.push(messages.invalidDate);
            }
            else {
                onValue && onValue('');
            }
            isValid = validationMessages.length === 0;
        }
        if (testValue === '' && icache.get('dirty') && required) {
            validationMessages = [messages.requiredDate];
            isValid = false;
        }
        var validationMessage = validationMessages.join('; ');
        onValidate && onValidate(isValid, validationMessage);
        icache.set('validationMessage', validationMessage);
    }
    icache.getOrSet('callOnValue', function () { return callOnValue(); });
    return (vdom_1.tsx("div", { classes: [theme.variant(), themedCss.root] },
        vdom_1.tsx("input", { type: "hidden", name: name, value: date_utils_1.formatDateISO(icache.get('value')), "aria-hidden": "true", required: required }),
        vdom_1.tsx(trigger_popup_1.default, { key: "popup", theme: themeProp, classes: classes, variant: variant }, {
            trigger: function (toggleOpen) {
                function openCalendar() {
                    if (!disabled && !readOnly) {
                        icache.set('focusNode', 'calendar');
                        focus.focus();
                        toggleOpen();
                    }
                }
                return (vdom_1.tsx("div", { classes: themedCss.input },
                    vdom_1.tsx(text_input_1.default, { key: "input", disabled: disabled, required: required, readOnly: readOnly, focus: function () { return shouldFocus && focusNode === 'input'; }, theme: theme.compose(textInputCss, css, 'input'), type: "text", initialValue: icache.get('inputValue'), onBlur: function () {
                            if (icache.get('dirty')) {
                                callOnValue();
                            }
                        }, onValue: function (v) {
                            if (v === void 0) { v = ''; }
                            icache.set('dirty', true);
                            icache.set(controlledValue === undefined
                                ? 'inputValue'
                                : 'nextValue', v);
                        }, valid: icache.get('validationMessage')
                            ? {
                                valid: false,
                                message: icache.get('validationMessage')
                            }
                            : undefined, onFocus: function () {
                            icache.set('dirty', true);
                        }, onKeyDown: function (key) {
                            if (key === util_1.Keys.Down ||
                                key === util_1.Keys.Space ||
                                key === util_1.Keys.Enter) {
                                if (key === util_1.Keys.Enter && icache.get('dirty')) {
                                    callOnValue();
                                }
                                openCalendar();
                            }
                        }, classes: classes, variant: variant, kind: kind }, {
                        label: label,
                        trailing: (vdom_1.tsx("button", { key: "dateIcon", disabled: disabled, onclick: function (e) {
                                e.stopPropagation();
                                openCalendar();
                            }, classes: themedCss.toggleCalendarButton, type: "button" },
                            vdom_1.tsx(icon_1.default, { type: "dateIcon" })))
                    })));
            },
            content: function (onClose) {
                function closeCalendar() {
                    icache.set('focusNode', 'input');
                    focus.focus();
                    onClose();
                }
                return (vdom_1.tsx("div", { classes: themedCss.popup },
                    vdom_1.tsx(calendar_1.default, { key: "calendar", focus: function () { return shouldFocus && focusNode === 'calendar'; }, maxDate: max, minDate: min, initialValue: icache.get('value') || date_utils_1.parseDate(date_utils_1.formatDateISO(new Date())), onValue: function (date) {
                            icache.set(controlledValue === undefined
                                ? 'inputValue'
                                : 'nextValue', dateFormatter(date));
                            callOnValue();
                            closeCalendar();
                        }, theme: themeProp, classes: classes, variant: variant })));
            }
        })));
});

/*# sourceMappingURL=index.js.map*/