#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
build_firmware.py — 基本季語700(Model B) の実機ヘッダを生成
------------------------------------------------------------------------
入力 : pad-data.js（build_pad_data.py が作る；分類別・年順・frac つき）
出力 :
  firmware/kigo_font.h  32px明朝(語) / 16px太ゴシック(語・読み・解説・UI)
  firmware/kigo_data.h  分類7行の季語テーブル（行オフセット＋各語 w/y/d/season/part/frac）
  各スケッチフォルダ＆ ~/Documents/Arduino/sketch_sep24a にもコピー

make_font.py のグリフ描画・出力関数を再利用する。
"""
import os, json, re, shutil
import make_font as mf   # render_glyph / emit_glyph_block / find_font / c_str を借りる

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SEASONS = ["春", "夏", "秋", "冬", "新年"]
SKETCH_DIRS = ["kigo_pad"]                      # Model B は kigo_pad のみ
EXTRA_SYNC = [os.path.expanduser("~/Documents/Arduino/sketch_sep24a")]

def load_pad():
    js = open(os.path.join(ROOT, "pad-data.js"), encoding="utf-8").read()
    return json.loads(js[js.index("{"): js.rindex("}") + 1])

def main():
    P = load_pad()
    CATS, ROWS = P["cats"], P["rows"]
    font32 = mf.find_font(None, mf.DEFAULT_FONTS)
    font16 = mf.find_font(None, mf.DEFAULT_FONTS16)

    # 行オフセットでフラット化（行r = [START[r], START[r]+LEN[r]) ）
    flat = []
    row_len, row_start = [], []
    acc = 0
    for r, lst in enumerate(ROWS):
        row_start.append(acc); row_len.append(len(lst)); acc += len(lst)
        for k in lst:
            flat.append((r, k))
    NK = len(flat)

    # 文字集合
    k32, k16 = set(), set()
    for _, k in flat:
        k32 |= set(k["w"])
        k16 |= set(k["w"]) | set(k["y"]) | set(k["d"])
    for c in CATS: k16 |= set(c)
    for s in SEASONS: k16 |= set(s)
    for _, k in flat: k16 |= set(k.get("part") or "")
    k16 |= set("・「」—")
    k32 = sorted(k32, key=ord); k16 = sorted(k16, key=ord)
    print(f"font32(語): {len(k32)}  font16(全): {len(k16)}  総語数: {NK}")

    # ---- kigo_font.h ----
    fp = os.path.join(ROOT, "firmware", "kigo_font.h")
    with open(fp, "w", encoding="utf-8") as f:
        f.write("// AUTOGENERATED by tools/build_firmware.py — do not edit.\n#pragma once\n#include <Arduino.h>\n\n")
        mf.emit_glyph_block(f, "GLYPH32", k32, 32, font32, 110)
        mf.emit_glyph_block(f, "GLYPH16", k16, 16, font16, 90)
    print("wrote", fp)

    # ---- kigo_data.h ----
    dp = os.path.join(ROOT, "firmware", "kigo_data.h")
    with open(dp, "w", encoding="utf-8") as f:
        f.write("// AUTOGENERATED by tools/build_firmware.py — do not edit.\n#pragma once\n#include <Arduino.h>\n\n")
        f.write(f"#define NROW {len(CATS)}\n#define NK {NK}\n\n")
        f.write("const char* const CAT_NAME[NROW] = {" + ",".join(mf.c_str(c) for c in CATS) + "};\n")
        f.write("const char* const SEASON_NAME[5] = {" + ",".join(mf.c_str(s) for s in SEASONS) + "};\n")
        f.write("const uint16_t ROW_START[NROW] = {" + ",".join(str(x) for x in row_start) + "};\n")
        f.write("const uint16_t ROW_LEN[NROW]   = {" + ",".join(str(x) for x in row_len) + "};\n\n")
        f.write("const char* const KW[NK] = {\n")
        for _, k in flat: f.write("  " + mf.c_str(k["w"]) + ",\n")
        f.write("};\n")
        f.write("const char* const KY[NK] = {\n")
        for _, k in flat: f.write("  " + mf.c_str(k["y"]) + ",\n")
        f.write("};\n")
        f.write("const char* const KD[NK] = {\n")
        for _, k in flat: f.write("  " + mf.c_str(k["d"]) + ",\n")
        f.write("};\n")
        f.write("const uint8_t  KSEASON[NK] = {" + ",".join(str(SEASONS.index(k["season"])) for _, k in flat) + "};\n")
        f.write("const char* const KPART[NK] = {" + ",".join(mf.c_str(k.get("part") or "") for _, k in flat) + "};\n")
        f.write("const uint16_t KFRAC[NK] = {" + ",".join(str(int(round(k["frac"]*1000))) for _, k in flat) + "};\n")
    print("wrote", dp)

    # ---- コピー ----
    targets = [os.path.join(ROOT, "firmware", d) for d in SKETCH_DIRS] + EXTRA_SYNC
    for t in targets:
        if os.path.isdir(t):
            shutil.copy(fp, os.path.join(t, "kigo_font.h"))
            shutil.copy(dp, os.path.join(t, "kigo_data.h"))
            print("copied ->", t)

if __name__ == "__main__":
    main()
