text: /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  import { DOWN_ARROW, END, ENTER, HOME, LEFT_ARROW, PAGE_DOWN, PAGE_UP, RIGHT_ARROW, UP_ARROW, } from '@angular/cdk/keycodes';
  import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Optional, Output, ViewChild, ViewEncapsulation, } from '@angular/core';
  import { DateAdapter } from '@angular/material/core';
  import { Directionality } from '@angular/cdk/bidi';
  import { MatCalendarBody, MatCalendarCell } from './calendar-body';
  import { createMissingDateImplError } from './datepicker-errors';
  export var /** @type {?} */ yearsPerPage = 24;
  export var /** @type {?} */ yearsPerRow = 4;
  /**
   * An internal component used to display a year selector in the datepicker.
   * \@docs-private
   * @template D
   */
  var MatMultiYearView = /** @class */ (function () {
      function MatMultiYearView(_changeDetectorRef, _dateAdapter, _dir) {
          this._changeDetectorRef = _changeDetectorRef;
          this._dateAdapter = _dateAdapter;
          this._dir = _dir;
          /**
           * Emits when a new year is selected.
           */
          this.selectedChange = new EventEmitter();
          /**
           * Emits the selected year. This doesn't imply a change on the selected date
           */
          this.yearSelected = new EventEmitter();
          /**
           * Emits when any date is activated.
           */
          this.activeDateChange = new EventEmitter();
          if (!this._dateAdapter) {
              throw createMissingDateImplError('DateAdapter');
          }
          this._activeDate = this._dateAdapter.today();
      }
      Object.defineProperty(MatMultiYearView.prototype, "activeDate", {
          get: /**
           * The date to display in this multi-year view (everything other than the year is ignored).
           * @return {?}
           */
          function () { return this._activeDate; },
          set: /**
           * @param {?} value
           * @return {?}
           */
          function (value) {
              var /** @type {?} */ oldActiveDate = this._activeDate;
              var /** @type {?} */ validDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today();
              this._activeDate = this._dateAdapter.clampDate(validDate, this.minDate, this.maxDate);
              if (Math.floor(this._dateAdapter.getYear(oldActiveDate) / yearsPerPage) !=
                  Math.floor(this._dateAdapter.getYear(this._activeDate) / yearsPerPage)) {
                  this._init();
              }
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatMultiYearView.prototype, "selected", {
          get: /**
           * The currently selected date.
           * @return {?}
           */
          function () { return this._selected; },
          set: /**
           * @param {?} value
           * @return {?}
           */
          function (value) {
              this._selected = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
              this._selectedYear = this._selected && this._dateAdapter.getYear(this._selected);
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatMultiYearView.prototype, "minDate", {
          get: /**
           * The minimum selectable date.
           * @return {?}
           */
          function () { return this._minDate; },
          set: /**
           * @param {?} value
           * @return {?}
           */
          function (value) {
              this._minDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatMultiYearView.prototype, "maxDate", {
          get: /**
           * The maximum selectable date.
           * @return {?}
           */
          function () { return this._maxDate; },
          set: /**
           * @param {?} value
           * @return {?}
           */
          function (value) {
              this._maxDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      MatMultiYearView.prototype.ngAfterContentInit = /**
       * @return {?}
       */
      function () {
          this._init();
      };
      /** Initializes this multi-year view. */
      /**
       * Initializes this multi-year view.
       * @return {?}
       */
      MatMultiYearView.prototype._init = /**
       * Initializes this multi-year view.
       * @return {?}
       */
      function () {
          var _this = this;
          this._todayYear = this._dateAdapter.getYear(this._dateAdapter.today());
          var /** @type {?} */ activeYear = this._dateAdapter.getYear(this._activeDate);
          var /** @type {?} */ activeOffset = activeYear % yearsPerPage;
          this._years = [];
          for (var /** @type {?} */ i = 0, /** @type {?} */ row = []; i < yearsPerPage; i++) {
              row.push(activeYear - activeOffset + i);
              if (row.length == yearsPerRow) {
                  this._years.push(row.map(function (year) { return _this._createCellForYear(year); }));
                  row = [];
              }
          }
          this._changeDetectorRef.markForCheck();
      };
      /** Handles when a new year is selected. */
      /**
       * Handles when a new year is selected.
       * @param {?} year
       * @return {?}
       */
      MatMultiYearView.prototype._yearSelected = /**
       * Handles when a new year is selected.
       * @param {?} year
       * @return {?}
       */
      function (year) {
          this.yearSelected.emit(this._dateAdapter.createDate(year, 0, 1));
          var /** @type {?} */ month = this._dateAdapter.getMonth(this.activeDate);
          var /** @type {?} */ daysInMonth = this._dateAdapter.getNumDaysInMonth(this._dateAdapter.createDate(year, month, 1));
          this.selectedChange.emit(this._dateAdapter.createDate(year, month, Math.min(this._dateAdapter.getDate(this.activeDate), daysInMonth)));
      };
      /** Handles keydown events on the calendar body when calendar is in multi-year view. */
      /**
       * Handles keydown events on the calendar body when calendar is in multi-year view.
       * @param {?} event
       * @return {?}
       */
      MatMultiYearView.prototype._handleCalendarBodyKeydown = /**
       * Handles keydown events on the calendar body when calendar is in multi-year view.
       * @param {?} event
       * @return {?}
       */
      function (event) {
          // TODO(mmalerba): We currently allow keyboard navigation to disabled dates, but just prevent
          // disabled ones from being selected. This may not be ideal, we should look into whether
          // navigation should skip over disabled dates, and if so, how to implement that efficiently.
          var /** @type {?} */ oldActiveDate = this._activeDate;
          var /** @type {?} */ isRtl = this._isRtl();
          switch (event.keyCode) {
              case LEFT_ARROW:
                  this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, isRtl ? 1 : -1);
                  break;
              case RIGHT_ARROW:
                  this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, isRtl ? -1 : 1);
                  break;
              case UP_ARROW:
                  this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, -yearsPerRow);
                  break;
              case DOWN_ARROW:
                  this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, yearsPerRow);
                  break;
              case HOME:
                  this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, -this._dateAdapter.getYear(this._activeDate) % yearsPerPage);
                  break;
              case END:
                  this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, yearsPerPage - this._dateAdapter.getYear(this._activeDate) % yearsPerPage - 1);
                  break;
              case PAGE_UP:
                  this.activeDate =
                      this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? -yearsPerPage * 10 : -yearsPerPage);
                  break;
              case PAGE_DOWN:
                  this.activeDate =
                      this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? yearsPerPage * 10 : yearsPerPage);
                  break;
              case ENTER:
                  this._yearSelected(this._dateAdapter.getYear(this._activeDate));
                  break;
              default:
                  // Don't prevent default or focus active cell on keys that we don't explicitly handle.
                  return;
          }
          if (this._dateAdapter.compareDate(oldActiveDate, this.activeDate)) {
              this.activeDateChange.emit(this.activeDate);
          }
          this._focusActiveCell();
          // Prevent unexpected default actions such as form submission.
          event.preventDefault();
      };
      /**
       * @return {?}
       */
      MatMultiYearView.prototype._getActiveCell = /**
       * @return {?}
       */
      function () {
          return this._dateAdapter.getYear(this.activeDate) % yearsPerPage;
      };
      /** Focuses the active cell after the microtask queue is empty. */
      /**
       * Focuses the active cell after the microtask queue is empty.
       * @return {?}
       */
      MatMultiYearView.prototype._focusActiveCell = /**
       * Focuses the active cell after the microtask queue is empty.
       * @return {?}
       */
      function () {
          this._matCalendarBody._focusActiveCell();
      };
      /**
       * Creates an MatCalendarCell for the given year.
       * @param {?} year
       * @return {?}
       */
      MatMultiYearView.prototype._createCellForYear = /**
       * Creates an MatCalendarCell for the given year.
       * @param {?} year
       * @return {?}
       */
      function (year) {
          var /** @type {?} */ yearName = this._dateAdapter.getYearName(this._dateAdapter.createDate(year, 0, 1));
          return new MatCalendarCell(year, yearName, yearName, this._shouldEnableYear(year));
      };
      /**
       * Whether the given year is enabled.
       * @param {?} year
       * @return {?}
       */
      MatMultiYearView.prototype._shouldEnableYear = /**
       * Whether the given year is enabled.
       * @param {?} year
       * @return {?}
       */
      function (year) {
          // disable if the year is greater than maxDate lower than minDate
          if (year === undefined || year === null ||
              (this.maxDate && year > this._dateAdapter.getYear(this.maxDate)) ||
              (this.minDate && year < this._dateAdapter.getYear(this.minDate))) {
              return false;
          }
          // enable if it reaches here and there's no filter defined
          if (!this.dateFilter) {
              return true;
          }
          var /** @type {?} */ firstOfYear = this._dateAdapter.createDate(year, 0, 1);
          // If any date in the year is enabled count the year as enabled.
          for (var /** @type {?} */ date = firstOfYear; this._dateAdapter.getYear(date) == year; date = this._dateAdapter.addCalendarDays(date, 1)) {
              if (this.dateFilter(date)) {
                  return true;
              }
          }
          return false;
      };
      /**
       * @param {?} obj The object to check.
       * @return {?} The given object if it is both a date instance and valid, otherwise null.
       */
      MatMultiYearView.prototype._getValidDateOrNull = /**
       * @param {?} obj The object to check.
       * @return {?} The given object if it is both a date instance and valid, otherwise null.
       */
      function (obj) {
          return (this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj)) ? obj : null;
      };
      /**
       * Determines whether the user has the RTL layout direction.
       * @return {?}
       */
      MatMultiYearView.prototype._isRtl = /**
       * Determines whether the user has the RTL layout direction.
       * @return {?}
       */
      function () {
          return this._dir && this._dir.value === 'rtl';
      };
      MatMultiYearView.decorators = [
          { type: Component, args: [{selector: 'mat-multi-year-view',
                      template: "<table class=\"mat-calendar-table\"><thead class=\"mat-calendar-table-header\"><tr><th class=\"mat-calendar-table-header-divider\" colspan=\"4\"></th></tr></thead><tbody mat-calendar-body allowDisabledSelection=\"true\" [rows]=\"_years\" [todayValue]=\"_todayYear\" [selectedValue]=\"_selectedYear\" [numCols]=\"4\" [cellAspectRatio]=\"4 / 7\" [activeCell]=\"_getActiveCell()\" (selectedValueChange)=\"_yearSelected($event)\" (keydown)=\"_handleCalendarBodyKeydown($event)\"></tbody></table>",
                      exportAs: 'matMultiYearView',
                      encapsulation: ViewEncapsulation.None,
                      changeDetection: ChangeDetectionStrategy.OnPush
                  },] },
      ];
      /** @nocollapse */
      MatMultiYearView.ctorParameters = function () { return [
          { type: ChangeDetectorRef, },
          { type: DateAdapter, decorators: [{ type: Optional },] },
          { type: Directionality, decorators: [{ type: Optional },] },
      ]; };
      MatMultiYearView.propDecorators = {
          "activeDate": [{ type: Input },],
          "selected": [{ type: Input },],
          "minDate": [{ type: Input },],
          "maxDate": [{ type: Input },],
          "dateFilter": [{ type: Input },],
          "selectedChange": [{ type: Output },],
          "yearSelected": [{ type: Output },],
          "activeDateChange": [{ type: Output },],
          "_matCalendarBody": [{ type: ViewChild, args: [MatCalendarBody,] },],
      };
      return MatMultiYearView;
  }());
  export { MatMultiYearView };
  function MatMultiYearView_tsickle_Closure_declarations() {
      /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
      MatMultiYearView.decorators;
      /**
       * @nocollapse
       * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
       */
      MatMultiYearView.ctorParameters;
      /** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */
      MatMultiYearView.propDecorators;
      /** @type {?} */
      MatMultiYearView.prototype._activeDate;
      /** @type {?} */
      MatMultiYearView.prototype._selected;
      /** @type {?} */
      MatMultiYearView.prototype._minDate;
      /** @type {?} */
      MatMultiYearView.prototype._maxDate;
      /**
       * A function used to filter which dates are selectable.
       * @type {?}
       */
      MatMultiYearView.prototype.dateFilter;
      /**
       * Emits when a new year is selected.
       * @type {?}
       */
      MatMultiYearView.prototype.selectedChange;
      /**
       * Emits the selected year. This doesn't imply a change on the selected date
       * @type {?}
       */
      MatMultiYearView.prototype.yearSelected;
      /**
       * Emits when any date is activated.
       * @type {?}
       */
      MatMultiYearView.prototype.activeDateChange;
      /**
       * The body of calendar table
       * @type {?}
       */
      MatMultiYearView.prototype._matCalendarBody;
      /**
       * Grid of calendar cells representing the currently displayed years.
       * @type {?}
       */
      MatMultiYearView.prototype._years;
      /**
       * The year that today falls on.
       * @type {?}
       */
      MatMultiYearView.prototype._todayYear;
      /**
       * The year of the selected date. Null if the selected date is null.
       * @type {?}
       */
      MatMultiYearView.prototype._selectedYear;
      /** @type {?} */
      MatMultiYearView.prototype._changeDetectorRef;
      /** @type {?} */
      MatMultiYearView.prototype._dateAdapter;
      /** @type {?} */
      MatMultiYearView.prototype._dir;
  }
  //# sourceMappingURL=multi-year-view.js.map