"""Measures each voice's head on its drawing, as fractions of figure height: the cream of the head filled out from around its
screen (as visors.py finds it) up to the ink around it, its width and its height (chin to the top of the head, or to the hat's
brim where a hat covers it). Writes .scratch/heads_mask.png to check the fill."""
from collections import deque

import numpy as np
from PIL import Image

from visors import out as SCREENS

shown = []


def measure(voice):
    drawing = np.asarray(Image.open(f"toon-preview/rest/{voice}.png").convert("RGBA")).astype(int)
    H, W = drawing.shape[:2]
    cell = drawing[..., :3]
    left, up, right, down = SCREENS[voice][3]
    figure = SCREENS[voice][4]
    reach = right - left
    cream = (cell.sum(-1) > 430) & (drawing[..., 3] > 200)
    near = np.zeros_like(cream)
    near[max(up - reach, 0):down + reach, max(left - reach // 2, 0):right + reach // 2] = True
    cream &= near
    fill = np.zeros_like(cream)
    fill[up:down + 1, left:right + 1] = True
    seeds = [(yy, xx) for yy in range(up, down + 1) for xx in (*range(left - 8, left), *range(right + 1, right + 9))]
    seeds += [(yy, xx) for xx in range(left, right) for yy in (*range(up - 8, up), *range(down + 1, down + 9))]
    queue = deque(p for p in seeds if 0 <= p[0] < H and 0 <= p[1] < W and cream[p])
    for p in queue: fill[p] = True
    while queue:
        yy, xx = queue.popleft()
        for ny, nx in ((yy + 1, xx), (yy - 1, xx), (yy, xx + 1), (yy, xx - 1)):
            if 0 <= ny < H and 0 <= nx < W and cream[ny, nx] and not fill[ny, nx]:
                fill[ny, nx] = True
                queue.append((ny, nx))
    picture = cell.copy()
    picture[fill] = (255, 60, 60)
    shown.append(Image.fromarray(picture.astype(np.uint8)).resize((256, 256)))
    ys, xs = np.nonzero(fill)
    return round((xs.max() - xs.min()) / figure, 3), round((ys.max() - ys.min()) / figure, 3)


print()
for voice in SCREENS:
    w, h = measure(voice)
    print(f"{voice:9} head width {w}, height {h}, {w / h:.2f} wide to tall")
sheet = Image.new("RGB", (256 * len(shown), 256))
for k, each in enumerate(shown): sheet.paste(each, (256 * k, 0))
sheet.save(".scratch/heads_mask.png")
