#!/usr/bin/env python3
"""
Build a contact sheet of every texture under art/ — each PNG upscaled
with nearest-neighbour (so pixels stay crisp) and labelled with its
relative path. Output: art/CATALOG.png

Run from repo root:
    python3 scripts/build-art-catalog.py
"""
import os
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont

REPO = Path(__file__).resolve().parent.parent
ART = REPO / "art"
OUT = ART / "CATALOG.png"

TILE = 128          # upscaled texture size
COLS = 6            # tiles per row
PAD_X = 20          # horizontal padding around each tile
PAD_Y = 60          # vertical padding (extra room for label below)
LABEL_PX = 14       # label font size
BG = (30, 30, 46)   # dark background
FG = (230, 230, 240)
SECTION_BG = (50, 60, 90)


def load_font(size):
    for cand in (
        "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
        "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf",
        "/mnt/c/Windows/Fonts/consola.ttf",
        "/mnt/c/Windows/Fonts/arial.ttf",
    ):
        if os.path.exists(cand):
            return ImageFont.truetype(cand, size)
    return ImageFont.load_default()


def collect():
    """Return {pack_name: [(relative_path, abs_path), ...]} grouped & sorted."""
    groups = {}
    for png in sorted(ART.rglob("*.png")):
        if png.name == "CATALOG.png":
            continue
        rel = png.relative_to(ART)
        pack = rel.parts[0]
        groups.setdefault(pack, []).append((rel, png))
    return groups


def upscale(png_path, size):
    img = Image.open(png_path).convert("RGBA")
    return img.resize((size, size), Image.NEAREST)


def main():
    groups = collect()
    if not groups:
        print("No PNGs found under art/. Nothing to do.")
        return

    font_label = load_font(LABEL_PX)
    font_section = load_font(LABEL_PX + 8)

    # Calculate overall canvas size
    section_height = LABEL_PX + 24
    tile_block_h = TILE + PAD_Y
    total_h = 40
    for pack, items in groups.items():
        rows = (len(items) + COLS - 1) // COLS
        total_h += section_height + rows * tile_block_h + 20
    total_w = COLS * (TILE + PAD_X) + PAD_X + 40

    canvas = Image.new("RGBA", (total_w, total_h), BG)
    draw = ImageDraw.Draw(canvas)

    y = 20
    for pack, items in groups.items():
        # Section header
        draw.rectangle([20, y, total_w - 20, y + section_height - 4], fill=SECTION_BG)
        draw.text((32, y + 4), pack, font=font_section, fill=FG)
        y += section_height + 6

        # Tiles
        for i, (rel, abs_path) in enumerate(items):
            col = i % COLS
            row = i // COLS
            x = 20 + PAD_X // 2 + col * (TILE + PAD_X)
            ty = y + row * tile_block_h

            try:
                tile = upscale(abs_path, TILE)
                canvas.paste(tile, (x, ty), tile)
            except Exception as e:
                draw.rectangle([x, ty, x + TILE, ty + TILE], outline=(200, 80, 80), width=2)
                draw.text((x + 4, ty + 4), f"ERR: {e}", font=font_label, fill=(255, 120, 120))

            # Label: show subpath + filename below the tile
            label = "/".join(rel.parts[1:])  # drop pack prefix
            draw.text((x, ty + TILE + 4), label, font=font_label, fill=FG)

        rows = (len(items) + COLS - 1) // COLS
        y += rows * tile_block_h + 20

    canvas.save(OUT)
    print(f"Wrote {OUT} — {sum(len(v) for v in groups.values())} textures across {len(groups)} packs.")


if __name__ == "__main__":
    main()
