"""Measures each visor on the overlay sheet, render (column 0) against drawing (column 1): its width and height and the cheek
beside it on each side, as fractions of the figure's height."""
import sys
from collections import deque
from PIL import Image
im = Image.open(sys.argv[1]).convert("RGB")
px = im.load()
BG = (0xee, 0xee, 0xf4)
bg = lambda p: sum(abs(a - b) for a, b in zip(p, BG)) < 30
def measure(x0, y0, voice):
    rows = [y for y in range(512) if any(not bg(px[x0 + x, y0 + y]) for x in range(0, 512, 2))]
    top, fig = rows[0], rows[-1] - rows[0]
    dark = lambda x, y: sum(px[x0 + x, y0 + y]) < 110
    cream = lambda x, y: 0 <= x < 512 and sum(px[x0 + x, y0 + y]) > 560
    seen, blobs = set(), []
    for y in range(top, top + int(fig * (0.35 if voice == "colleague" else 0.5)), 2):
        for x in range(0, 512, 2):
            if (x, y) in seen or not dark(x, y): continue
            q, pts = deque([(x, y)]), []
            seen.add((x, y))
            while q:
                a, b = q.popleft(); pts.append((a, b))
                for c, d in ((a + 1, b), (a - 1, b), (a, b + 1), (a, b - 1)):
                    if 0 <= c < 512 and top <= d < 512 and (c, d) not in seen and dark(c, d):
                        seen.add((c, d)); q.append((c, d))
            xs, ys = [p[0] for p in pts], [p[1] for p in pts]
            box = (min(xs), min(ys), max(xs), max(ys))
            mid = (box[1] + box[3]) // 2
            ok = voice == "colleague" or (any(cream(box[0] - k, mid) for k in range(2, 30)) and any(cream(box[2] + k, mid) for k in range(2, 30)))
            if len(pts) > 300 and ok and box[3] - box[1] < fig * 0.3: blobs.append((len(pts), box))
    blobs.sort(reverse=True)
    use = [b for _, b in blobs[:2]] if voice == "colleague" else [blobs[0][1]]
    box = (min(b[0] for b in use), min(b[1] for b in use), max(b[2] for b in use), max(b[3] for b in use))
    mid = (box[1] + box[3]) // 2
    left, right = box[0], box[2]
    while left > 0 and not bg(px[x0 + left - 1, y0 + mid]): left -= 1
    while right < 511 and not bg(px[x0 + right + 1, y0 + mid]): right += 1
    f = lambda v: round(v / fig, 3)
    return f(box[2] - box[0]), f(box[3] - box[1]), f(box[0] - left), f(right - box[2])
for r, voice in enumerate(["butler", "coach", "colleague", "homie", "squire"]):
    a, b = measure(0, r * 512, voice), measure(512, r * 512, voice)
    print(f"{voice:9} visor {a[0]}x{a[1]} against {b[0]}x{b[1]}   cheek beside it {a[2]} | {a[3]} against {b[2]} | {b[3]}")
