#!/usr/bin/env python3
"""
pop_pack_guard.py — упаковщик спрайтов СТРАЖА (chtab_5_guard, база 750).

Оригинал грузит стражей из отдельного .DAT по типу уровня
(GUARD/FAT/SKEL/VIZIER/SHADOW, seg000:1092); уровень 1 — обычный «guard»,
то есть data/GUARD/res(750+id).png.  Палитра — НЕ из PNG: оригинал
подменяет её из res10.bin (guard_palettes, 7 палитр по 16 цветов, 6-бит) по
level.guards_color; на уровне 1 у обоих стражей color = 2.

Выход: poc/res/guard/g0..gN.atl (по 8 спрайтов на страницу, адресация
id>>3 / id&7 — как у Kid) + группа палитры 0x90..0x9F в общий kid.pal
(его собирает pop_pack_kid.py, см. GUARD_PAL_BASE там).
"""
import os
import sys
from PIL import Image

HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
import pop_pack_bg as B
from pop_pack_kid import transpose_cols

GUARD_DIR = os.path.join(HERE, "..", "SDLPoP", "data", "GUARD")
PAL_BIN   = os.path.join(HERE, "..", "SDLPoP", "data", "PRINCE", "res10.bin")
OUT_DIR   = os.path.join(HERE, "..", "poc", "res", "guard")
PAL_BASE  = 0x90          # слоты палитры Sprinter под стража
COLOR     = 2             # level.guards_color обоих стражей уровня 1
SHIFT     = 3             # g[id>>3], idx id&7 (спрайты крупные)
MASK      = (1 << SHIFT) - 1
MAX_ID    = 33            # атлас-индексы 0..33 = res751..res784


def load_guard(id):
    """Атлас-индекс id (== frame.image) -> res(751+id).png -> (w, h, 8bpp
    COLUMN-MAJOR); 0 -> 0xFF (прозрачность).

    Off-by-one как у Kid (см. pop_pack_kid.load_kid): load_chtab_from_file
    зовётся с ресурсом 750, а images[i-1] = res(750+i), то есть images[0] =
    res751.  Рисование берёт get_image(chtab, obj_id+1 − 1) = images[image],
    значит frame.image=N -> res(751+N).  С res(750+N) страж стоял в позе
    предыдущего кадра (замечено на frame_166_stand_inactive: image 17
    рисовался как res767 — выпад — вместо res768). """
    path = os.path.join(GUARD_DIR, f"res{751 + id}.png")
    if not os.path.exists(path):
        return None
    im = Image.open(path)
    if im.mode != "P":
        B.die(f"res{750+id}: mode {im.mode}, ожидался P")
    src = im.tobytes()
    rowmajor = bytes((0xFF if v == 0 else PAL_BASE + v) for v in src)
    return im.width, im.height, transpose_cols(im.width, im.height, rowmajor)


def guard_palette():
    """16 цветов (r,g,b 0..63) из res10.bin для COLOR."""
    b = open(PAL_BIN, "rb").read()
    off = 0x30 * COLOR - 0x30
    return [(b[off + i * 3], b[off + i * 3 + 1], b[off + i * 3 + 2]) for i in range(16)]


def main():
    os.makedirs(OUT_DIR, exist_ok=True)
    pages = {}
    n = 0
    for id in range(0, MAX_ID + 1):
        g = load_guard(id)
        if g is None:
            continue
        pages.setdefault(id >> SHIFT, {})[id & MASK] = g
        n += 1
    if not pages:
        B.die("нет спрайтов стража")
    total = 0
    for pg in range(max(pages) + 1):
        nm = f"g{pg}.atl"
        cnt, sz = B.pack_atlas(os.path.join(OUT_DIR, nm), pages.get(pg, {}))
        total += sz
        print(f"  {nm}: {len(pages.get(pg, {}))} спрайтов, каталог {cnt}, {sz} Б")
    print(f"ИТОГО: {n} спрайтов стража, {max(pages)+1} EMM-страниц, {total} Б -> {OUT_DIR}")


if __name__ == "__main__":
    main()
