"""Generate Week 02 r1 draft drawings and cutter contours. Units: mm.
No machine settings or physical fit is implied. Python standard library only.
"""
import argparse
from pathlib import Path
from html import escape

B = 'M 0,0 H 28 L 40,12 V 22 L 32,30 L 40,38 V 48 L 28,60 H 0 Z M 10,10 H 24 L 30,16 L 24,22 H 10 Z M 10,38 H 24 L 30,44 L 24,50 H 10 Z'

def tile(side, slot, depth):
    a=(side-slot)/2; b=(side+slot)/2; s=side; d=depth
    pts=[(0,0),(a,0),(a,d),(b,d),(b,0),(s,0),(s,a),(s-d,a),(s-d,b),(s,b),(s,s),(b,s),(b,s-d),(a,s-d),(a,s),(0,s),(0,b),(d,b),(d,a),(0,a)]
    return 'M '+' L '.join(f'{x:g},{y:g}' for x,y in pts)+' Z'

def svg(w,h,body,physical=False):
    return f'<svg xmlns="http://www.w3.org/2000/svg" width="{w}{"mm" if physical else ""}" height="{h}{"mm" if physical else ""}" viewBox="0 0 {w} {h}">{body}</svg>\n'

def txt(x,y,s,size=15):return f'<text x="{x}" y="{y}" font-family="Arial,sans-serif" font-size="{size}" fill="#31372f">{escape(s)}</text>'
def line(x1,y1,x2,y2):return f'<path d="M{x1},{y1} L{x2},{y2}" fill="none" stroke="#59674d" stroke-width="1"/>'
def dimh(x1,x2,y,label):
    return line(x1,y,x2,y)+line(x1,y-6,x1,y+6)+line(x2,y-6,x2,y+6)+txt((x1+x2)/2-25,y-9,label)
def dimv(x,y1,y2,label):
    return line(x,y1,x,y2)+line(x-6,y1,x+6,y1)+line(x-6,y2,x+6,y2)+txt(x+9,(y1+y2)/2,label)
def main():
    ap=argparse.ArgumentParser();ap.add_argument('--out',type=Path,default=Path(__file__).parent/'exports');ap.add_argument('--side',type=float,default=60);ap.add_argument('--thickness',type=float,default=3);ap.add_argument('--clearance',type=float,default=0);ap.add_argument('--kerf',type=float,default=0);ap.add_argument('--depth',type=float,default=15);a=ap.parse_args()
    # Centerline laser paths: retained outside = path span - kerf;
    # removed slot = path gap + kerf. No extra CAM offset should be applied.
    side=a.side+a.kerf;slot=a.thickness+a.clearance-a.kerf
    assert 0<slot<a.depth<a.side/2 and a.kerf>=0
    p=tile(side,slot,a.depth);a.out.mkdir(parents=True,exist_ok=True)
    paths=''.join(f'<path transform="translate({5+c*(side+5):g},{5+r*(side+5):g})" d="{p}"/>' for r in range(2) for c in range(2))
    (a.out/'laser-kit-r1.svg').write_text(svg(2*side+15,2*side+15,f'<g fill="none" stroke="black" stroke-width="0.1">{paths}</g>',True))
    (a.out/'vinyl-b-r1.svg').write_text(svg(50,70,f'<path transform="translate(5,5)" d="{B}" fill="black" fill-rule="evenodd"/>',True))
    # Slot coupon is a single comb contour; left-to-right path widths vary around the nominal slot.
    widths=[slot+x/10 for x in [-3,-2,-1,0,1,2,3]];assert min(widths)>0
    d='M 0,0'
    for i,w in enumerate(widths):
        x=10+12*i;d+=f' H{x:g} V10 H{x+w:g} V0'
    d+=' H94 V25 H0 Z'
    (a.out/'fit-coupon-r1.svg').write_text(svg(104,35,f'<path transform="translate(5,5)" d="{d}" fill="none" stroke="black" stroke-width="0.1"/>',True))
    header=txt(32,38,'LASER KIT / R1 · DESIGN DRAFT',24)+txt(32,65,'One repeated tile · 4 pieces · dimensions in mm · no physical fit test')
    drawing=f'<path transform="translate(85,115) scale(4)" d="{p}" fill="#f2e5cd" stroke="#242821" stroke-width="0.35"/>'
    drawing+=dimh(85,85+4*side,95,f'{side:g}')+dimv(350,115,115+4*side,f'{side:g}')
    drawing+=dimv(225,115,115+a.depth*4,f'{a.depth:g} depth')
    drawing+=line(85+4*side/2,220,430,220)+txt(440,220,f'4 centered slots: {slot:g} wide')
    drawing+=txt(440,250,f'Stock thickness t = {a.thickness:g} (assumed)')+txt(440,279,f'Kerf k = {a.kerf:g} (not measured)')+txt(440,308,f'Fit clearance c = {a.clearance:g} (draft)')
    drawing+=txt(32,410,'Slot centerline gap = t + c − k. Outside path span = target size + k.')+txt(32,438,'Measure stock and kerf; regenerate paths before cutting. Avoid double compensation.')
    drawing+=txt(32,480,'FIT COUPON / left to right, slot path widths: '+', '.join(f'{w:g}' for w in widths),14)
    drawing+=f'<path transform="translate(32,505) scale(4)" d="{d}" fill="#f2e5cd" stroke="#242821" stroke-width="0.35"/>'
    drawing+=txt(440,535,'Coupon outline: 94 × 25')+txt(440,563,'7 slots · depth 10 · pitch 12')+txt(32,644,'Preview parts below use this r1 silhouette. Dimensions come from SVG, not photo pixels.')
    (a.out/'laser-drawing-r1.svg').write_text(svg(820,680,'<rect width="820" height="680" fill="#fafaf6"/>'+header+drawing))
    drawing=txt(32,38,'VINYL DECAL / B-R1 · DESIGN DRAFT',24)+txt(32,65,'One connected black shape · 2 weeded openings · dimensions in mm')
    drawing+=f'<path transform="translate(90,120) scale(6)" d="{B}" fill="#20231f" fill-rule="evenodd"/>'
    drawing+=dimh(90,330,98,'40')+dimv(355,120,480,'60')+dimh(90,150,510,'10 spine')
    drawing+=txt(440,140,'Outer profile: 40 × 60')+txt(440,174,'Two identical 20 × 12 openings')+txt(440,208,'Opening left edge: x = 10')+txt(440,242,'Opening top edges: y = 10, 38')+txt(440,276,'Outer waist tip: (32, 30)')+txt(440,310,'No font required: editable paths')
    drawing+=txt(32,561,'Cut SVG has a 50 × 70 mm page, with the 40 × 60 mm decal centered inside.')+txt(32,590,'Weed outside the silhouette and both openings; transfer the remaining black vinyl.')+txt(32,619,'Verify import dimensions. Blade offset and force are cutter settings, not drawn offsets.')
    (a.out/'vinyl-drawing-r1.svg').write_text(svg(820,650,'<rect width="820" height="650" fill="#fafaf6"/>'+drawing))
    # Geometry-only references for image generation, derived from the same paths.
    refs=''.join(f'<path transform="translate({120+c*350},{80+r*350}) scale(4.5)" d="{p}" fill="#c9ae7c"/>' for r in range(2) for c in range(2))
    (a.out/'laser-reference-r1.svg').write_text(svg(820,760,'<rect width="820" height="760" fill="#ededE8"/>'+refs))
    (a.out/'vinyl-reference-r1.svg').write_text(svg(700,800,'<rect width="700" height="800" fill="#ededE8"/><rect x="110" y="60" width="480" height="680" fill="white"/>'+f'<path transform="translate(190,160) scale(8)" d="{B}" fill="#171917" fill-rule="evenodd"/>'))
if __name__=='__main__':main()
