#!/usr/bin/env python3
"""Importa l'arte ufficiale Catch Up delle due espansioni in pwa/img/.

Sorgente = assets/official/, dove sono conservati i file come li manda Catch Up.
I nomi sono in ordine di numero di carta, e la corrispondenza e' questa:

  peuple-du-dessous/regions/      01..09 -> regioni  0, 69..76
  peuple-du-dessous/sanctuaries/  01..08 -> santuari S45..S52
  sous-un-ciel-detoiles/meteore/  01..15 -> meteore  M4..M38

Gli originali hanno gli ANGOLI ARROTONDATI incisi su fondo bianco (4,8% sulle
Regioni, 7,7% sui Santuari). Vanno squadrati: la card e' gia' arrotondata dal
CSS con un raggio FISSO, quindi un raggio inciso che scala con la larghezza
lascia uscire una lunetta bianca appena la carta si fa piu' grande. Riempiamo
gli angoli con inpaint (l'area e' minuscola, il bordo carta e' quasi uniforme).

Uso:  /usr/bin/python3 recognition/import_official_art.py [--src DIR] [--dry]
"""
import os, sys, argparse, cv2, numpy as np

HERE = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.dirname(HERE)
IMG = os.path.join(ROOT, "pwa", "img")
SRC_DEFAULT = os.path.join(ROOT, "assets", "official")

REG_SIZE = (520, 520)          # come le 68 Regioni base
SAN_SIZE = (360, 556)          # 44x68mm -> stesso rapporto delle carte vere

# ordine dei file -> carta di destinazione (verificato leggendo i numeri stampati)
PFB_REGIONS   = [0, 69, 70, 71, 72, 73, 74, 75, 76]
PFB_SANCT     = ["S45", "S46", "S47", "S48", "S49", "S50", "S51", "S52"]
METEORS       = [4, 5, 7, 9, 11, 13, 15, 20, 21, 26, 27, 29, 32, 33, 38]


def squadra(im, thr=238):
    """Riempie gli angoli bianchi incisi, lasciando l'immagine perfettamente quadra."""
    h, w = im.shape[:2]
    white = (im.min(axis=2) >= thr)
    # solo il bianco ATTACCATO ai 4 angoli: il bianco dentro l'illustrazione resta
    mask = np.zeros((h + 2, w + 2), np.uint8)
    keep = np.zeros((h, w), np.uint8)
    for sy, sx in ((0, 0), (0, w - 1), (h - 1, 0), (h - 1, w - 1)):
        if not white[sy, sx]:
            continue
        ff = np.zeros((h, w), np.uint8)
        ff[white] = 255
        m = np.zeros((h + 2, w + 2), np.uint8)
        cv2.floodFill(ff, m, (sx, sy), 128)
        keep[ff == 128] = 255
    if not keep.any():
        return im, 0
    out = cv2.inpaint(im, cv2.dilate(keep, np.ones((3, 3), np.uint8)), 5, cv2.INPAINT_TELEA)
    return out, int(keep.sum() // 255)


def conv(src, dst, size, dry):
    im = cv2.imread(src)
    if im is None:
        raise SystemExit("illeggibile: " + src)
    im, npix = squadra(im)
    im = cv2.resize(im, size, interpolation=cv2.INTER_AREA)
    if not dry:
        cv2.imwrite(dst, im, [cv2.IMWRITE_JPEG_QUALITY, 88])
    print("  %-46s -> %-28s angoli:%6d px" % (os.path.basename(src), os.path.basename(dst), npix))


def group(srcdir, names, outdir, size, ext, dry):
    files = sorted(f for f in os.listdir(srcdir) if f.lower().endswith(".jpg"))
    if len(files) != len(names):
        raise SystemExit("attesi %d file in %s, trovati %d" % (len(names), srcdir, len(files)))
    for f, n in zip(files, names):
        conv(os.path.join(srcdir, f), os.path.join(outdir, "%s%s" % (n, ext)), size, dry)


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--src", default=SRC_DEFAULT)
    ap.add_argument("--dry", action="store_true")
    a = ap.parse_args()
    pfb = os.path.join(a.src, "peuple-du-dessous")
    usk = os.path.join(a.src, "sous-un-ciel-detoiles")

    print("Regioni People From Below:")
    group(os.path.join(pfb, "regions"), PFB_REGIONS,
          os.path.join(IMG, "regions"), REG_SIZE, ".jpg", a.dry)
    print("Santuari People From Below (sostituiscono le foto):")
    group(os.path.join(pfb, "sanctuaries"), PFB_SANCT,
          os.path.join(IMG, "sanctuaries"), SAN_SIZE, ".jpg", a.dry)
    print("Meteore Under Starry Skies:")
    group(os.path.join(usk, "meteore"), ["M%d" % n for n in METEORS],
          os.path.join(IMG, "regions"), REG_SIZE, ".jpg", a.dry)
    print("fatto." + (" (dry run, niente scritto)" if a.dry else ""))


if __name__ == "__main__":
    main()
