import { h } from "@stencil/core";
export class Calendar {
    constructor() {
        /**
         * If true, display a calendar view, otherwise show yearly
         */
        this.monthMode = true;
    }
    onDateChange() {
        if (!this.date) {
            return;
        }
        this.month = this.adapter.month(this.date);
        this.year = this.adapter.year(this.date);
        this.setHeaderData();
        this.updateMonth();
    }
    componentWillLoad() {
        this.weekdays = this.adapter.weekdays();
        this.months = this.adapter.months();
    }
    setHeaderData() {
        this.displayYear = this.adapter.prepHeaderYear(this.date);
        this.displayDate = this.adapter.prepHeaderDate(this.date);
    }
    displayActiveDay({ detail }) {
        this.displayYear = detail.year.toString();
        this.displayDate = this.adapter.prepHeaderDate(this.adapter.newDateFromArray(detail.year, detail.month, detail.day));
    }
    toggleMonthMode({ detail }) {
        this.monthMode = detail;
        this.controlsEl.focus();
    }
    updateYear({ detail }) {
        // Make increments in year
        this.year = this.year + detail;
        // Update current date to be first of the current month in the newly selected year
        this.date = this.adapter.newDateFromArray(this.year, this.month, 1);
    }
    selectMonth({ detail }) {
        // Update current date to be first of the newly selected month in the current year
        this.date = this.adapter.newDateFromArray(this.year, detail, 1);
        this.month = detail;
        this.monthMode = true;
        this.controlsEl.focus();
    }
    updateMonth(event = 0) {
        const change = isNaN(event) ? event.detail : event;
        // Make increments in month/year
        this.month = this.month + change;
        if (this.month < 0) {
            this.month = 11;
            this.year--;
        }
        if (this.month > 11) {
            this.month = 0;
            this.year++;
        }
        // Establish date info for previous, current and following month
        const lastMonth = {
            date: this.getMonthInfo(-1),
            days: this.getDaysInMonth(-1)
        };
        const thisMonth = {
            date: this.getMonthInfo(),
            days: this.getDaysInMonth(),
            dayOfFirst: this.getDayOfFirst()
        };
        const nextMonth = {
            date: this.getMonthInfo(1),
            dayOfFirst: this.getDayOfFirst(1)
        };
        // Establish dates for display on calendar for current month, including padded days.
        const prefix = Array.from(this.createRange(lastMonth.days - thisMonth.dayOfFirst + 1, lastMonth.days, lastMonth.date));
        const currentMonthDays = Array.from(this.createRange(1, thisMonth.days, thisMonth.date));
        let postfix = [];
        if (nextMonth.dayOfFirst > 0) {
            postfix = Array.from(this.createRange(1, 7 - nextMonth.dayOfFirst, nextMonth.date));
        }
        this.days = [].concat(prefix, currentMonthDays, postfix);
        this.package = {
            adapter: this.adapter,
            year: this.year,
            months: this.months,
            month: this.month,
            days: this.days,
            date: this.date,
            weekdays: this.weekdays
        };
    }
    selectDay({ detail }) {
        const selection = this.adapter.newDateFromArray(detail.year, detail.month, detail.day);
        this.date = selection;
        this.anjCalendarDaySelect.emit(selection);
    }
    focusControls() {
        return new Promise(resolve => {
            window.setTimeout(() => {
                this.controlsEl.focus();
                resolve();
            }, 100);
        });
    }
    componentDidLoad() {
        this.onDateChange();
    }
    getDayOfFirst(varianceFromCurrentMonth = 0) {
        const evaluatedMonth = this.month + varianceFromCurrentMonth;
        return this.adapter.dayOfFirst(this.year, evaluatedMonth);
    }
    getDaysInMonth(varianceFromCurrentMonth = 0) {
        const evaluatedMonth = this.month + varianceFromCurrentMonth;
        return this.adapter.daysInMonth(this.year, evaluatedMonth);
    }
    getMonthInfo(varianceFromCurrentMonth = 0) {
        const evaluatedMonth = this.month + varianceFromCurrentMonth;
        return this.adapter.getMonthInfo(this.year, evaluatedMonth);
    }
    createRange(start, end, dateInfo) {
        const rangeArray = [];
        for (let i = start; i <= end; i++) {
            rangeArray.push({
                day: i,
                month: this.adapter.month(dateInfo),
                year: this.adapter.year(dateInfo)
            });
        }
        return rangeArray;
    }
    render() {
        if (!this.package) {
            return;
        }
        return [
            h("div", { class: "anj-picker-header" },
                h("p", { class: "anj-display-year" }, this.displayYear),
                h("p", { class: "anj-display-date" }, this.displayDate)),
            h("div", { class: "anj-date-controls", ref: r => this.controlsEl = r, tabindex: "0" }, this.monthMode
                ? h("anj-date-picker-month-view", { package: this.package, rangeParams: this.rangeParams })
                : h("anj-date-picker-year-view", { package: this.package }))
        ];
    }
    static get is() { return "anj-calendar"; }
    static get encapsulation() { return "scoped"; }
    static get originalStyleUrls() { return {
        "$": ["calendar.scss"]
    }; }
    static get styleUrls() { return {
        "$": ["calendar.css"]
    }; }
    static get properties() { return {
        "adapter": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "DatePickerService",
                "resolved": "DatePickerService",
                "references": {
                    "DatePickerService": {
                        "location": "import",
                        "path": "../date-picker.service"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "The adapter to use for i18n, l10n needs"
            }
        },
        "date": {
            "type": "unknown",
            "mutable": true,
            "complexType": {
                "original": "Date",
                "resolved": "Date",
                "references": {
                    "Date": {
                        "location": "global"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "The current value"
            }
        },
        "monthMode": {
            "type": "boolean",
            "mutable": true,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "If true, display a calendar view, otherwise show yearly"
            },
            "attribute": "month-mode",
            "reflect": false,
            "defaultValue": "true"
        },
        "rangeParams": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "DateRangeValidationParams",
                "resolved": "DateRangeValidationParams",
                "references": {
                    "DateRangeValidationParams": {
                        "location": "import",
                        "path": "../../../types/types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Min and max selectable days"
            }
        }
    }; }
    static get states() { return {
        "controlsEl": {},
        "days": {},
        "displayYear": {},
        "displayDate": {},
        "package": {},
        "month": {},
        "year": {}
    }; }
    static get events() { return [{
            "method": "anjCalendarDaySelect",
            "name": "anjCalendarDaySelect",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "Date",
                "resolved": "Date",
                "references": {
                    "Date": {
                        "location": "global"
                    }
                }
            }
        }]; }
    static get methods() { return {
        "focusControls": {
            "complexType": {
                "signature": "() => Promise<void>",
                "parameters": [],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        }
    }; }
    static get elementRef() { return "element"; }
    static get watchers() { return [{
            "propName": "date",
            "methodName": "onDateChange"
        }]; }
    static get listeners() { return [{
            "name": "anjMouseOut",
            "method": "setHeaderData",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjMouseOver",
            "method": "displayActiveDay",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjToggleMonthMode",
            "method": "toggleMonthMode",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjYearChanged",
            "method": "updateYear",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjMonthChanged",
            "method": "selectMonth",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjMonthUpdated",
            "method": "updateMonth",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjDaySelect",
            "method": "selectDay",
            "target": undefined,
            "capture": false,
            "passive": false
        }]; }
}
