from PIL import Image
import os

audit_dir = r'C:\allgifted\mathapi11v2\_work_barmodels\audit_r6'

# Test shape detector on known shape images from IDs 139-152
known = {
    'imp1pg035q1_1.png': ('circle', 0),
    'imp1pg035q2_1.png': ('rectangle', 1),
    'imp1pg035q3_1.png': ('triangle', 2),
    'imp1pg035q4_1.png': ('square', 1),
    'imp1pg035q5_1.png': ('triangle', 2),
    'imp1pg035q6.png': ('?', '?'),
    'imp1pg035q7.png': ('rectangle', 1),
    'imp1pg035q8.png': ('triangle', 2),
    'imp1pg035q9.png': ('rectangle', 1),
    'imp1pg035q10.png': ('triangle', 2),
    'imp1pg035q1_2.png': ('triangle', 2),
    'imp1pg035q2_2.png': ('rectangle', 1),
    'imp1pg035q3_2.png': ('rectangle', 1),
    'imp1pg035q4_2.png': ('circle', 0),
}

def shape_features(fpath):
    img = Image.open(fpath)
    w_img, h_img = img.size

    if img.mode == 'RGBA':
        pixels = list(img.getdata())
        opaque = [(i % w_img, i // w_img, r, g, b) for i, (r, g, b, a) in enumerate(pixels) if a > 128]
    else:
        pixels = list(img.getdata())
        opaque = [(i % w_img, i // w_img, r, g, b) for i, (r, g, b) in enumerate(pixels) if (r < 240 or g < 240 or b < 240)]

    if not opaque:
        return {'count': 0}

    xs = [p[0] for p in opaque]
    ys = [p[1] for p in opaque]
    min_x, max_x = min(xs), max(xs)
    min_y, max_y = min(ys), max(ys)
    w = max_x - min_x
    h = max_y - min_y
    aspect = w / h if h > 0 else 0
    cx = (min_x + max_x) / 2
    cy = (min_y + max_y) / 2

    # Corner emptiness
    corner_sz = max(5, min(w, h) // 8)
    corner_regions = [
        (range(min_x, min_x + corner_sz), range(min_y, min_y + corner_sz)),
        (range(max_x - corner_sz, max_x + 1), range(min_y, min_y + corner_sz)),
        (range(min_x, min_x + corner_sz), range(max_y - corner_sz, max_y + 1)),
        (range(max_x - corner_sz, max_x + 1), range(max_y - corner_sz, max_y + 1)),
    ]
    empty_corners = 0
    for xr, yr in corner_regions:
        area = len(xr) * len(yr)
        filled = sum(1 for (x, y, _, _, _) in opaque if x in xr and y in yr)
        if filled / area < 0.2:
            empty_corners += 1

    # Fill ratio of bounding box
    bbox_area = w * h
    fill_ratio = len(opaque) / bbox_area if bbox_area > 0 else 0

    # Symmetry check
    q1 = sum(1 for x, y, _, _, _ in opaque if x >= cx and y >= cy)
    q2 = sum(1 for x, y, _, _, _ in opaque if x < cx and y >= cy)
    q3 = sum(1 for x, y, _, _, _ in opaque if x < cx and y < cy)
    q4 = sum(1 for x, y, _, _, _ in opaque if x >= cx and y < cy)
    total = len(opaque)
    max_q = max(q1, q2, q3, q4) / total
    min_q = min(q1, q2, q3, q4) / total
    sym_diff = max_q - min_q

    return {
        'aspect': aspect,
        'empty_corners': empty_corners,
        'fill_ratio': fill_ratio,
        'sym_diff': sym_diff,
        'w': w, 'h': h
    }

for fname, (expected, ci) in known.items():
    fpath = os.path.join(audit_dir, fname)
    if not os.path.exists(fpath):
        print(f"{fname}: NOT FOUND")
        continue
    feats = shape_features(fpath)
    if 'count' in feats and feats['count'] == 0:
        print(f"{fname}: EMPTY")
        continue
    print(f"{fname}: expected={expected:>12s}  aspect={feats['aspect']:.2f}  corners_empty={feats['empty_corners']}  fill={feats['fill_ratio']:.2f}  sym_diff={feats['sym_diff']:.3f}  bbox={feats['w']}x{feats['h']}")
