import { getLoksyuData, setLoksyuData } from "./singletons.js" const SYSTEM_ID = "fvtt-chroniques-de-l-etrange" export class CDELoksyuApp extends foundry.applications.api.HandlebarsApplicationMixin( foundry.applications.api.ApplicationV2 ) { static DEFAULT_OPTIONS = { id: "cde-loksyu-app", tag: "div", window: { title: "CDE.Loksyu", icon: "fas fa-yin-yang", resizable: false, }, classes: ["cde-app", "cde-loksyu-standalone"], position: { width: 520, height: "auto" }, actions: { resetElement: CDELoksyuApp.#onResetElement, resetAll: CDELoksyuApp.#onResetAll, }, } static PARTS = { main: { template: `systems/${SYSTEM_ID}/templates/apps/cde-loksyu-app.html`, }, } /** @type {Function|null} bound hook handler */ _updateHook = null /** Singleton accessor — open or bring to front */ static open() { const existing = Array.from(foundry.applications.instances.values()).find( (app) => app instanceof CDELoksyuApp ) if (existing) { existing.bringToFront(); return existing } const app = new CDELoksyuApp() app.render(true) return app } async _prepareContext() { const sys = getLoksyuData() const ELEMENTS = [ { key: "wood", nameKey: "CDE.Wood", qualKey: "CDE.WoodQualities", img: `systems/${SYSTEM_ID}/images/cde_bois.webp` }, { key: "fire", nameKey: "CDE.Fire", qualKey: "CDE.FireQualities", img: `systems/${SYSTEM_ID}/images/cde_feu.webp` }, { key: "earth", nameKey: "CDE.Earth", qualKey: "CDE.EarthQualities", img: `systems/${SYSTEM_ID}/images/cde_terre.webp` }, { key: "metal", nameKey: "CDE.Metal", qualKey: "CDE.MetalQualities", img: `systems/${SYSTEM_ID}/images/cde_metal.webp` }, { key: "water", nameKey: "CDE.Water", qualKey: "CDE.WaterQualities", img: `systems/${SYSTEM_ID}/images/cde_eau.webp` }, ] return { canEdit: game.user.isGM, elements: ELEMENTS.map((el) => ({ ...el, yang: sys[el.key]?.yang ?? 0, yin: sys[el.key]?.yin ?? 0, })), } } _onRender(context, options) { super._onRender(context, options) this.#bindInputs() this._updateHook = Hooks.on("cde:loksyuUpdated", () => this.render()) } _onClose(options) { if (this._updateHook !== null) { Hooks.off("cde:loksyuUpdated", this._updateHook) this._updateHook = null } super._onClose(options) } #bindInputs() { const inputs = this.element?.querySelectorAll("input[data-field]") if (!inputs?.length) return inputs.forEach((input) => { input.addEventListener("change", async (ev) => { const field = ev.currentTarget.dataset.field const val = parseInt(ev.currentTarget.value, 10) if (!field || isNaN(val)) return // field is like "wood.yin" or "fire.yang" const [aspect, dim] = field.split(".") if (!aspect || !dim) return const data = getLoksyuData() if (!data[aspect]) data[aspect] = { yin: 0, yang: 0 } data[aspect][dim] = Math.max(0, val) await setLoksyuData(data) }) }) } static async #onResetElement(event, target) { const key = target.dataset.element if (!key) return const data = getLoksyuData() data[key] = { yin: 0, yang: 0 } await setLoksyuData(data) } static async #onResetAll(_event, _target) { const KEYS = ["wood", "fire", "earth", "metal", "water"] const data = getLoksyuData() for (const k of KEYS) data[k] = { yin: 0, yang: 0 } await setLoksyuData(data) } }