import { createStore } from '../core/store.js';
import { initialClock, start, elapsedMs } from '../core/clock.js';
import { nextUnreachedBeat } from '../core/timeline.js';
import './director-rail.js';
import './dice-tray.js';
import './npc-tray.js';
import './art-tray.js';
import './prop-viewer.js';
export class GmShell extends HTMLElement {
constructor() {
super();
this.now = () => Date.now();
this.scenario = null;
this.store = null;
this.clockState = initialClock();
this.stamps = {};
this.cast = [];
this._tick = null;
}
connectedCallback() {
this.innerHTML = `
`;
this.addEventListener('reached', () => this.onReached());
this.addEventListener('open-tool', (e) => this.onOpenTool(e));
this.addEventListener('keep-npc', (e) => this.onKeepNpc(e));
this.addEventListener('show-prop', (e) => this.onShowProp(e));
}
loadScenario(scenario) {
this.scenario = scenario;
this.store = createStore(scenario.meta.id);
this.clockState = this.store.get('clock', initialClock());
this.stamps = this.store.get('stamps', {});
this.cast = this.store.get('cast', []);
this.querySelector('dice-tray').systemId = scenario.meta.system;
this.refresh();
}
startSession() {
this.clockState = start(this.clockState, this.now());
this.store.set('clock', this.clockState);
if (!this._tick) this._tick = setInterval(() => this.refresh(), 1000);
this.refresh();
}
elapsedMs() { return elapsedMs(this.clockState, this.now()); }
onReached() {
const beat = nextUnreachedBeat(this.scenario.timeline, this.stamps);
if (!beat) return;
this.stamps = { ...this.stamps, [beat.id]: this.elapsedMs() / 60000 };
this.store.set('stamps', this.stamps);
this.refresh();
}
onOpenTool(e) {
const tool = e.detail?.tool;
const trays = { dice: 'dice-tray', npc: 'npc-tray', art: 'art-tray' };
if (!(tool in trays)) return;
const target = this.querySelector(trays[tool]);
const willShow = target.hidden;
for (const sel of Object.values(trays)) this.querySelector(sel).hidden = true;
target.hidden = !willShow;
}
onKeepNpc(e) {
this.cast = [...this.cast, e.detail];
this.store.set('cast', this.cast);
}
onShowProp(e) {
this.querySelector('prop-viewer').show(e.detail.src, e.detail.label);
}
refresh() {
this.querySelector('director-rail').update({
scenario: this.scenario,
elapsedMs: this.elapsedMs(),
stamps: this.stamps,
});
}
}
customElements.define('gm-shell', GmShell);