// Desk calendar: a dial clock that turns once per in-game day, the date, term progress, next // decision dates, the brass speed controls and the way into the menu. import { t, dateParts } from "../i18n/i18n.js"; import { dateOfDay } from "../engine/index.js"; import { $, dialSvg, setDial } from "./desk.js"; export function createCalendar(root, bal, { onSpeed, onMenu }) { const speeds = bal.time.speeds; root.innerHTML = `
${dialSvg("cal__dial")}
${t("cal.briefing")}
${t("cal.review")}
${speeds.map((s) => ``).join("")}
`; root.addEventListener("click", (e) => { const b = e.target.closest("button"); if (!b) return; if (b.dataset.menu !== undefined) onMenu(); else onSpeed(Number(b.dataset.speed)); }); const until = (day, every) => (every - (day % every)) % every; const when = (n) => { if (n === 0) return t("cal.today"); return n === 1 ? t("cal.tomorrow") : t("cal.inDays", { n }); }; const dial = $(root, ".cal__dial"); let lastDay = -1; function update(state) { const p = dateParts(dateOfDay(state.startDate, state.day).iso); $(root, ".cal__weekday").textContent = p.weekday; const dayEl = $(root, ".cal__day"); dayEl.textContent = p.day; if (lastDay >= 0 && state.day !== lastDay && state.speed > 0 && state.speed <= 2) { dayEl.classList.remove("is-flip"); void dayEl.offsetWidth; // restart the animation dayEl.classList.add("is-flip"); } lastDay = state.day; $(root, ".cal__month").textContent = `${p.month} ${p.year}`; const shown = Math.min(state.day + 1, bal.time.termDays); $(root, ".cal__count").textContent = t("cal.dayCount", { day: shown, total: bal.time.termDays }); $(root, ".cal__term span").style.width = `${(state.day / bal.time.termDays) * 100}%`; const over = Boolean(state.over); $(root, '[data-next="briefing"]').textContent = over ? "–" : when(until(state.day, bal.time.daysPerWeek)); $(root, '[data-next="review"]').textContent = over ? "–" : when(state.pending.review ? 0 : until(state.day, bal.time.daysPerQuarter)); for (const b of root.querySelectorAll("button[data-speed]")) { b.setAttribute("aria-pressed", String(Number(b.dataset.speed) === state.speed)); } } return { update, clockHand: (progress) => setDial(dial, progress) }; }