"""Build a rebake2 plan: one or two tracked segments, crossfaded, with softness measured on the face above the print."""
import cv2,numpy as np,json,sys
cfg=json.loads(sys.argv[1]); d=cfg['dir']
def traj(seg):
    T=json.load(open(seg['track'])); ax,ay=seg['anchor']; out={}
    for k,M in T.items():
        k=int(k)
        if not(seg['range'][0]<=k<=seg['range'][1]): continue
        M=np.array(M); c=M@[ax,ay,1]; out[k]=[c[0],c[1],float(np.sqrt(abs(np.linalg.det(M[:2,:2])))),float(np.arctan2(M[1,0],M[0,0]))]
    ks=sorted(out); A=np.array([out[k] for k in ks])
    def g(x,sig):
        r=int(3*sig); w=np.exp(-np.arange(-r,r+1)**2/(2*sig*sig)); return np.convolve(np.pad(x,(r,r),mode='edge'),w/w.sum(),'valid')
    A[:,0]=g(A[:,0],1.0); A[:,1]=g(A[:,1],1.0); A[:,2]=np.exp(g(np.log(A[:,2]),3.0)); A[:,3]=g(A[:,3],4.0)*seg.get('rot',0.3)
    return {k:A[j] for j,k in enumerate(ks)}
segs=[traj(s) for s in cfg['segs']]
def wt(si,i):
    f=cfg.get('fade')
    if not f or len(segs)==1: return 1.0
    a0,a1,b0,b1=f   # seg0 fades out a0->a1, seg1 fades in b0->b1
    return float(np.clip((a1-i)/(a1-a0),0,1)) if si==0 else float(np.clip((i-b0)/(b1-b0),0,1))
plan={}
frames=sorted(set().union(*[set(s) for s in segs]))
for i in frames:
    pr=[]
    for si,s in enumerate(segs):
        if i in s:
            w=wt(si,i)
            if w>0: pr.append([*map(float,s[i]),cfg['segs'][si]['width'],w])
    if not pr: continue
    pr.sort(key=lambda p:-p[5]); si=[k for k,s in enumerate(segs) if i in s and np.allclose(s[i][:2],pr[0][:2])][0]
    sg=cfg['segs'][si]; ink=sg['ink']
    sat=True
    for f0,f1,span,st in sg.get('ink_over',[]):
        if f0<=i<=f1: ink=span; sat=st
    plan[i]={'prints':pr,'box':sg['box'],'ink':ink,'grey':sg.get('grey',True),'sat':sat}
# softness from the face above the print
ks=sorted(plan); lv=[]
for i in ks:
    x,y,s=plan[i]['prints'][0][:3]; gy=cv2.cvtColor(cv2.imread(f'{d}/f{i:03d}.png'),cv2.COLOR_BGR2GRAY).astype(np.float32)
    roi=gy[max(0,int(y-170*s)):max(1,int(y-45*s)), max(0,int(x-90*s)):int(x+90*s)]
    lv.append(np.log10(max(cv2.Laplacian(roi,cv2.CV_32F).var(),1.0)) if roi.size>100 else 2.5)
w=np.exp(-np.arange(-6,7)**2/8.0); lv=np.convolve(np.pad(np.array(lv),6,mode='edge'),w/w.sum(),'valid')
for i,v in zip(ks,lv): plan[i]['sigma']=0.5+2.2*plan[i]['prints'][0][2]*float(np.clip((2.2-v)/1.6,0,1))
json.dump({str(k):v for k,v in plan.items()},open(cfg['out'],'w'))
for i in ks[::10]: print(i,[[round(v,2) for v in p] for p in plan[i]['prints']],round(plan[i]['sigma'],2))
