import { DHImporter } from "./importer.js"; const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; export class DHImporterApp extends HandlebarsApplicationMixin(ApplicationV2) { constructor(options) { super(options); this.step = "input"; this.parsedData = null; this.parsedDataType = null; this.inputText = ""; } static DEFAULT_OPTIONS = { id: "dh-importer", tag: "form", classes: ["daggerheart", "dh-style", "dh-importer-app"], window: { title: "Daggerheart Importer", resizable: true, icon: "fas fa-file-import" }, position: { width: 600, height: 700 }, actions: { parse: DHImporterApp.onParse, import: DHImporterApp.onImport, back: DHImporterApp.onBack } }; static PARTS = { main: { template: "modules/dh-importer/templates/importer.hbs" } }; async _prepareContext(options) { return { step: this.step, parsedData: this.parsedData, isInput: this.step === "input", isPreview: this.step === "preview", types: { adversary: "Adversary", environment: "Environment" }, inputText: this.inputText, folders: game.folders.filter(f => f.type === "Actor").sort((a, b) => a.name.localeCompare(b.name)), packs: game.packs.filter(p => p.documentName === "Actor" && !p.locked) }; } _onRender(context, options) { super._onRender(context, options); // Bind File Pickers this.element.querySelectorAll("img[data-edit]").forEach(img => { img.addEventListener("click", ev => { const field = img.dataset.edit; const fp = new FilePicker({ type: "image", current: img.getAttribute("src"), callback: path => { img.src = path; const input = this.element.querySelector(`input[name='${field}']`); if (input) input.value = path; } }); fp.browse(); }); }); } static async onParse(event, target) { const form = this.element; const text = form.querySelector("textarea[name='text']").value; const type = form.querySelector("select[name='type']").value; // Store input text this.inputText = text; if (!text) { ui.notifications.warn("Please enter text to import."); return; } try { let data = []; if (type === "adversary") { data = DHImporter.parseAdversaries(text); } else if (type === "environment") { data = DHImporter.parseEnvironments(text); } if (data.length === 0) { ui.notifications.warn("No valid statblocks found."); return; } // Check existing features this.parsedData = await DHImporter.checkExistingFeatures(data); this.parsedDataType = type; this.step = "preview"; this.render(true); } catch (e) { console.error(e); ui.notifications.error("Error parsing data. Check console for details."); } } static async onImport(event, target) { try { const formData = new foundry.applications.ux.FormDataExtended(this.element).object; for (const actor of this.parsedData) { // Update Actor Image if (formData[`img.${actor.name}`]) { actor.img = formData[`img.${actor.name}`]; actor.prototypeToken.texture.src = formData[`img.${actor.name}`]; } // Update Attack Image if (formData[`attackImg.${actor.name}`]) { actor.system.attack.img = formData[`attackImg.${actor.name}`]; } // Open Sheet Flag if (formData[`openSheet.${actor.name}`]) { actor.openSheet = true; } actor.useFeatures = {}; for (const item of actor.items) { const key = `useFeatures.${actor.name}.${item.name}`; if (formData[key]) { actor.useFeatures[item.name] = formData[key]; } // Update Item Image const itemImgKey = `itemImg.${actor.name}.${item.name}`; if (formData[itemImgKey]) { item.img = formData[itemImgKey]; // Also update embedded action image if present if (item.system.actions) { for (const actionId in item.system.actions) { item.system.actions[actionId].img = formData[itemImgKey]; } } } } } const importTarget = formData.importTarget || ""; const sortTier = formData.sortTier || false; await DHImporter.createDocuments(this.parsedData, this.parsedDataType, { target: importTarget, sortTier }); ui.notifications.info(`Successfully imported ${this.parsedData.length} documents.`); this.close(); } catch (e) { console.error(e); ui.notifications.error("Error importing data."); } } static onBack(event, target) { this.step = "input"; this.render(true); } }