/*
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
if you want to view the source visit the plugins github repository
*/

'use strict';

var obsidian = require('obsidian');

/******************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */

function __awaiter(thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
}

const DEFAULT_SETTINGS = {
    startOfWeek: '0',
    monthFormat: 'YYYY-MM',
    displayHead: true,
    enableHTML: false,
    enableMarkdown: true,
    Sunday: 'SUN',
    Monday: 'MON',
    Tuesday: 'TUE',
    Wednesday: 'WED',
    Thursday: 'THU',
    Friday: 'FRI',
    Saturday: 'SAT'
};
class HabitTrackerPlugin extends obsidian.Plugin {
    onload() {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.loadSettings();
            this.addSettingTab(new HabitTrackerSettingTab(this.app, this));
            //@ts-ignore
            window.renderHabitCalendar = (el, dv, calendarParam) => {
                dv.current().file.path;
                let calendarData = param2CalendarData(dv, calendarParam);
                let ctx = fromCalendarData(calendarData, this.settings);
                const styles = ctx.tableWidth ? `width: ${ctx.tableWidth};` : '';
                const table = createEl('table', { cls: 'habitt', attr: { style: styles } });
                table.appendChild(renderHead(ctx));
                table.appendChild(renderBody(ctx));
                el.appendChild(table);
            };
        });
    }
    loadSettings() {
        return __awaiter(this, void 0, void 0, function* () {
            this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
        });
    }
    saveSettings() {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.saveData(this.settings);
        });
    }
}
function createContext(calendarData, settings) {
    return {
        startOfWeek: parseInt(settings.startOfWeek, 10),
        startDay: 0,
        monthDays: 0,
        displayMonth: '',
        tableWidth: '',
        marks: new Map(),
        settings,
        error: '',
        calendarData,
        filepath: calendarData.filepath
    };
}
function isTableData(data) {
    return data.successful && data.value && data.value.type == 'table';
}
function param2CalendarData(dv, params) {
    const calendarData = {
        year: params.year,
        month: params.month,
        filepath: dv.current().file.path,
        width: params.width || "100%",
        entries: params.data,
        format: params.format || 'text',
        date_pattern: params.date_pattern || params.note_pattern || 'YYYY-MM-DD'
    };
    if (isTableData(params.data)) {
        const headers = params.data.value.headers;
        const values = params.data.value.values;
        const dataDict = {};
        for (let ri = 0; ri < values.length; ri += 1) {
            // fill calendar day
            const value = values[ri];
            const link = value[0];
            const date = obsidian.moment(link.fileName(), calendarData.date_pattern);
            if (!date.isValid()) {
                continue;
            }
            const dateString = link.fileName();
            let entry = dataDict[dateString];
            if (!entry) {
                entry = {
                    'date': dateString,
                    'content': '',
                    'link': link.path
                };
                dataDict[dateString] = entry;
            }
            // fill content
            for (let ci = 1; ci < value.length; ci++) {
                if (value[ci]) {
                    // if the header contains a "|", use the string after "|" as label
                    const splited = headers[ci].split("|");
                    const label = splited[splited.length - 1];
                    entry.content += `${label} ${value[ci]}\n`;
                }
            }
        }
        calendarData.entries = Object.values(dataDict);
        calendarData.format = 'text';
    }
    return calendarData;
}
function fromCalendarData(calendarData, settings) {
    const ctx = createContext(calendarData, settings);
    const mon = obsidian.moment(`${calendarData.year}-${calendarData.month}`, 'YYYY-M');
    if (!mon.isValid()) {
        ctx.error = `Fail: Invalid Date ${calendarData.year}-${calendarData.month}`;
        return ctx;
    }
    ctx.displayMonth = mon.format(settings.monthFormat);
    ctx.startDay = mon.startOf('month').day();
    ctx.monthDays = mon.endOf('month').date();
    // table width (optional)
    if (calendarData.width) {
        ctx.tableWidth = calendarData.width;
    }
    // punch in
    calendarData.entries.forEach(entry => {
        const d = obsidian.moment(entry.date, calendarData.date_pattern);
        if (d.year() == calendarData.year && d.month() + 1 == calendarData.month) {
            ctx.marks.set(d.date(), entry);
        }
    });
    return ctx;
}
function renderHead(ctx) {
    const { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } = ctx.settings;
    const WEEK = [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday];
    const thead = createEl('thead');
    if (ctx.settings.displayHead) {
        const tr = thead.createEl('tr');
        tr.createEl('th', { cls: 'habitt-head', attr: { colspan: 7 }, text: ctx.displayMonth });
    }
    const tr = thead.createEl('tr');
    for (let i = 0; i < 7; i++) {
        tr.createEl('th', { cls: `habitt-th habitt-th-${i}`, text: WEEK[(i + ctx.startOfWeek) % 7] });
    }
    return thead;
}
function renderBody(ctx) {
    const startHolds = ctx.startDay >= ctx.startOfWeek ? ctx.startDay - ctx.startOfWeek : 7 - ctx.startOfWeek + ctx.startDay;
    let days = (new Array(ctx.monthDays)).fill(0).map((v, i) => i + 1);
    const weeks = [];
    if (startHolds) {
        const startWeekDays = 7 - startHolds;
        const firstWeek = (new Array(startHolds)).fill(0);
        weeks.push(firstWeek.concat(days.slice(0, startWeekDays)));
        days = days.slice(startWeekDays);
    }
    let i = 0;
    while (i < days.length) {
        weeks.push(days.slice(i, i + 7));
        i = i + 7;
    }
    const lastWeek = weeks[weeks.length - 1];
    if (lastWeek.length < 7) {
        const pad = 7 - lastWeek.length;
        for (let i = 0; i < pad; i++) {
            lastWeek.push(0);
        }
    }
    const tbody = createEl('tbody');
    const { enableHTML } = ctx.settings;
    for (let i = 0; i < weeks.length; i++) {
        const tr = tbody.createEl('tr');
        for (let j = 0; j < weeks[i].length; j++) {
            const d = weeks[i][j];
            const hasOwn = ctx.marks.has(d);
            const td = tr.createEl('td', { cls: `habitt-td habitt-td--${d || 'disabled'} ${hasOwn ? 'habitt-td--checked' : ''}` });
            const div = td.createDiv({ cls: 'habitt-c' });
            // create link to file
            if (hasOwn) {
                const day_div = div.createDiv({ cls: 'habitt-date' });
                const link = ctx.marks.get(d).link ? ctx.marks.get(d).link : ctx.marks.get(d).date;
                day_div.createEl('a', { text: `${d || ''}`, cls: "internal-link", href: link, attr: { "data-href": link, "target": "_blank", "rel": "noopener" } });
            }
            else {
                div.createDiv({ cls: 'habitt-date', text: `${d || ''}` });
            }
            const dots = div.createDiv({ cls: 'habitt-dots' });
            if (hasOwn) {
                const input = ctx.marks.get(d).content;
                // treat as HTML
                if (enableHTML && ctx.calendarData.format == 'html') {
                    dots.innerHTML = `<div>${input}</div>`;
                }
                else if (ctx.settings.enableMarkdown && ctx.calendarData.format == 'markdown') {
                    const md_div = dots.createDiv();
                    obsidian.MarkdownRenderer.renderMarkdown(input, md_div, ctx.filepath, this);
                }
                else {
                    dots.createDiv({ cls: 'habit-content', text: input });
                }
            }
        }
    }
    return tbody;
}
class HabitTrackerSettingTab extends obsidian.PluginSettingTab {
    constructor(app, plugin) {
        super(app, plugin);
        this.plugin = plugin;
    }
    display() {
        const { containerEl } = this;
        containerEl.empty();
        // containerEl.createEl('h2', {text: 'Settings for my awesome plugin.'});
        const weeks = {
            '0': 'Sunday',
            '1': 'Monday',
            '2': 'Tuesday',
            '3': 'Wednesday',
            '4': 'Thursday',
            '5': 'Friday',
            '6': 'Saturday'
        };
        new obsidian.Setting(containerEl)
            .setName('Start Of Week')
            .setDesc('The day a week begins.')
            .addDropdown(dropdown => dropdown
            .addOptions(weeks)
            .setValue(this.plugin.settings.startOfWeek)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.startOfWeek = value;
            yield this.plugin.saveSettings();
        })));
        new obsidian.Setting(containerEl)
            .setName('Display Table Header')
            .addToggle(dropdown => dropdown
            .setValue(this.plugin.settings.displayHead)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.displayHead = value;
            yield this.plugin.saveSettings();
        })));
        new obsidian.Setting(containerEl)
            .setName('Enable HTML')
            .setDesc('Treat your input text as HTML. Be careful, it may cause DOM injection attacks')
            .addToggle(dropdown => dropdown
            .setValue(this.plugin.settings.enableHTML)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.enableHTML = value;
            yield this.plugin.saveSettings();
        })));
        new obsidian.Setting(containerEl)
            .setName('Enable Markdown Rendering')
            .setDesc('Treat your input text as Markdown.')
            .addToggle(dropdown => dropdown
            .setValue(this.plugin.settings.enableMarkdown)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.enableMarkdown = value;
            yield this.plugin.saveSettings();
        })));
        new obsidian.Setting(containerEl)
            .setName('Month Format')
            .setDesc('To format the month text which displays in the header')
            .addText(text => text
            .setValue(this.plugin.settings.monthFormat)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.monthFormat = value;
            yield this.plugin.saveSettings();
        })));
        new obsidian.Setting(containerEl)
            .setName('Sunday Label')
            .setDesc('Default is SUN')
            .addText(text => text
            .setValue(this.plugin.settings.Sunday)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.Sunday = value || DEFAULT_SETTINGS.Sunday;
            yield this.plugin.saveSettings();
        })));
        new obsidian.Setting(containerEl)
            .setName('Monday Label')
            .setDesc('Default is MON')
            .addText(text => text
            .setValue(this.plugin.settings.Monday)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.Monday = value || DEFAULT_SETTINGS.Monday;
            yield this.plugin.saveSettings();
        })));
        new obsidian.Setting(containerEl)
            .setName('Tuesday Label')
            .setDesc('Default is TUE')
            .addText(text => text
            .setValue(this.plugin.settings.Tuesday)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.Tuesday = value || DEFAULT_SETTINGS.Tuesday;
            yield this.plugin.saveSettings();
        })));
        new obsidian.Setting(containerEl)
            .setName('Wednesday Label')
            .setDesc('Default is WED')
            .addText(text => text
            .setValue(this.plugin.settings.Wednesday)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.Wednesday = value || DEFAULT_SETTINGS.Wednesday;
            yield this.plugin.saveSettings();
        })));
        new obsidian.Setting(containerEl)
            .setName('Thursday Label')
            .setDesc('Default is THU')
            .addText(text => text
            .setValue(this.plugin.settings.Thursday)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.Thursday = value || DEFAULT_SETTINGS.Thursday;
            yield this.plugin.saveSettings();
        })));
        new obsidian.Setting(containerEl)
            .setName('Friday Label')
            .setDesc('Default is FRI')
            .addText(text => text
            .setValue(this.plugin.settings.Friday)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.Friday = value || DEFAULT_SETTINGS.Friday;
            yield this.plugin.saveSettings();
        })));
        new obsidian.Setting(containerEl)
            .setName('Saturday Label')
            .setDesc('Default is SAT')
            .addText(text => text
            .setValue(this.plugin.settings.Saturday)
            .onChange((value) => __awaiter(this, void 0, void 0, function* () {
            this.plugin.settings.Saturday = value || DEFAULT_SETTINGS.Saturday;
            yield this.plugin.saveSettings();
        })));
    }
}

module.exports = HabitTrackerPlugin;
