// 字体の候補を、実際のゲーム画面で見比べられるようにする。
// 同じ状態まで進めてから、フォントだけ差し替えて撮る。
import fs from 'fs';
import { spawn } from 'child_process';

const CHROME = 'C:/Program Files/Google/Chrome/Application/chrome.exe';
const PORT = 9455;
const profile = 'C:/Users/ADMINI~1/AppData/Local/Temp/lm-font';

const CANDIDATES = [
  { id: '1-pgothic', name: 'MS Pゴシック（現状）', stack: '"MS PGothic","MS Gothic"', px: 11, web: null,
    note: 'Windows 98 の日本語版が実際に使っていたUIフォント。小さい字はビットマップで表示されるので、この11pxでもにじまない。' },
  { id: '2-pmincho', name: 'MS P明朝', stack: '"MS PMincho","MS Mincho"', px: 11, web: null,
    note: '同じくWin98純正の明朝。印刷された台帳や説明書の雰囲気。' },
  { id: '3-bizmincho', name: 'BIZ UD P明朝', stack: '"BIZ UDPMincho"', px: 12, web: null,
    note: '現代的な明朝で、明朝のわりに小さい字でも潰れにくい。Windows 10以降に標準搭載。' },
  { id: '4-kyokasho', name: 'UDデジタル教科書体', stack: '"UD Digi Kyokasho NP-R","UD Digi Kyokasho NP"', px: 12, web: null,
    note: '教科書体。筆の運びが残っていて、手で書かれた記録らしく見える。' },
  { id: '5-zenold', name: 'Zen Old Mincho', stack: '"Zen Old Mincho"', px: 12, web: 'Zen+Old+Mincho',
    note: '古風な明朝。活版の古い本の趣。要ダウンロード（OFL）。' },
  { id: '6-klee', name: 'Klee One', stack: '"Klee One"', px: 12, web: 'Klee+One',
    note: '楷書寄りの手書き体。冒険者の手帳という感じ。要ダウンロード（OFL）。' },
  { id: '7-dot', name: 'DotGothic16（ドット）', stack: '"DotGothic16"', px: 16, web: 'DotGothic16',
    note: 'ドット絵フォント。ファミコン期のRPGの字。設計サイズが16pxなので、他より大きめに出す必要がある。要ダウンロード（OFL）。' },
];

fs.rmSync(profile, { recursive: true, force: true });
const chrome = spawn(CHROME, ['--headless=new', '--disable-gpu', '--no-sandbox', '--no-first-run',
  '--remote-debugging-port=' + PORT, '--user-data-dir=' + profile,
  '--window-size=1370,820', 'about:blank'], { stdio: 'ignore' });
const sleep = ms => new Promise(r => setTimeout(r, ms));

let list = null;
for (let i = 0; i < 40; i++) { try { list = await (await fetch(`http://127.0.0.1:${PORT}/json/list`)).json(); if (list.length) break; } catch { } await sleep(300); }
const ws = new WebSocket(list.find(t => t.type === 'page').webSocketDebuggerUrl);
await new Promise(r => ws.addEventListener('open', r));
let id = 0; const pend = new Map();
ws.addEventListener('message', e => { const m = JSON.parse(e.data); if (m.id && pend.has(m.id)) { pend.get(m.id)(m.result); pend.delete(m.id); } });
const send = (m, p = {}) => new Promise(res => { const i = ++id; pend.set(i, res); ws.send(JSON.stringify({ id: i, method: m, params: p })); });
const ev = async x => (await send('Runtime.evaluate', { expression: x, returnByValue: true, awaitPromise: true })).result?.value;
const shot = async n => fs.writeFileSync(`shots/font-${n}.png`, Buffer.from((await send('Page.captureScreenshot', { format: 'png' })).data, 'base64'));

await send('Page.enable'); await send('Runtime.enable');
await send('Page.navigate', { url: 'file:///' + process.cwd().replace(/\\/g, '/') + '/build/index-app.html' });
await sleep(4000);

// 画面に文章が並ぶところまで進める
for (let k = 0; k < 3; k++) {
  await ev('(function(){try{ fastForward(3600); }catch(e){} })()');
  await sleep(500);
}
await sleep(2000);

for (const c of CANDIDATES) {
  if (c.web) {
    await ev(`(()=>{ if(document.getElementById('gf-${c.id}')) return;
      const l=document.createElement('link'); l.id='gf-${c.id}'; l.rel='stylesheet';
      l.href='https://fonts.googleapis.com/css2?family=${c.web}&display=block';
      document.head.appendChild(l); })()`);
    await sleep(3500);            // 取得と適用を待つ
  }
  await ev(`(()=>{ let s=document.getElementById('fontswap');
    if(!s){ s=document.createElement('style'); s.id='fontswap'; document.head.appendChild(s); }
    s.textContent = 'body, button, input, select, textarea, table, td, th {'
      + 'font-family: ${c.stack.replace(/'/g, "\\\\'")}, sans-serif !important;'
      + 'font-size: ${c.px}px !important; }';
  })()`);
  await sleep(1200);
  await shot(c.id);
  console.log('撮影:', c.id, c.name);
}

fs.writeFileSync('shots/font-candidates.json', JSON.stringify(CANDIDATES, null, 1));
ws.close(); chrome.kill();
