"""Top-down placement SVG v2: OV5640 module per drawing, board moved to Y120-218, pogo-pin charging, no Qi."""
S = 1.4
TOP = 56
PANELS = {"A": 30, "B": 330}


def px(panel, x, y):
    return PANELS[panel] + (x + 60) * S, TOP + (220 - y) * S


def rect(panel, x0, x1, y0, y1, cls, rx=0):
    ax, ay = px(panel, x0, y1)
    bx, by = px(panel, x1, y0)
    return f'<rect x="{ax:.1f}" y="{ay:.1f}" width="{bx-ax:.1f}" height="{by-ay:.1f}" rx="{rx}" class="{cls}"/>'


def circ(panel, x, y, r_mm, cls):
    cx, cy = px(panel, x, y)
    return f'<circle cx="{cx:.1f}" cy="{cy:.1f}" r="{r_mm*S:.1f}" class="{cls}"/>'


def screw(panel, x, y):
    cx, cy = px(panel, x, y)
    return f'<circle cx="{cx:.1f}" cy="{cy:.1f}" r="2.6" class="p-screw"/>'


def badge(panel, x, y, n):
    cx, cy = px(panel, x, y)
    return (f'<circle cx="{cx:.1f}" cy="{cy:.1f}" r="8" class="p-badge"/>'
            f'<text x="{cx:.1f}" y="{cy+3.8:.1f}" class="p-num" text-anchor="middle">{n}</text>')


def line(panel, pts, cls):
    d = " ".join(("M" if i == 0 else "L") + "%.1f %.1f" % px(panel, *p) for i, p in enumerate(pts))
    return f'<path d="{d}" class="{cls}"/>'


o = []
for p, title in (("A", "电子舱盖 · 俯视（高 112–126 mm）"), ("B", "托盘层与底部 · 俯视（高 0–30 mm）")):
    x0, y0 = px(p, -60, 220)
    o.append(f'<text x="{x0:.1f}" y="22" class="d-t">{title}</text>')
    o.append(f'<text x="{x0+84:.1f}" y="{y0-6:.1f}" class="d-s" text-anchor="middle">后壁</text>')
    o.append(f'<text x="{x0+84:.1f}" y="{y0+308+18:.1f}" class="d-s" text-anchor="middle">前面板</text>')
    o.append(rect(p, -60, 60, 0, 220, "p-house", 6))

# ---- panel A: lid
o += [
    rect("A", -30, 30, 120, 218, "p-pcb", 3),
    rect("A", 6, 24, 120, 151, "p-mod", 1),
    rect("A", 6, 24, 120, 126, "p-ant"),
    rect("A", -4.5, 4.5, 216, 220, "p-dark"),
    rect("A", -21, -9, 120, 125, "p-conn"),
    rect("A", -16, 16, 79, 99, "p-bracket", 2),
    rect("A", -9.1, 9.1, 82, 96, "p-small"),
    rect("A", -6.5, 6.5, 82.5, 95.5, "p-dark", 1),
    circ("A", 0, 89, 2.6, "p-lens"),
    line("A", [(-3, 96), (-3, 112), (-15, 118), (-15, 120)], "p-fpc"),
    rect("A", 30, 58, 2, 8, "p-small", 1),
]
o += [screw("A", x, y) for x, y in ((-25, 127), (25, 127), (-25, 211), (25, 211), (-13, 89), (13, 89), (-9, 89), (9, 89))]
o.append(line("A", [(-13, 86), (-13, 92)], "p-slot"))
o.append(line("A", [(13, 86), (13, 92)], "p-slot"))
o += [badge("A", -24, 89, 1), badge("A", -14, 170, 2), badge("A", -24, 110, 3),
      badge("A", 14, 214, 4), badge("A", 44, 18, 5)]

# ---- panel B: tray level
o += [
    rect("B", -48, 48, 0, 195, "p-tray", 4),
    rect("B", -40, 40, 6, 172, "p-pocket", 6),
    rect("B", -24, -16, 176, 184, "p-dark"),
    rect("B", 16, 24, 176, 184, "p-dark"),
    rect("B", -55, -52, 4, 210, "p-rail"),
    rect("B", 52, 55, 4, 210, "p-rail"),
    rect("B", 45, 47, 12, 192, "p-rack"),
    circ("B", 46, 14, 3.5, "p-gear"),
    rect("B", -15, 15, 199, 215, "p-lock", 2),
    rect("B", -5, 5, 195, 199, "p-dark"),
    rect("B", 20, 50, 199, 214, "p-small", 2),
    rect("B", -47, -17, 214, 220, "p-dark"),
    line("B", [(-35, 190), (-35, 8)], "p-strip"),
    circ("B", -35, 190, 5.5, "p-spring"),
    rect("B", -38, -32, 5, 11, "p-dark"),
    line("B", [(-58.5, 40), (-58.5, 140)], "p-led"),
    line("B", [(58.5, 40), (58.5, 140)], "p-led"),
    # charging: pogo block (bottom shell) + copper pads (tray underside) + plug at pocket front
    rect("B", 14, 26, 8, 20, "p-conn", 1),
    rect("B", 15.5, 19.5, 9.5, 18.5, "p-small"),
    rect("B", 20.5, 24.5, 9.5, 18.5, "p-small"),
    rect("B", -4, 4, 2, 7, "p-dark", 1),
    line("B", [(4, 4.5), (20, 4.5), (20, 8)], "p-fpc"),
    # fiducials
    rect("B", -49, -43, 67, 73, "p-dark"),
    rect("B", 43, 49, 105, 111, "p-dark"),
]
o += [screw("B", x, y) for x, y in ((-57.5, 30), (-57.5, 105), (-57.5, 180), (57.5, 30), (57.5, 105), (57.5, 180),
                                     (-12, 207), (12, 207), (40, 14), (52, 14), (-35, 8), (16, 22), (24, 22))]
o += [badge("B", -50, 60, 6), badge("B", -20, 30, 7), badge("B", 0, 207, 8), badge("B", -24, 190, 9),
      badge("B", 34, 20, 10), badge("B", 34, 120, 11), badge("B", 30, 32, 12), badge("B", 35, 206, 13),
      badge("B", -46, 84, 14), badge("B", -32, 217, 15), badge("B", 50, 150, 16), badge("B", -12, 6, 17)]

svg = ('<svg viewBox="0 0 530 395" role="img" aria-label="零件位置俯视图，编号对应下表">'
       + "".join(o) + "</svg>")
open("/tmp/claude-0/plan2.svg", "w").write(svg)
print(len(svg))
