from PIL import Image, ImageDraw, ImageFont
from pathlib import Path
import json, math

SRC = Path(r"C:\allgifted\mathapi11v2\docs\past year questions\Only Images")
OUT = Path(r"C:\allgifted\mathapi11v2\docs\past year questions\_scan_montages")
OUT.mkdir(parents=True, exist_ok=True)
for old in OUT.glob("*"):
    old.unlink()

COLS, ROWS = 8, 6           # 48 tiles per montage
THUMB = 150                 # thumbnail box
LABEL = 16                  # label strip height
CELL_W, CELL_H = THUMB, THUMB + LABEL
PER = COLS * ROWS

files = sorted(SRC.glob("*.png"))
print(f"{len(files)} crops -> {math.ceil(len(files)/PER)} montages")

try:
    font = ImageFont.truetype("arial.ttf", 13)
except Exception:
    font = ImageFont.load_default()

mapping = {}
n_mont = math.ceil(len(files) / PER)
for mi in range(n_mont):
    chunk = files[mi*PER:(mi+1)*PER]
    canvas = Image.new("RGB", (COLS*CELL_W, ROWS*CELL_H), (255,255,255))
    draw = ImageDraw.Draw(canvas)
    names = []
    for ti, f in enumerate(chunk):
        r, c = divmod(ti, COLS)
        x0, y0 = c*CELL_W, r*CELL_H
        try:
            im = Image.open(f).convert("RGB")
            im.thumbnail((THUMB-6, THUMB-LABEL-6), Image.LANCZOS)
            canvas.paste(im, (x0+3, y0+LABEL+3))
        except Exception as e:
            draw.text((x0+3, y0+LABEL+3), "ERR", fill=(255,0,0), font=font)
        # tile number label (1-based within montage)
        draw.rectangle([x0, y0, x0+CELL_W-1, y0+LABEL-1], fill=(30,30,30))
        draw.text((x0+2, y0+1), str(ti+1), fill=(255,255,0), font=font)
        draw.rectangle([x0, y0, x0+CELL_W-1, y0+CELL_H-1], outline=(200,200,200))
        names.append(f.name)
    mname = f"m{mi+1:03d}.png"
    canvas.save(OUT / mname)
    mapping[mname] = names

(OUT / "_mapping.json").write_text(json.dumps(mapping), encoding="utf-8")
print(f"wrote {n_mont} montages + _mapping.json to {OUT}")
