'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _SelectField = require('../SelectField/SelectField');

var _SelectField2 = _interopRequireDefault(_SelectField);

var _style = require('./style.scss');

var _style2 = _interopRequireDefault(_style);

var _OptClass = require('../internal/OptClass');

var _OptClass2 = _interopRequireDefault(_OptClass);

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

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

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } 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; }

/**
 * The DatePicker component.
 */

var DatePicker = function (_React$Component) {
  _inherits(DatePicker, _React$Component);

  function DatePicker(props) {
    _classCallCheck(this, DatePicker);

    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DatePicker).call(this, props));

    _this.state = {
      year: {
        min: 0,
        value: 0,
        max: 0,
        options: []
      },
      month: {
        min: 0,
        value: 0,
        max: 0,
        options: []
      },
      day: {
        min: 0,
        value: 0,
        max: 0,
        options: []
      }
    };

    _this._initDate = function (date, format) {
      var dateObj = {
        year: {
          min: 0,
          value: 0,
          max: 0,
          options: []
        },
        month: {
          min: 0,
          value: 0,
          max: 0,
          options: []
        },
        day: {
          min: 0,
          value: 0,
          max: 0,
          options: []
        },
        value: ''
      };

      var mDate = date === undefined ? (0, _moment2.default)() : (0, _moment2.default)(date, format);

      // selected date values
      dateObj.year.value = mDate.year();
      dateObj.month.value = mDate.month();
      dateObj.day.value = mDate.date();

      dateObj.value = mDate.format(format);

      // min & max values
      dateObj.year.min = _this._getMinOrMax(_this.props.min, 'year');
      dateObj.year.max = _this._getMinOrMax(_this.props.max, 'year');
      dateObj.month.min = _this._getMinOrMax(_this.props.min, 'month');
      dateObj.month.max = _this._getMinOrMax(_this.props.max, 'month');
      dateObj.day.min = _this._getMinOrMax(_this.props.min, 'day');
      dateObj.day.max = _this._getMinOrMax(_this.props.max, 'day');

      // options
      dateObj.year.options = _this._getYears(dateObj.year.min, dateObj.year.max);
      dateObj.month.options = _this._getMonths(dateObj);
      dateObj.day.options = _this._getDays(dateObj);

      _this.setState(dateObj);
    };

    _this._getMinOrMax = function (minOrMax, type) {
      var momentDate = void 0;
      var value = void 0;

      if (minOrMax[type] === 'current') {
        momentDate = (0, _moment2.default)();
      } else if (minOrMax[type].indexOf('+') !== -1) {
        momentDate = (0, _moment2.default)().add(Math.abs(minOrMax[type]), type);
      } else if (minOrMax[type].indexOf('-') !== -1) {
        momentDate = (0, _moment2.default)().subtract(Math.abs(minOrMax[type]), type);
      } else {
        value = minOrMax[type];
      }

      if (momentDate) {
        switch (type) {
          case 'year':
            value = momentDate.year();
            break;
          case 'month':
            value = momentDate.month();
            break;
          case 'day':
            value = momentDate.date();
            break;
        }
      }

      return parseInt(value);
    };

    _this._getYears = function (min, max) {
      var yearOptions = [];

      for (var i = min; i <= max; i++) {
        yearOptions.push({ value: i.toString() });
      }

      return yearOptions;
    };

    _this._getMonths = function (dateObj) {
      var monthOptions = [];
      var checkMin = dateObj.year.value === dateObj.year.min;
      var checkMax = dateObj.year.value === dateObj.year.max;

      var start = checkMin ? dateObj.month.min : 0;
      var end = checkMax ? dateObj.month.max + 1 : 12;

      for (var i = start; i < end; i++) {
        monthOptions.push({ value: i.toString(), display: (0, _moment2.default)(i + 1, 'MM').format('MMM') });
      }

      // if selected month is greater than max month, change it to max month
      if (checkMax && dateObj.month.value > dateObj.month.max) {
        dateObj.month.value = dateObj.month.max;
      }

      // if selected month is lower than min month, change it to min month
      if (checkMin && dateObj.month.value < dateObj.month.min) {
        dateObj.month.value = dateObj.month.min;
      }

      return monthOptions;
    };

    _this._getDays = function (dateObj) {
      var dayOptions = [];

      var checkMin = dateObj.year.value === dateObj.year.min && dateObj.month.value === dateObj.month.min;
      var checkMax = dateObj.year.value === dateObj.year.max && dateObj.month.value === dateObj.month.max;
      var daysInMonth = (0, _moment2.default)(dateObj.year.value + '-' + (dateObj.month.value + 1), 'YYYY-M').daysInMonth();

      var start = checkMin ? dateObj.day.min : 1;
      var end = checkMax ? dateObj.day.max : daysInMonth;

      for (var i = start; i <= end; i++) {
        dayOptions.push({ value: i.toString() });
      }

      // if selected day is greater than max day in a month, change it to max day in a month
      if (dateObj.day.value > daysInMonth) {
        dateObj.day.value = daysInMonth;
      }

      // if selected day is greater than max day, change it to max day
      if (checkMax && dateObj.day.value > dateObj.day.max) {
        dateObj.day.value = dateObj.day.max;
      }

      // if selected day is lower than min day, change it to min day
      if (checkMin && dateObj.day.value < dateObj.day.min) {
        dateObj.day.value = dateObj.day.min;
      }

      dateObj.value = _this._getValue(dateObj);

      return dayOptions;
    };

    _this._getValue = function (state) {
      return (0, _moment2.default)().year(state.year.value).month(state.month.value).date(state.day.value).format(_this.props.format);
    };

    _this.handleChangeYear = function (event) {
      var state = _this.state;
      state.year.value = parseInt(event.target.value);
      state.value = _this._getValue(state);

      state.month.options = _this._getMonths(state);
      state.day.options = _this._getDays(state);
      _this.setState({
        year: state.year,
        month: state.month,
        day: state.day,
        value: state.value
      }, function () {
        _this.callback(state.value);
      });
    };

    _this.handleChangeMonth = function (event) {
      var state = _this.state;
      state.month.value = parseInt(event.target.value);
      state.value = _this._getValue(state);
      state.day.options = _this._getDays(state);
      _this.setState({
        month: state.month,
        day: state.day,
        value: state.value
      }, function () {
        _this.callback(state.value);
      });
    };

    _this.handleChangeDay = function (event) {
      var state = _this.state;
      state.day.value = parseInt(event.target.value);
      state.value = _this._getValue(state);
      _this.setState({
        day: state.day,
        value: state.value
      }, function () {
        _this.callback(state.value);
      });
    };

    _this.callback = function (value) {
      if (typeof _this.props.changeCallback === 'function') {
        _this.props.changeCallback({
          target: {
            name: _this.props.name,
            value: value
          }
        });
      }
    };

    _this.componentWillMount = function () {
      _this._initDate(_this.props.value, _this.props.format);
    };

    _this.componentWillReceiveProps = function (nextProps) {
      if (nextProps.value !== _this.props.value) {
        _this._initDate(nextProps.value, _this.props.format);
      }
    };

    return _this;
  }

  _createClass(DatePicker, [{
    key: 'render',
    value: function render() {
      var componentClass = (0, _OptClass2.default)(_style2.default, 'datepicker-component', this.props.optClass);

      return _react2.default.createElement(
        'div',
        { className: componentClass },
        _react2.default.createElement(_SelectField2.default, {
          options: this.state.month.options,
          valueProp: 'value',
          displayProp: 'display',
          value: this.state.month.value.toString(),
          changeCallback: this.handleChangeMonth
        }),
        _react2.default.createElement(_SelectField2.default, {
          options: this.state.day.options,
          valueProp: 'value',
          displayProp: 'value',
          value: this.state.day.value.toString(),
          changeCallback: this.handleChangeDay
        }),
        _react2.default.createElement(_SelectField2.default, {
          options: this.state.year.options,
          valueProp: 'value',
          displayProp: 'value',
          value: this.state.year.value.toString(),
          changeCallback: this.handleChangeYear
        })
      );
    }
  }]);

  return DatePicker;
}(_react2.default.Component);

DatePicker.defaultProps = {
  min: { month: '-0', day: '-0', year: '-10' },
  max: { month: '+0', day: '+0', year: '+10' },
  format: 'YYYY-MM-DD'
};
DatePicker.propTypes = {
  /**
   * Max date - object with month, day, year.
   */
  max: _react2.default.PropTypes.object,
  /**
   * Min date - object with month, day, year.
   */
  min: _react2.default.PropTypes.object,
  /**
   * Date string.
   */
  value: _react2.default.PropTypes.string,
  /**
   * Date format - any valid Moment.js format string.
   */
  format: _react2.default.PropTypes.string,
  /**
   * A callback function to be called when the value changes.
   */
  changeCallback: _react2.default.PropTypes.func,
  /**
   * Optional CSS class(es) to be used for local styles (string or array of strings)
   */
  optClass: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.array, _react2.default.PropTypes.string])
};
exports.default = DatePicker;