"""Pictorial wiring view of the UNO Q breakout board (companion to draw_schematic.py)."""
import sys
W,H=2030,1450
o=[]
F='font-family="-apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Arial, sans-serif"'
C=dict(v12="#ff3b30",v5="#ff9500",v33="#30b0c7",gnd="#5f5f63",scl="#af52de",sda="#2f7df6",dhi="#ffd60a",dlo="#34c759",an="#ff5fa2",uart="#a2845e")
def T(x,y,s,size=24,anchor="start",weight="600",c="#fff",op=1):
    s=s.replace('&','&amp;').replace('<','&lt;')
    o.append(f'<text x="{x}" y="{y}" {F} font-size="{size}" text-anchor="{anchor}" font-weight="{weight}" fill="{c}" opacity="{op}">{s}</text>')
def box(x,y,w,h,fill,r=28,stroke=None):
    s=f' stroke="{stroke}" stroke-width="2"' if stroke else ''
    o.append(f'<rect x="{x}" y="{y}" width="{w}" height="{h}" rx="{r}" fill="{fill}"{s}/>')
def wire(x1,y1,x2,y2,c,dash=False,w=7):
    m=(x1+x2)/2; d=' stroke-dasharray="14 10"' if dash else ''
    o.append(f'<path d="M{x1},{y1} C{m},{y1} {m},{y2} {x2},{y2}" fill="none" stroke="{c}" stroke-width="{w}" stroke-linecap="round"{d}/>')
def bus(pts,c,dash=False,w=7,r=26):
    d=f'M{pts[0][0]},{pts[0][1]}'
    for i in range(1,len(pts)-1):
        (x0,y0),(x1,y1),(x2,y2)=pts[i-1],pts[i],pts[i+1]
        def toward(ax,ay,bx,by):
            L=((bx-ax)**2+(by-ay)**2)**.5; k=min(r,L/2)/L; return ax+(bx-ax)*k, ay+(by-ay)*k
        ax,ay=toward(x1,y1,x0,y0); bx,by=toward(x1,y1,x2,y2)
        d+=f' L{ax:.1f},{ay:.1f} Q{x1},{y1} {bx:.1f},{by:.1f}'
    d+=f' L{pts[-1][0]},{pts[-1][1]}'
    ds=' stroke-dasharray="14 10"' if dash else ''
    o.append(f'<path d="{d}" fill="none" stroke="{c}" stroke-width="{w}" stroke-linecap="round" stroke-linejoin="round"{ds}/>')
def dot(x,y,c,ring=None,r=12):
    s=f' stroke="{ring}" stroke-width="3"' if ring else ''
    o.append(f'<circle cx="{x}" cy="{y}" r="{r}" fill="{c}"{s}/>')
def joint(x,y,c): o.append(f'<circle cx="{x}" cy="{y}" r="8" fill="{c}"/>')

o.append(f'<rect width="{W}" height="{H}" fill="#fff"/>')
BLK,INK,CARD,EDGE,MUTE="#1c1c1e","#1d1d1f","#f2f2f7","#c7c7cc","#6e6e73"
Y12,Y5,Y33=28,52,76            # top rails
L12,L5,L33=22,48,74            # left rails
R12,R5,R33,RG=1915,1940,1965,2000   # right rails + ground
GV=730                         # ground riser

# ---- blocks ----
box(100,110,150,220,BLK); T(175,150,'DC jack',22,"middle","700"); T(175,232,'12 V in',16,"middle","400",op=.7)
box(100,372,160,96,CARD,stroke=EDGE); T(190,424,'12 V out',21,"middle","700",INK); T(190,446,'2 sockets',14.5,"middle","400",MUTE)
box(330,372,150,96,BLK,r=18); T(405,430,'12.0',34,"middle","700","#ff453a"); T(405,454,'input voltmeter',13,"middle","400","#fff",.7)
box(470,110,230,220,"#d92d2d"); T(585,150,'DC-DC',27,"middle","700"); T(585,232,'12 V → 5 V buck',17,"middle","400",op=.9)
UX,UY,UW,UH=760,290,480,770
box(UX,UY,UW,UH,BLK,r=36); box(UX+110,UY+70,UW-220,UH-160,"#262628",r=18,stroke="#3a3a3c")
T(UX+UW/2,UY+360,'Arduino',34,"middle","700"); T(UX+UW/2,UY+402,'UNO Q',34,"middle","700")
T(UX+UW/2,UY+436,'under the board',17,"middle","400",op=.65)
box(UX+UW/2-38,UY+UH-112,76,40,"#8e8e93",r=8); T(UX+UW/2,UY+UH-40,'USB-C',17,"middle","400",op=.65)
RX,RW=1500,340; RE2=RX+RW
box(RX,110,RW,240,"#5856d6")
T(RX+140,172,'I²C  × 3',30,"middle","700")
T(RX+22,292,'two 5-pin: ADDR SDA SCL GND VCC',14.5,"start","400",op=.92)
T(RX+22,316,'one 4-pin: SDA SCL GND VCC',14.5,"start","400",op=.92)
box(RX,380,RW,290,CARD,stroke=EDGE)
T(RX+150,508,'Digital',27,"middle","700",INK); T(RX+150,540,'D13 – D8',27,"middle","700",INK); T(RX+150,568,'6 sockets',14.5,"middle","400",MUTE)
box(RX,700,RW,370,CARD,stroke=EDGE)
T(RX+150,868,'Digital',27,"middle","700",INK); T(RX+150,900,'D7 – D0',27,"middle","700",INK); T(RX+150,928,'8 sockets',14.5,"middle","400",MUTE)
box(RX,1120,RW,150,CARD,stroke=EDGE)
T(RX+180,1190,'UART',27,"middle","700",INK); T(RX+180,1218,'1 socket · GND RX TX',14.5,"middle","400",MUTE)
AX,AW=110,330; AE=AX+AW
box(AX,480,AW,430,CARD,stroke=EDGE)
T(AX+185,690,'Analog',27,"middle","700",INK); T(AX+185,722,'A0 – A5',27,"middle","700",INK); T(AX+185,750,'6 sockets',14.5,"middle","400",MUTE)

# ---- supply rails ----
bus([(L12,560),(L12,Y12),(R12,Y12),(R12,800)],C['v12'])
bus([(L5,594),(L5,Y5),(R5,Y5),(R5,834)],C['v5'])
bus([(L33,628),(L33,Y33),(R33,Y33),(R33,868)],C['v33'])
T(1330,20,'12 V',14,"middle","700","#c0271e"); T(1400,46,'5 V',14,"middle","700","#b36b00"); T(1470,70,'3.3 V',14,"middle","700","#1f7f92")
# sources
wire(250,180,470,180,C['v12']); bus([(430,180),(430,Y12)],C['v12'])                 # jack → diode → switch → 12 V
bus([(430,180),(430,372)],C['v12'],w=5)                                             # voltmeter +
bus([(700,180),(720,180),(720,Y5)],C['v5'])                                         # DC-DC out → 5 V
bus([(900,UY),(900,Y33)],C['v33'])                                                  # UNO Q 3V3 → 3.3 V
bus([(840,UY),(840,Y12)],C['v12'])                                                  # 12 V → VIN
bus([(L12,410),(100,410)],C['v12'])                                                 # 12 V out sockets
# ground
wire(250,270,470,270,C['gnd']); bus([(380,270),(380,372)],C['gnd'],w=5)
bus([(260,440),(290,440),(290,270)],C['gnd'])
bus([(700,270),(GV,270),(GV,1345),(RG,1345),(RG,270)],C['gnd'])
wire(UX,440,GV,440,C['gnd']); wire(AE,870,GV,870,C['gnd'])
T(1100,1375,'GND  (common)',15,"middle","600","#48484a")
# diode + switch on the 12 V input
o.append('<rect x="268" y="163" width="46" height="34" rx="8" fill="#1c1c1e"/><rect x="298" y="163" width="7" height="34" fill="#d1d1d6"/>')
T(291,152,'diode',15,"middle","600",MUTE)
o.append('<rect x="336" y="160" width="70" height="40" rx="20" fill="#d1d1d6" stroke="#8e8e93" stroke-width="2"/><circle cx="386" cy="180" r="13" fill="#fff" stroke="#8e8e93" stroke-width="2"/>')
T(371,152,'switch',15,"middle","600",MUTE)
# selector taps
sel=[(RE2,150,'R'),(RE2,430,'R'),(RE2,800,'R'),(AX,560,'L')]
for x,y,side in sel:
    for k,(c,rx,lx) in enumerate([('v12',R12,L12),('v5',R5,L5),('v33',R33,L33)]):
        yy=y+34*k; bx=rx if side=='R' else lx
        wire(x,yy,bx,yy,C[c],w=6); joint(bx,yy,C[c])
for y in (270,550,920,1160): wire(RE2,y,RG,y,C['gnd']); joint(RG,y,C['gnd'])
for p,c in [((430,180),'v12'),((430,Y12),'v12'),((720,Y5),'v5'),((900,Y33),'v33'),((840,Y12),'v12'),((L12,410),'v12'),
            ((380,270),'gnd'),((290,270),'gnd'),((GV,440),'gnd'),((GV,870),'gnd')]: joint(*p,C[c])

# ---- signals ----
RE=UX+UW
wire(RE,340,RX,150,C['scl']); wire(RE,380,RX,200,C['sda'])
dhi=[(13-i,450+i*40,420+i*40) for i in range(6)]
dlo=[(7-i,720+i*40,740+i*40) for i in range(8)]
for d,y1,y2 in dhi: wire(RE,y1,RX,y2,C['dhi'])
for d,y1,y2 in dlo: wire(RE,y1,RX,y2,C['dlo'])
wire(RE,1000,RX,1185,C['uart'],w=6); wire(RE,960,RX,1230,C['uart'],w=6)
an=[(i,540+i*60) for i in range(6)]
for i,y in an: wire(AE,y,UX,y,C['an'])

# ---- dots + labels ----
for y,c,l in [(180,'v12','+'),(270,'gnd','−')]: dot(250,y,C[c],"#fff"); T(230,y+8,l,24,"end","700")
dot(100,410,C['v12']); T(120,398,'V+',14,weight="700",c=INK); dot(260,440,C['gnd']); T(244,400,'GND',13,"end","700",INK)
dot(430,372,C['v12'],r=9); dot(380,372,C['gnd'],r=9)
for y,c,l in [(180,'v12','IN+'),(270,'gnd','IN−')]: dot(470,y,C[c],"#fff"); T(490,y+7,l,19,weight="700")
for y,c,l in [(180,'v5','OUT+'),(270,'gnd','OUT−')]: dot(700,y,C[c],"#fff"); T(680,y+7,l,19,"end","700")
dot(840,UY,C['v12']); T(840,UY+38,'VIN',19,"middle","700"); dot(900,UY,C['v33']); T(900,UY+38,'3V3',19,"middle","700")
dot(UX,440,C['gnd']); T(UX+24,447,'GND',21,weight="700")
for i,y in an:
    dot(UX,y,C['an']); T(UX+24,y+7,f'A{i}',21,weight="700"); dot(AE,y,C['an']); T(AE-22,y+7,f'A{i}',19,"end","700",INK)
dot(AE,870,C['gnd']); T(AE-22,877,'GND',19,"end","700",INK)
for y,c,l in [(340,'scl','SCL'),(380,'sda','SDA')]: dot(RE,y,C[c]); T(RE-24,y+7,l,21,"end","700")
for d,y1,y2 in dhi:
    dot(RE,y1,C['dhi']); T(RE-24,y1+7,f'D{d}',21,"end","700"); dot(RX,y2,C['dhi']); T(RX+22,y2+7,f'D{d}',19,weight="700",c=INK)
for d,y1,y2 in dlo:
    dot(RE,y1,C['dlo']); T(RE-24,y1+7,f'D{d}',21,"end","700"); dot(RX,y2,C['dlo']); T(RX+22,y2+7,f'D{d}',19,weight="700",c=INK)
for y,c,l in [(150,'scl','SCL'),(200,'sda','SDA')]: dot(RX,y,C[c],"#fff"); T(RX+22,y+7,l,19,weight="700")
for x,y,side in sel:
    onblk = (y==150); ring="#fff" if onblk else None; tc="#fff" if onblk else INK
    for k,(c,l) in enumerate([('v12','12 V'),('v5','5 V'),('v33','3.3 V')]):
        yy=y+34*k; dot(x,yy,C[c],ring,r=11)
        if side=='R': T(x-22,yy+6,l,17,"end","700",tc)
        else: T(x+22,yy+6,l,17,"start","700",tc)
    if side=='R': T(x-22,y-22,'VCC jumper',13,"end","400",tc,.7)
    else: T(x+22,y-22,'VCC jumper',13,"start","400",tc,.7)
dot(RE2,270,C['gnd'],"#fff"); T(RE2-22,277,'GND',19,"end","700")
for y in (550,920,1160): dot(RE2,y,C['gnd']); T(RE2-22,y+7,'GND',19,"end","700",INK)
dot(RX,1185,C['uart']); T(RX+22,1192,'RX',19,weight="700",c=INK); dot(RX,1230,C['uart']); T(RX+22,1237,'TX',19,weight="700",c=INK)

# ---- legend ----
x=40; y=1422
for c,l in [('v12','12 V'),('v5','5 V'),('v33','3.3 V'),('gnd','GND'),('scl','SCL'),('sda','SDA'),('dhi','D13–D8'),('dlo','D7–D0'),('an','A0–A5'),('uart','UART')]:
    o.append(f'<line x1="{x}" y1="{y-7}" x2="{x+34}" y2="{y-7}" stroke="{C[c]}" stroke-width="6" stroke-linecap="round"/>')
    T(x+46,y,l,20,weight="400",c="#48484a"); x+=46+len(l)*11.5+34
T(W-40,y,'VCC jumper: one per socket, picks 12 V, 5 V or 3.3 V',20,"end","400","#48484a")
open(sys.argv[1],'w').write(f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" width="{W}" height="{H}">'+''.join(o)+'</svg>')
