"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.DateTimeDecorator = exports.default = void 0;

var _hoc = _interopRequireDefault(require("@enact/core/hoc"));

var _i18n = _interopRequireDefault(require("@enact/i18n"));

var _I18nDecorator = require("@enact/i18n/I18nDecorator");

var _DateFactory = _interopRequireDefault(require("@enact/i18n/ilib/lib/DateFactory"));

var _Changeable = _interopRequireDefault(require("@enact/ui/Changeable"));

var _propTypes = _interopRequireDefault(require("prop-types"));

var _react = _interopRequireDefault(require("react"));

var _ExpandableItem = require("../../ExpandableItem");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

/**
 * {@link moonstone/internal/DateTimeDecorator.DateTimeDecorator} provides common behavior for
 * {@link moonstone/DatePicker.DatePicker} and {@link moonstone/TimePicker.TimePicker}.
 *
 * @class DateTimeDecorator
 * @memberof moonstone/internal/DateTimeDecorator
 * @mixes ui/Toggleable.Toggleable
 * @mixes ui/RadioDecorator.RadioDecorator
 * @mixes ui/Changeable.Changeable
 * @hoc
 * @private
 */
var DateTimeDecorator = (0, _hoc.default)(function (config, Wrapped) {
  var _class, _temp, _initialiseProps;

  var customProps = config.customProps,
      defaultOrder = config.defaultOrder,
      handlers = config.handlers,
      i18n = config.i18n;
  var Decorator = (_temp = _class =
  /*#__PURE__*/
  function (_React$Component) {
    _inherits(Decorator, _React$Component);

    function Decorator(props) {
      var _this;

      _classCallCheck(this, Decorator);

      _this = _possibleConstructorReturn(this, (Decorator.__proto__ || Object.getPrototypeOf(Decorator)).call(this, props));

      _initialiseProps.call(_assertThisInitialized(_this));

      _this.initI18n();

      var initialValue = _this.toTime(props.value);

      var value = props.open && !initialValue ? Date.now() : initialValue;
      _this.state = {
        initialValue: initialValue,
        value: value
      };
      _this.handlers = {};

      if (handlers) {
        Object.keys(handlers).forEach(function (name) {
          _this.handlers[name] = _this.handlePickerChange.bind(_assertThisInitialized(_this), handlers[name]);
        });
      }

      return _this;
    }

    _createClass(Decorator, [{
      key: "componentWillReceiveProps",
      value: function componentWillReceiveProps(nextProps) {
        var newValue = this.toTime(nextProps.value);

        if (nextProps.open && !this.props.open) {
          var value = newValue || Date.now(); // if we're opening, store the current value as the initial value for cancellation

          this.setState({
            initialValue: newValue,
            pickerValue: null,
            value: value
          }); // if no value was provided, we need to emit the onChange event for the generated value

          if (!newValue) {
            this.emitChange(this.toIDate(value));
          }
        } else {
          this.setState({
            value: newValue
          });
        }
      }
    }, {
      key: "componentWillUpdate",
      value: function componentWillUpdate() {
        // check for a new locale when updating
        this.initI18n();
      }
    }, {
      key: "initI18n",
      value: function initI18n() {
        var locale = _i18n.default.getLocale();

        if (i18n && this.locale !== locale && (typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object') {
          this.locale = locale;
          this.i18nContext = i18n();
        }
      }
      /**
       * Converts a Date to an IDate
       *
       * @param	{Date}	time	Date object
       *
       * @returns	{IDate}			ilib Date object
       */

    }, {
      key: "toIDate",
      value: function toIDate(time) {
        if (time && this.locale) {
          return (0, _DateFactory.default)({
            unixtime: time,
            timezone: 'local'
          });
        }
      }
      /**
       * Converts a JavaScript Date to unix time
       *
       * @param	{Date}	date	A Date to convert
       *
       * @returns	{undefined}
       */

    }, {
      key: "toTime",
      value: function toTime(date) {
        return date && date.getTime();
      }
      /**
       * Updates the internal value in state
       *
       * @param	{IDate}		value	ilib Date object
       *
       * @returns {Number}			Updated internal value
       */

    }, {
      key: "render",
      value: function render() {
        var value = this.toIDate(this.state.value); // pickerValue is only set when cancelling to prevent the unexpected changing of the
        // picker values before closing.

        var pickerValue = this.state.pickerValue ? this.toIDate(this.state.pickerValue) : value;
        var label = null;
        var props = null;
        var order = defaultOrder; // Guard for isomorphic builds

        if (this.i18nContext) {
          if (value) {
            label = this.i18nContext.formatter.format(value);
          }

          props = customProps(this.i18nContext, pickerValue, this.props);
          order = this.i18nContext.order;
        }

        return _react.default.createElement(Wrapped, _extends({}, this.props, props, this.handlers, {
          label: label,
          order: order,
          value: value
        }));
      }
    }]);

    return Decorator;
  }(_react.default.Component), Object.defineProperty(_class, "displayName", {
    configurable: true,
    enumerable: true,
    writable: true,
    value: 'DateTimeDecorator'
  }), Object.defineProperty(_class, "propTypes", {
    configurable: true,
    enumerable: true,
    writable: true,
    value:
    /** @lends moonstone/internal/DateTimeDecorator.DateTimeDecorator.prototype */
    {
      /**
       * Handler for `onChange` events
       *
       * @type {Function}
       * @public
       */
      onChange: _propTypes.default.func,

      /**
       * When `true`, the date picker is expanded to select a new date.
       *
       * @type {Boolean}
       * @public
       */
      open: _propTypes.default.bool,

      /**
       * The selected date
       *
       * @type {Date}
       * @public
       */
      value: _propTypes.default.instanceOf(Date)
    }
  }), _initialiseProps = function _initialiseProps() {
    var _this2 = this;

    Object.defineProperty(this, "updateValue", {
      configurable: true,
      enumerable: true,
      writable: true,
      value: function value(_value) {
        var day = _value.day,
            month = _value.month,
            year = _value.year;

        var maxDays = _value.cal.getMonLength(month, year);

        _value.day = day <= maxDays ? day : maxDays;
        var date = (0, _DateFactory.default)(_value);
        var newValue = date.getTimeExtended();
        var changed = _this2.props.value == null || _this2.props.value !== newValue;

        _this2.setState({
          value: newValue
        });

        if (changed) {
          _this2.emitChange(date);
        }

        return newValue;
      }
    });
    Object.defineProperty(this, "emitChange", {
      configurable: true,
      enumerable: true,
      writable: true,
      value: function value(date) {
        var onChange = _this2.props.onChange;

        if (onChange) {
          onChange({
            value: date ? date.getJSDate() : null
          });
        }
      }
    });
    Object.defineProperty(this, "handlePickerChange", {
      configurable: true,
      enumerable: true,
      writable: true,
      value: function value(handler, ev) {
        var value = _this2.toIDate(_this2.state.value);

        handler(ev, value, _this2.i18nContext);

        _this2.updateValue(value);
      }
    });
    Object.defineProperty(this, "handleCancel", {
      configurable: true,
      enumerable: true,
      writable: true,
      value: function value() {
        var _this2$state = _this2.state,
            initialValue = _this2$state.initialValue,
            value = _this2$state.value;

        if (_this2.props.open) {
          // if we're cancelling, reset our state and emit an onChange with the initial value
          _this2.setState({
            value: initialValue,
            initialValue: null,
            pickerValue: value
          });

          if (initialValue !== value) {
            _this2.emitChange(_this2.toIDate(initialValue));
          }
        }
      }
    });
  }, _temp);
  return (0, _I18nDecorator.I18nContextDecorator)({
    rtlProp: 'rtl'
  }, (0, _ExpandableItem.Expandable)((0, _Changeable.default)(Decorator)));
});
exports.DateTimeDecorator = DateTimeDecorator;
var _default = DateTimeDecorator;
exports.default = _default;