"""Capture limits of the four complete key assemblies; geometry only, not return force."""
from audit_functional_28 import *

def main():
 M,I=load();results=[]
 for name,ids,hw,actuator in [('Front',[3,10,11],'Front_Switch',2),('PTT',[6,16,17],'PTT_Switch',3),('Volume Up',[7,12,13],'Volume_Up_Switch',3),('Volume Down',[8,14,15],'Volume_Down_Switch',3)]:
  keys=[q for q in I.values() if any(q.name.startswith(f'C27_R2_{i:02d}_') for i in ids)];moving=Item(name,b.Compound(children=[s for q in keys for s in q.solids]),'control')
  A=moving.bb;lo=[A[i]-1.21 for i in [0,2,4]];hi=[A[i]+1.21 for i in [1,3,5]];region=b.Solid.make_box(*(hi[i]-lo[i]for i in range(3)),b.Plane(origin=lo));local=[]
  for q in I.values():
   if q in keys or q.kind=='flexible_route':continue
   if q.name=='C27_R2_REF_'+hw:q=Item(q.name,b.Compound(children=[s for j,s in enumerate(q.solids)if j!=actuator-1]),q.kind)
   if not candidate(q.bb,bbox(region)):continue
   c=norm(q.s.intersect(region))
   if volume(c)>1e-8:local.append(Item(q.name,c,q.kind))
  for axis,sign in [(0,-1),(0,1),(1,-1),(1,1),(2,-1),(2,1)]:
   row={'control':name,'direction':('+'if sign>0 else '-')+'XYZ'[axis],'first_tested_capture_mm':None,'stops':[]}
   for mm in [.1,.25,.5,.8,1.2]:
    t=[0.,0.,0.];t[axis]=sign*mm;k=moving.moved(t)
    for q in local:
     v=overlap(k,q)
     if v>1e-4:row['first_tested_capture_mm']=mm;row['stops'].append({'part':q.name,'overlap_mm3':v});break
    if row['stops']:break
   results.append(row);print('CAPTURE',name,row['direction'],row['first_tested_capture_mm'],flush=True)
 (ROOT/'audit/Concept_28_R1_control_capture.json').write_text(json.dumps({'checks':results,'method':'complete key group translated against actual surrounding parts, fixed switch housing only; moving actuator excluded; clipped local exact geometry','qualification_limit':'Geometric travel bounds, not switch force, return, retention load or permissible overtravel.'},indent=2))
if __name__=='__main__':main()
