"""Reproduce original SVG diagrams and CSV studies with Python standard library.
Run from an empty output folder; no model, engine or media upload is used.
"""
import csv
import math
from pathlib import Path

out = Path.cwd()

def svg(name, title, subtitle, body):
    text = f'''<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="900" viewBox="0 0 1600 900"><rect width="1600" height="900" fill="#0e1625"/><g font-family="sans-serif" fill="#e2e8f0"><text x="80" y="100" font-size="48" font-weight="700">{title}</text><text x="80" y="155" font-size="24" fill="#94a3b8">{subtitle}</text>{body}<text x="80" y="845" font-size="22" fill="#94a3b8">CLOUT ORIGINAL STUDY · SCHEMATIC PLANNING MATERIAL</text></g></svg>'''
    p = out / name
    if p.exists():
        raise FileExistsError(p)
    p.write_text(text)

def csvfile(name, rows):
    with (out / name).open("x", newline="") as f:
        csv.writer(f).writerows(rows)

# Projection signs for cameras looking along +Y and -Y respectively
body = '<rect x="70" y="200" width="700" height="565" rx="24" fill="#182438"/><rect x="820" y="200" width="710" height="565" rx="24" fill="#182438"/>'
body += '<text x="110" y="255" font-size="27">Top view of the same scene</text><path d="M160 490H680" stroke="#fbbf24" stroke-width="4" stroke-dasharray="12 10"/><text x="295" y="535" font-size="20">Action axis A to B</text>'
for x,label,color in [(240,'A','#67e8f9'),(600,'B','#c4b5fd')]:
    body += f'<circle cx="{x}" cy="490" r="42" fill="{color}"/><text x="{x-15}" y="501" font-size="30" fill="#101827">{label}</text>'
body += '<path d="M420 610L385 665H455Z M420 370L385 315H455Z" fill="#fbbf24"/><text x="325" y="710" font-size="23">Near camera</text><text x="330" y="300" font-size="23">Far camera</text>'
for y,label,order in [(330,'Near camera screen', [('A',950,'#67e8f9'),('B',1390,'#c4b5fd')]),(600,'Far camera screen',[('B',950,'#c4b5fd'),('A',1390,'#67e8f9')])]:
    body+=f'<text x="870" y="{y-45}" font-size="27">{label}</text><path d="M900 {y}H1440" stroke="#475569" stroke-width="3"/>'
    for who,x,color in order:body+=f'<circle cx="{x}" cy="{y+55}" r="40" fill="{color}"/><text x="{x-14}" y="{y+65}" font-size="30" fill="#101827">{who}</text>'
svg('screen-direction-study.svg','Screen direction changes with camera side','Same world positions · Opposing screen-right bases · No camera footage',body)
csvfile('screen-direction-shots.csv',[['shot','camera_side','A_screen_position','B_screen_position','A_movement','B_gaze','review'],['01 establish','near','left','right','still','left','confirm desk geography'],['02 approach','near','left toward desk','offscreen right','screen right','not shown','check exit and destination'],['03 response','near','offscreen left','right','not shown','screen left','check eyeline and room']])

l1,l2=100,80
a,b=math.radians(20),math.radians(60)
def fk(L1,L2,A,B):return (L1*math.cos(A),L1*math.sin(A),L1*math.cos(A)+L2*math.cos(A+B),L1*math.sin(A)+L2*math.sin(A+B))
src=fk(l1,l2,a,b); copied=fk(140,60,a,b)
x,y=src[2:]; B=math.acos((x*x+y*y-140*140-60*60)/(2*140*60)); A=math.atan2(y,x)-math.atan2(60*math.sin(B),140+60*math.cos(B)); corrected=fk(140,60,A,B)
rows=[['case','upper_length','lower_length','shoulder_degrees','elbow_relative_degrees','elbow_x','elbow_y','hand_x','hand_y']]
body=''
for i,(label,L1,L2,A1,B1,p,color) in enumerate([('Source',100,80,a,b,src,'#67e8f9'),('Target with copied angles',140,60,a,b,copied,'#fbbf24'),('Target with point IK',140,60,A,B,corrected,'#c4b5fd')]):
    ox=105+i*505;oy=660;s=2.35
    body+=f'<rect x="{ox-35}" y="215" width="470" height="530" rx="22" fill="#182438"/><text x="{ox}" y="270" font-size="25">{label}</text><text x="{ox}" y="310" font-size="21">Links {L1} and {L2}</text>'
    ex,ey,hx,hy=p
    body+=f'<path d="M{ox} {oy}L{ox+ex*s} {oy-ey*s}L{ox+hx*s} {oy-hy*s}" fill="none" stroke="{color}" stroke-width="16" stroke-linecap="round"/>'
    for px,py in [(0,0),(ex,ey),(hx,hy)]:body+=f'<circle cx="{ox+px*s}" cy="{oy-py*s}" r="12" fill="#e2e8f0"/>'
    body+=f'<circle cx="{ox+x*s}" cy="{oy-y*s}" r="22" fill="none" stroke="#f87171" stroke-width="3"/><text x="{ox}" y="710" font-size="20">Hand ({hx:.3f}, {hy:.3f})</text>'
    rows.append([label,L1,L2,math.degrees(A1),math.degrees(B1),ex,ey,hx,hy])
svg('animation-retargeting-study.svg','Matching joint angles can miss the contact','A calculated planar reach · Red ring marks the source hand target',body)
csvfile('retargeting-reach-study.csv',rows)
csvfile('retargeting-chain-map.csv',[['chain_function','source_start','source_end','target_start','target_end','reference_pose_difference','contact_goal','review_notes'],['torso','','','','','','',''],['left_arm','','','','','','',''],['right_arm','','','','','','',''],['left_leg','','','','','','',''],['right_leg','','','','','','','']])
body=''
for i,(label,lines,color) in enumerate([('Prepare',['Approved portrait','Recorded speech','Short pilot brief'],'#67e8f9'),('Select',['Lite or Pro weights','Matching script','Recorded revision'],'#c4b5fd'),('Review',['Saved picture and sound','Pause and phrase ending','Timestamped accept or reject'],'#fbbf24')]):
    x=80+i*510
    body+=f'<rect x="{x}" y="280" width="450" height="380" rx="26" fill="#182438" stroke="{color}" stroke-width="2"/><text x="{x+30}" y="350" font-size="34" fill="{color}">{label}</text>'
    for n,line in enumerate(lines):body+=f'<text x="{x+30}" y="{430+n*65}" font-size="23">{line}</text>'
svg('soulx-flashhead-workflow-guide-hero.svg','SoulX FlashHead portrait pilot','Source-based workflow map · No model output or speed benchmark',body)
(out/'flashhead-portrait-pilot.txt').write_text('Original Clout portrait pilot\nUse one approved portrait and one short owned speech recording\nInclude an opening, pause, closed-mouth sound and phrase ending\nRecord repository and checkpoint revisions, mode, hardware and environment\nReview the saved output with sound at normal speed and frame by frame\nLog identity, mouth closure, teeth, background, duration and alignment issues\nNo inference or hardware benchmark is supplied with this planning brief\n')
csvfile('flashhead-review-ledger.csv',[['take','repository_revision','checkpoint_revision','mode','hardware','input_duration','output_duration','elapsed_seconds','timestamp','issue','decision','notes']])
