import "core-js/modules/es.symbol";
import "core-js/modules/es.symbol.description";
import "core-js/modules/es.symbol.iterator";
import "core-js/modules/es.array.concat";
import "core-js/modules/es.array.index-of";
import "core-js/modules/es.array.iterator";
import "core-js/modules/es.array.slice";
import "core-js/modules/es.array.splice";
import "core-js/modules/es.function.name";
import "core-js/modules/es.object.keys";
import "core-js/modules/es.object.to-string";
import "core-js/modules/es.regexp.to-string";
import "core-js/modules/es.string.iterator";
import "core-js/modules/web.dom-collections.iterator";

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

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; }

import { arrayEach } from '../../helpers/array';
import { objectEach } from '../../helpers/object';
import { warn } from '../../helpers/console';
import { getMixedMonthObject, getMixedMonthName, parseDate, DEC_LENGTH, WEEK_LENGTH } from './utils';
/**
 * This class handles the date-related calculations for the GanttChart plugin.
 *
 * @plugin GanttChart
 */

var DateCalculator =
/*#__PURE__*/
function () {
  function DateCalculator(_ref) {
    var year = _ref.year,
        _ref$allowSplitWeeks = _ref.allowSplitWeeks,
        allowSplitWeeks = _ref$allowSplitWeeks === void 0 ? true : _ref$allowSplitWeeks,
        _ref$hideDaysBeforeFu = _ref.hideDaysBeforeFullWeeks,
        hideDaysBeforeFullWeeks = _ref$hideDaysBeforeFu === void 0 ? false : _ref$hideDaysBeforeFu,
        _ref$hideDaysAfterFul = _ref.hideDaysAfterFullWeeks,
        hideDaysAfterFullWeeks = _ref$hideDaysAfterFul === void 0 ? false : _ref$hideDaysAfterFul;

    _classCallCheck(this, DateCalculator);

    /**
     * Year to base calculations on.
     *
     * @type {Number}
     */
    this.year = year;
    /**
     * First day of the week.
     *
     * @type {String}
     */

    this.firstWeekDay = 'monday';
    /**
     * The current `allowSplitWeeks` option state.
     */

    this.allowSplitWeeks = allowSplitWeeks;
    /**
     * The current `hideDaysBeforeFullWeeks` option state.
     */

    this.hideDaysBeforeFullWeeks = hideDaysBeforeFullWeeks;
    /**
     * The current `hideDaysAfterFullWeeks` option state.
     */

    this.hideDaysAfterFullWeeks = hideDaysAfterFullWeeks;
    /**
     * Number of week sections (full weeks + incomplete week blocks in months).
     *
     * @type {Number}
     */

    this.weekSectionCount = 0;
    /**
     * Cache of lists of months and their week/day related information.
     * It's categorized by year, so month information for a certain year is stored under `this.monthListCache[year]`.
     *
     * @type {Object}
     */

    this.monthListCache = {};
    /**
     * Object containing references to the year days and their corresponding columns.
     *
     * @type {Object}
     */

    this.daysInColumns = {};
    this.calculateWeekStructure();
  }
  /**
   * Set the year as a base for calculations.
   *
   * @param {Number} year
   */


  _createClass(DateCalculator, [{
    key: "setYear",
    value: function setYear(year) {
      this.year = year;
      this.monthListCache[year] = this.calculateMonthData(year);
      this.calculateWeekStructure(year);
    }
    /**
     * Set the first week day.
     *
     * @param {String} day Day of the week. Available options: 'monday' or 'sunday'.
     */

  }, {
    key: "setFirstWeekDay",
    value: function setFirstWeekDay(day) {
      var lowercaseDay = day.toLowerCase();

      if (lowercaseDay !== 'monday' && lowercaseDay !== 'sunday') {
        warn('First day of the week must be set to either Monday or Sunday');
      }

      this.firstWeekDay = lowercaseDay;
      this.calculateWeekStructure();
    }
    /**
     * Count week sections (full weeks + incomplete weeks in the months).
     *
     * @returns {Number} Week section count.
     */

  }, {
    key: "countWeekSections",
    value: function countWeekSections() {
      return this.weekSectionCount;
    }
    /**
     * Get the first week day.
     *
     * @returns {String}
     */

  }, {
    key: "getFirstWeekDay",
    value: function getFirstWeekDay() {
      return this.firstWeekDay;
    }
    /**
     * Get the currently applied year.
     *
     * @returns {Number}
     */

  }, {
    key: "getYear",
    value: function getYear() {
      return this.year;
    }
    /**
     * Get month list along with the month information.
     *
     * @param {Number} [year] Year for the calculation.
     * @returns {Array}
     */

  }, {
    key: "getMonthList",
    value: function getMonthList() {
      var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.year;

      if (!this.monthListCache[year]) {
        this.monthListCache[year] = this.calculateMonthData(year);
      }

      return this.monthListCache[year];
    }
    /**
     * Get month lists for all years declared in the range bars.
     *
     * @returns {Object}
     */

  }, {
    key: "getFullMonthList",
    value: function getFullMonthList() {
      return this.monthListCache;
    }
    /**
     * Convert a date to a column number.
     *
     * @param {String|Date} date
     * @returns {Number|Boolean}
     */

  }, {
    key: "dateToColumn",
    value: function dateToColumn(date) {
      var convertedDate = parseDate(date);

      if (!convertedDate) {
        return false;
      }

      var month = convertedDate.getMonth();
      var day = convertedDate.getDate() - 1;
      var year = convertedDate.getFullYear();
      return this.getWeekColumn(day, month, year);
    }
    /**
     * Get the column index for the provided day and month indexes.
     *
     * @private
     * @param {Number} dayIndex The index of the day.
     * @param {Number} monthIndex The index of the month.
     * @param {Number} [year] Year for the calculation.
     * @returns {Number} Returns the column index.
     */

  }, {
    key: "getWeekColumn",
    value: function getWeekColumn(dayIndex, monthIndex) {
      var year = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getYear();
      var resultColumn = null;
      var monthCacheArray = this.getMonthCacheArray(monthIndex, year);
      arrayEach(monthCacheArray, function (monthCache) {
        objectEach(monthCache, function (column, index) {
          if (column.indexOf(dayIndex + 1) > -1) {
            resultColumn = parseInt(index, 10);
            return false;
          }
        });

        if (resultColumn) {
          return false;
        }
      });
      return resultColumn;
    }
    /**
     * Get the cached day array for the provided month.
     *
     * @private
     * @param {Number} monthIndex Index of the Month.
     * @param {Number} [year] Year for the calculation.
     * @returns {Array}
     */

  }, {
    key: "getMonthCacheArray",
    value: function getMonthCacheArray(monthIndex) {
      var _this = this;

      var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
      var monthList = this.getMonthList(year);
      var resultArray = [];

      if (this.allowSplitWeeks) {
        resultArray.push(this.daysInColumns[year][monthIndex]);
      } else {
        var fullMonthCount = -1;
        objectEach(this.daysInColumns[year], function (month, i) {
          var monthObject = monthList[i];

          if (Object.keys(month).length > 1) {
            fullMonthCount += 1;
          }

          if (fullMonthCount === monthIndex) {
            if (monthObject.daysBeforeFullWeeks > 0) {
              resultArray.push(_this.daysInColumns[year][parseInt(i, 10) - 1]);
            }

            resultArray.push(month);

            if (monthObject.daysAfterFullWeeks > 0) {
              resultArray.push(_this.daysInColumns[year][parseInt(i, 10) + 1]);
            }

            return false;
          }
        });
      }

      return resultArray;
    }
    /**
     * Convert a column index to a certain date.
     *
     * @param {Number} column Column index.
     * @param {Number} [year] Year to be used.
     * @returns {Object} Object in a form of {start: startDate, end: endDate}
     */

  }, {
    key: "columnToDate",
    value: function columnToDate(column) {
      var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
      var month = null;
      objectEach(this.daysInColumns[year], function (monthCache, index) {
        if (monthCache[column]) {
          month = index;
          return false;
        }
      });
      var monthSection = this.daysInColumns[year][month][column];

      if (monthSection.length === 1) {
        var resultingDate = new Date(year, month, monthSection[0]);
        return {
          start: resultingDate,
          end: resultingDate
        };
      }

      return {
        start: new Date(year, month, monthSection[0]),
        end: new Date(year, month, monthSection[monthSection.length - 1])
      };
    }
    /**
     * Check if the provided date is a starting or an ending day of a week.
     *
     * @private
     * @param {Date|String} date
     * @returns {Array|Boolean} Returns null, if an invalid date was provided or an array of results ( [1,0] => is on the beginning of the week, [0,1] => is on the end of the week).
     */

  }, {
    key: "isOnTheEdgeOfWeek",
    value: function isOnTheEdgeOfWeek(date) {
      var _this2 = this;

      var convertedDate = parseDate(date);

      if (!convertedDate) {
        return null;
      }

      var month = convertedDate.getMonth();
      var day = convertedDate.getDate() - 1;
      var year = convertedDate.getFullYear();
      var monthCacheArray = this.getMonthCacheArray(month, year);
      var isOnTheEdgeOfWeek = false;
      arrayEach(monthCacheArray, function (monthCache) {
        objectEach(monthCache, function (column) {
          if (!_this2.allowSplitWeeks && column.length !== 7) {
            if (day === 0 || day === new Date(convertedDate.getYear(), convertedDate.getMonth() + 1, 0).getDate() - 1) {
              return true;
            }
          }

          var indexOfDay = column.indexOf(day + 1);

          if (indexOfDay === 0) {
            isOnTheEdgeOfWeek = [1, 0];
            return false;
          } else if (indexOfDay === column.length - 1) {
            isOnTheEdgeOfWeek = [0, 1];
            return false;
          }
        }); // break the iteration

        if (isOnTheEdgeOfWeek) {
          return false;
        }
      });
      return isOnTheEdgeOfWeek;
    }
    /**
     * Generate headers for the year structure.
     *
     * @private
     * @param {String} type Granulation type ('months'/'weeks'/'days')
     * @param {Function|null} weekHeaderGenerator Function generating the looks of the week headers.
     * @param {Number} [year=this.year] The year for the calculation.
     * @returns {Array} The header array
     */

  }, {
    key: "generateHeaderSet",
    value: function generateHeaderSet(type, weekHeaderGenerator) {
      var _this3 = this;

      var year = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.year;
      var monthList = this.getMonthList(year);
      var headers = [];
      objectEach(monthList, function (month, index) {
        var areDaysBeforeFullWeeks = month.daysBeforeFullWeeks > 0 ? 1 : 0;
        var areDaysAfterFullWeeks = month.daysAfterFullWeeks > 0 ? 1 : 0;
        var areDaysBeforeFullWeeksVisible = _this3.hideDaysBeforeFullWeeks ? 0 : areDaysBeforeFullWeeks;
        var areDaysAfterFullWeeksVisible = _this3.hideDaysAfterFullWeeks ? 0 : areDaysAfterFullWeeks;
        var headerCount = month.fullWeeks + (_this3.allowSplitWeeks ? areDaysBeforeFullWeeksVisible + areDaysAfterFullWeeksVisible : 0);
        var monthNumber = parseInt(index, 10);
        var headerLabel = '';

        if (type === 'months') {
          headers.push({
            label: month.name,
            colspan: headerCount
          });
        } else if (type === 'weeks') {
          for (var i = 0; i < headerCount; i++) {
            var start = null;
            var end = null; // Mixed month's only column

            if (!_this3.allowSplitWeeks && month.fullWeeks === 1) {
              var _this3$getWeekColumnR = _this3.getWeekColumnRange({
                monthObject: month,
                monthNumber: monthNumber,
                headerIndex: i,
                headerCount: headerCount,
                areDaysBeforeFullWeeksVisible: areDaysBeforeFullWeeksVisible,
                areDaysAfterFullWeeksVisible: areDaysAfterFullWeeksVisible,
                mixedMonth: true,
                year: year
              });

              var _this3$getWeekColumnR2 = _slicedToArray(_this3$getWeekColumnR, 2);

              start = _this3$getWeekColumnR2[0];
              end = _this3$getWeekColumnR2[1];
            } else {
              var _this3$getWeekColumnR3 = _this3.getWeekColumnRange({
                monthObject: month,
                monthNumber: monthNumber,
                headerIndex: i,
                areDaysBeforeFullWeeksVisible: areDaysBeforeFullWeeksVisible,
                areDaysAfterFullWeeksVisible: areDaysAfterFullWeeksVisible,
                headerCount: headerCount,
                year: year
              });

              var _this3$getWeekColumnR4 = _slicedToArray(_this3$getWeekColumnR3, 2);

              start = _this3$getWeekColumnR4[0];
              end = _this3$getWeekColumnR4[1];
            }

            if (start === end) {
              headerLabel = "".concat(start);
            } else {
              headerLabel = "".concat(start, " -  ").concat(end);
            }

            headers.push(weekHeaderGenerator ? weekHeaderGenerator.call(_this3, start, end) : headerLabel);

            _this3.addDaysToCache(monthNumber, headers.length - 1, start, end, year);
          }
        }
      });
      return headers;
    }
    /**
     * Get the week column range.
     *
     * @private
     * @param {Object} options The options object.
     * @param {Object} options.monthObject The month object.
     * @param {Number} options.monthNumber Index of the month.
     * @param {Number} options.headerIndex Index of the header.
     * @param {Boolean} options.areDaysBeforeFullWeeksVisible `true` if the days before full weeks are to be visible.
     * @param {Boolean} options.areDaysAfterFullWeeksVisible `true` if the days after full weeks are to be visible.
     * @param {Number} options.headerCount Number of headers to be generated for the provided month.
     * @param {Boolean} [options.mixedMonth=false] `true` if the header is the single header of a mixed month.
     * @param {Number} [year] Year for the calculation.
     * @returns {Array}
     */

  }, {
    key: "getWeekColumnRange",
    value: function getWeekColumnRange(_ref2) {
      var monthObject = _ref2.monthObject,
          monthNumber = _ref2.monthNumber,
          headerIndex = _ref2.headerIndex,
          headerCount = _ref2.headerCount,
          areDaysBeforeFullWeeksVisible = _ref2.areDaysBeforeFullWeeksVisible,
          areDaysAfterFullWeeksVisible = _ref2.areDaysAfterFullWeeksVisible,
          _ref2$mixedMonth = _ref2.mixedMonth,
          mixedMonth = _ref2$mixedMonth === void 0 ? false : _ref2$mixedMonth,
          _ref2$year = _ref2.year,
          year = _ref2$year === void 0 ? this.year : _ref2$year;
      var monthList = this.getMonthList(year);
      var allowSplitWeeks = this.allowSplitWeeks;
      var start = null;
      var end = null;

      if (mixedMonth) {
        if (monthNumber === 0) {
          end = monthList[monthNumber + 1].daysBeforeFullWeeks;
          start = DEC_LENGTH - (WEEK_LENGTH - end) + 1;
        } else if (monthNumber === monthList.length - 1) {
          end = WEEK_LENGTH - monthList[monthNumber - 1].daysAfterFullWeeks;
          start = monthList[monthNumber - 1].days - monthList[monthNumber - 1].daysAfterFullWeeks + 1;
        } else {
          end = monthList[monthNumber + 1].daysBeforeFullWeeks;
          start = monthList[monthNumber - 1].days - (WEEK_LENGTH - end) + 1;
        }
      } else if (allowSplitWeeks && areDaysBeforeFullWeeksVisible && headerIndex === 0) {
        start = headerIndex + 1;
        end = monthObject.daysBeforeFullWeeks;
      } else if (allowSplitWeeks && areDaysAfterFullWeeksVisible && headerIndex === headerCount - 1) {
        start = monthObject.days - monthObject.daysAfterFullWeeks + 1;
        end = monthObject.days;
      } else {
        start = null;

        if (allowSplitWeeks) {
          start = monthObject.daysBeforeFullWeeks + (headerIndex - areDaysBeforeFullWeeksVisible) * WEEK_LENGTH + 1;
        } else {
          start = monthObject.daysBeforeFullWeeks + headerIndex * WEEK_LENGTH + 1;
        }

        end = start + WEEK_LENGTH - 1;
      }

      return [start, end];
    }
    /**
     * Add days to the column/day cache.
     *
     * @private
     * @param {Number} monthNumber Index of the month.
     * @param {Number} columnNumber Index of the column.
     * @param {Number} start First day in the column.
     * @param {Number} end Last day in the column.
     * @param {Number} [year] Year to process.
     */

  }, {
    key: "addDaysToCache",
    value: function addDaysToCache(monthNumber, columnNumber, start, end) {
      var year = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : this.getYear();

      if (!this.daysInColumns[year]) {
        this.daysInColumns[year] = {};
      }

      if (!this.daysInColumns[year][monthNumber]) {
        this.daysInColumns[year][monthNumber] = {};
      }

      if (!this.daysInColumns[year][monthNumber][columnNumber]) {
        this.daysInColumns[year][monthNumber][columnNumber] = [];
      }

      if (start <= end) {
        for (var dayIndex = start; dayIndex <= end; dayIndex++) {
          this.daysInColumns[year][monthNumber][columnNumber].push(dayIndex);
        }
      } else {
        var previousMonthDaysCount = monthNumber - 1 >= 0 ? this.countMonthDays(monthNumber) : 31;

        for (var _dayIndex = start; _dayIndex <= previousMonthDaysCount; _dayIndex++) {
          this.daysInColumns[year][monthNumber][columnNumber].push(_dayIndex);
        }

        for (var _dayIndex2 = 1; _dayIndex2 <= end; _dayIndex2++) {
          this.daysInColumns[year][monthNumber][columnNumber].push(_dayIndex2);
        }
      }
    }
    /**
     * Check if the provided dates can be used in a range bar.
     *
     * @param {Date|String} startDate Range start date.
     * @param {Date|String} endDate Range end date.
     * @returns {Boolean}
     */

  }, {
    key: "isValidRangeBarData",
    value: function isValidRangeBarData(startDate, endDate) {
      var startDateParsed = parseDate(startDate);
      var endDateParsed = parseDate(endDate);
      return startDateParsed && endDateParsed && startDateParsed.getTime() <= endDateParsed.getTime();
    }
    /**
     * Calculate the month/day related information.
     *
     * @param {Number} [year] Year to be used.
     * @returns {Array}
     */

  }, {
    key: "calculateMonthData",
    value: function calculateMonthData() {
      var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.year;
      return [{
        name: 'January',
        days: 31
      }, {
        name: 'February',
        days: new Date(year, 2, 0).getDate()
      }, {
        name: 'March',
        days: 31
      }, {
        name: 'April',
        days: 30
      }, {
        name: 'May',
        days: 31
      }, {
        name: 'June',
        days: 30
      }, {
        name: 'July',
        days: 31
      }, {
        name: 'August',
        days: 31
      }, {
        name: 'September',
        days: 30
      }, {
        name: 'October',
        days: 31
      }, {
        name: 'November',
        days: 30
      }, {
        name: 'December',
        days: 31
      }].slice(0);
    }
    /**
     * Count the number of months.
     *
     * @param {Number} [year] Year to be used.
     * @returns {Number}
     */

  }, {
    key: "countMonths",
    value: function countMonths() {
      var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getYear();
      return this.monthListCache[year].length;
    }
    /**
     * Count days in a month.
     *
     * @param {Number} month Month index, where January = 1, February = 2, etc.
     * @param {Number} [year] Year to be used.
     * @returns {Number}
     */

  }, {
    key: "countMonthDays",
    value: function countMonthDays(month) {
      var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
      return this.monthListCache[year][month - 1].days;
    }
    /**
     * Count full weeks in a month.
     *
     * @param {Number} month Month index, where January = 1, February = 2, etc.
     * @param {Number} [year] Year to be used.
     * @returns {Number}
     */

  }, {
    key: "countMonthFullWeeks",
    value: function countMonthFullWeeks(month) {
      var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
      return this.monthListCache[year][month - 1].fullWeeks;
    }
    /**
     * Calculate week structure within defined months.
     *
     * @private
     * @param {Number} [year] Year for the calculation.
     */

  }, {
    key: "calculateWeekStructure",
    value: function calculateWeekStructure() {
      var _this4 = this;

      var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getYear();
      this.monthListCache[year] = this.calculateMonthData(year);
      var firstWeekDay = this.getFirstWeekDay();
      var monthList = this.getMonthList(year);
      var mixedMonthToAdd = [];
      var daysBeforeFullWeeksRatio = this.hideDaysBeforeFullWeeks ? 0 : 1;
      var daysAfterFullWeeksRatio = this.hideDaysAfterFullWeeks ? 0 : 1;
      var weekOffset = 0;
      var weekSectionCount = 0;

      if (firstWeekDay === 'monday') {
        weekOffset = 1;
      }

      arrayEach(monthList, function (currentMonth, monthIndex) {
        var firstMonthDay = new Date(year, monthIndex, 1).getDay();
        var mixedMonthsAdded = 0;
        currentMonth.daysBeforeFullWeeks = (7 - firstMonthDay + weekOffset) % 7;

        if (!_this4.allowSplitWeeks && currentMonth.daysBeforeFullWeeks) {
          mixedMonthToAdd.push(getMixedMonthObject(getMixedMonthName(monthIndex, monthList), monthIndex));
          mixedMonthsAdded += 1;
        }

        currentMonth.fullWeeks = Math.floor((currentMonth.days - currentMonth.daysBeforeFullWeeks) / 7);
        currentMonth.daysAfterFullWeeks = currentMonth.days - currentMonth.daysBeforeFullWeeks - 7 * currentMonth.fullWeeks;

        if (!_this4.allowSplitWeeks) {
          if (monthIndex === monthList.length - 1 && currentMonth.daysAfterFullWeeks) {
            mixedMonthToAdd.push(getMixedMonthObject(getMixedMonthName(monthIndex, monthList), null));
            mixedMonthsAdded += 1;
          }

          weekSectionCount += currentMonth.fullWeeks + mixedMonthsAdded;
        } else {
          var numberOfPartialWeeksBefore = daysBeforeFullWeeksRatio * (currentMonth.daysBeforeFullWeeks ? 1 : 0);
          var numberOfPartialWeeksAfter = daysAfterFullWeeksRatio * (currentMonth.daysAfterFullWeeks ? 1 : 0);
          weekSectionCount += currentMonth.fullWeeks + numberOfPartialWeeksBefore + numberOfPartialWeeksAfter;
        }
      });
      arrayEach(mixedMonthToAdd, function (monthObject, monthIndex) {
        var index = monthObject.index;
        delete monthObject.index;

        _this4.addMixedMonth(index === null ? index : monthIndex + index, monthObject, year);
      });

      if (year === this.getYear()) {
        this.weekSectionCount = weekSectionCount;
      }
    }
    /**
     * Add a mixed (e.g. 'Jan/Feb') month to the month list.
     *
     * @private
     * @param {Number} index Index for the month.
     * @param {Object} monthObject The month object.
     * @param {Number} [year] Year for the calculation.
     */

  }, {
    key: "addMixedMonth",
    value: function addMixedMonth(index, monthObject, year) {
      if (index === null) {
        this.monthListCache[year].push(monthObject);
      } else {
        this.monthListCache[year].splice(index, 0, monthObject);
      }
    }
  }]);

  return DateCalculator;
}();

export default DateCalculator;