// #region Imports
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { HTMLElementEventEmitter } from '@breadstone/mosaik-elements';
import { Emit } from '../../../../../../events/Decorators/EmitDecorator';
import { getDateOnly } from '../../../../../../Extensions/DateExtensions';
import { Disableable } from '../../../../../Behaviors/Disableable';
import { Localeable } from '../../../../../Behaviors/Localeable';
import { Attribute } from '../../../../../Decorators/AttributeDecorator';
import { Property } from '../../../../../Decorators/PropertyDecorator';
import { RangeSelectionMode } from '../../../../../Types/RangeSelectionMode';
import { CustomElement } from '../../../../Abstracts/CustomElement';
import { CalendarElementIntl } from '../../Intl/CalendarElementIntl';
/**
 * The `CalendarViewBaseElement` element.
 *
 * @fires valueChanged {DateChangedEvent} - Fired when the value is changed.
 *                       In the years view, the `value` property is the selected year.
 *                       In the months view, the `value` property is the selected month.
 *                       In the days view, the `value` property is the selected date.
 * @fires viewChanged {CalendarViewChangedEvent} - Fired when the view is changed between years, months, and days.
 * @fires displayChanged {CalendarDisplayChangedEvent} - Fired when the display date is changed.
 *
 * @public
 * @abstract
 */
export class CalendarViewBaseElement extends Disableable(Localeable(CustomElement)) {
    // #region Fields
    _valueChanged;
    _viewChanged;
    _displayChanged;
    _displayDate;
    _displayDateStart;
    _displayDateEnd;
    _value;
    _values;
    _selection;
    _blackoutDates;
    _specialDates;
    _markerHandler;
    _intl;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._displayDate = null;
        this._displayDateStart = null;
        this._displayDateEnd = null;
        this.locale = 'en';
        this._value = undefined;
        this._values = undefined;
        this._selection = RangeSelectionMode.Single;
        this._blackoutDates = [];
        this._specialDates = [];
        this._markerHandler = () => [];
        this._intl = null;
        this._valueChanged = new HTMLElementEventEmitter(this, 'valueChanged');
        this._viewChanged = new HTMLElementEventEmitter(this, 'viewChanged');
        this._displayChanged = new HTMLElementEventEmitter(this, 'displayChanged');
    }
    // #endregion
    // #region Properties
    /**
     * Gets or sets the `displayDate` property.
     *
     * @public
     * @attr
     */
    get displayDate() {
        return this._displayDate;
    }
    set displayDate(value) {
        if (this._displayDate !== value) {
            this._displayDate = value;
            this.requestUpdate('displayDate');
        }
    }
    /**
     * Gets or sets the `displayDateStart` property.
     *
     * @public
     * @attr
     */
    get displayDateStart() {
        return this._displayDateStart;
    }
    set displayDateStart(value) {
        if (this._displayDateStart !== value) {
            this._displayDateStart = value;
            this.requestUpdate('displayDateStart');
        }
    }
    /**
     * Gets or sets the `displayDateEnd` property.
     *
     * @public
     * @attr
     */
    get displayDateEnd() {
        return this._displayDateEnd;
    }
    set displayDateEnd(value) {
        if (this._displayDateEnd !== value) {
            this._displayDateEnd = value;
            this.requestUpdate('displayDateEnd');
        }
    }
    /**
     * Gets or sets the `value` property.
     *
     * @public
     * @attr
     */
    get value() {
        return this._value;
    }
    set value(value) {
        if (this._value !== value) {
            this._value = value;
            this.requestUpdate('value');
        }
    }
    /**
     * Gets or sets the `values` property.
     *
     * @public
     * @attr
     */
    get values() {
        return this._values;
    }
    set values(value) {
        if (this._values !== value) {
            this._values = value;
            this.requestUpdate('values');
        }
    }
    /**
     * Gets or sets the `selection` property.
     *
     * @public
     * @attr
     */
    get selection() {
        return this._selection;
    }
    set selection(value) {
        if (this._selection !== value) {
            this._selection = value;
            this.requestUpdate('selection');
        }
    }
    /**
     * Gets or sets the `blackoutDates` property.
     *
     * @public
     */
    get blackoutDates() {
        return this._blackoutDates;
    }
    set blackoutDates(value) {
        if (this._blackoutDates !== value) {
            this._blackoutDates = value;
            this.requestUpdate('blackoutDates');
        }
    }
    /**
     * Gets or sets the `specialDates` property.
     *
     * @public
     */
    get specialDates() {
        return this._specialDates;
    }
    set specialDates(value) {
        if (this._specialDates !== value) {
            this._specialDates = value;
            this.requestUpdate('specialDates');
        }
    }
    /**
     * Gets or sets the `markerHandler` property.
     *
     * @public
     */
    get markerHandler() {
        return this._markerHandler;
    }
    set markerHandler(value) {
        if (this._markerHandler !== value) {
            this._markerHandler = value;
            this.requestUpdate('markerHandler');
        }
    }
    /**
     * Gets or sets the `intl` property.
     *
     * @public
     */
    get intl() {
        return this._intl;
    }
    set intl(value) {
        if (this._intl !== value) {
            this._intl = value;
            this.requestUpdate('intl');
        }
    }
    /**
     * Called when the value is changed.
     * Provides reference to `IDateChangedEventDetail` as event detail.
     *
     * @public
     * @readonly
     * @eventProperty
     */
    get valueChanged() {
        return this._valueChanged;
    }
    /**
     * Called when the view is changed between years, months, and days.
     * Provides reference to `ICalendarViewChangedEventDetail` as event detail.
     *
     * @public
     * @readonly
     * @eventProperty
     */
    get viewChanged() {
        return this._viewChanged;
    }
    /**
     * Called when the view is changed between years, months, and days.
     * Provides reference to `ICalendarDisplayChangedEventDetail` as event detail.
     *
     * @public
     * @readonly
     * @eventProperty
     */
    get displayChanged() {
        return this._displayChanged;
    }
    // #endregion
    // #region Methods
    /**
     * @protected
     * @template
     */
    isDateInRange(date) {
        return this._displayDateStart === null || this._displayDateEnd === null
            ? true
            : getDateOnly(date) >= getDateOnly(this._displayDateStart) && getDateOnly(date) <= getDateOnly(this._displayDateEnd);
    }
    /**
     * Emits the `changed` event.
     *
     * @protected
     */
    onValueChanged(args) {
        this._valueChanged.emit(args);
    }
    /**
     * Emits the `viewChanged` event.
     *
     * @protected
     */
    onViewChanged(args) {
        this._viewChanged.emit(args);
    }
    /**
     * Emits the `displayChanged` event.
     *
     * @protected
     */
    onDisplayChanged(args) {
        this._displayChanged.emit(args);
    }
}
__decorate([
    Attribute({
        type: Date,
        converter: {
            fromAttribute: (value) => value ? new Date(value) : new Date(),
            toAttribute: (value) => value ? value.toISOString() : ''
        }
    }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], CalendarViewBaseElement.prototype, "displayDate", null);
__decorate([
    Attribute({
        type: Date,
        converter: {
            fromAttribute: (value) => value ? new Date(value) : new Date(),
            toAttribute: (value) => value ? value.toISOString() : ''
        }
    }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], CalendarViewBaseElement.prototype, "displayDateStart", null);
__decorate([
    Attribute({
        type: Date,
        converter: {
            fromAttribute: (value) => value ? new Date(value) : new Date(),
            toAttribute: (value) => value ? value.toISOString() : ''
        }
    }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], CalendarViewBaseElement.prototype, "displayDateEnd", null);
__decorate([
    Attribute({
        type: Date,
        converter: {
            fromAttribute: (value) => value ? new Date(value) : undefined,
            toAttribute: (value) => value ? value.toISOString() : ''
        }
    }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], CalendarViewBaseElement.prototype, "value", null);
__decorate([
    Attribute({
        type: (Array),
        converter: {
            fromAttribute: (value) => !value
                ? undefined
                : value
                    .split(' ')
                    .map((v) => v.trim())
                    .filter((v) => v)
                    .map((v) => new Date(v)),
            toAttribute: (value) => value.map((v) => v.toISOString()).join(' ')
        }
    }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], CalendarViewBaseElement.prototype, "values", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], CalendarViewBaseElement.prototype, "selection", null);
__decorate([
    Property({ type: (Array) }),
    __metadata("design:type", Array),
    __metadata("design:paramtypes", [Array])
], CalendarViewBaseElement.prototype, "blackoutDates", null);
__decorate([
    Property({
        type: (Array),
        attribute: false
    }),
    __metadata("design:type", Array),
    __metadata("design:paramtypes", [Array])
], CalendarViewBaseElement.prototype, "specialDates", null);
__decorate([
    Property({ type: Function }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Function])
], CalendarViewBaseElement.prototype, "markerHandler", null);
__decorate([
    Property({ type: CalendarElementIntl }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], CalendarViewBaseElement.prototype, "intl", null);
__decorate([
    Emit({ eventName: 'valueChanged' }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], CalendarViewBaseElement.prototype, "valueChanged", null);
__decorate([
    Emit({ eventName: 'viewChanged' }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], CalendarViewBaseElement.prototype, "viewChanged", null);
__decorate([
    Emit({ eventName: 'displayChanged' }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], CalendarViewBaseElement.prototype, "displayChanged", null);
//# sourceMappingURL=CalendarViewBase.js.map