#!/usr/bin/env python3
"""Generate original A4 SVG/PDF Year 10 mathematics teaching aids."""
import subprocess
from html import escape
from pathlib import Path

P=Path(__file__).resolve().parent
INK='#1d2631'; COBALT='#27476e'; TEAL='#086b63'; GOLD='#965420'; PALE='#f7f8f5'

def t(x,y,s,size=18,weight=400,color=INK):
 return f'<text x="{x}" y="{y}" fill="{color}" font-family="DejaVu Sans" font-size="{size}" font-weight="{weight}">{escape(str(s))}</text>'
def line(x,y,X,Y,color=COBALT,w=2):
 return f'<line x1="{x}" y1="{y}" x2="{X}" y2="{Y}" stroke="{color}" stroke-width="{w}"/>'
def box(x,y,w,h,color=COBALT,fill='white'):
 return f'<rect x="{x}" y="{y}" width="{w}" height="{h}" rx="10" fill="{fill}" stroke="{color}" stroke-width="2"/>'
def page(title,subtitle,desc,body):
 return '\n'.join(['<svg xmlns="http://www.w3.org/2000/svg" width="210mm" height="297mm" viewBox="0 0 794 1123" role="img" aria-labelledby="ttl dsc">',f'<title id="ttl">{escape(title)}</title><desc id="dsc">{escape(desc)}</desc>',box(0,0,794,1123,PALE,PALE),box(36,34,722,9,TEAL,TEAL),t(42,93,title,29,700,COBALT),t(42,126,subtitle,16),body,line(42,1060,750,1060,'#b5c2c5',1),t(42,1088,'SubjectNest · Year 10 · invented data · A4',13,400,COBALT),'</svg>'])
def emit(name,title,subtitle,desc,body):
 src=P/(name+'.svg');src.write_text(page(title,subtitle,desc,body),encoding='utf8')
 subprocess.run(['rsvg-convert','-f','pdf','-o',str(P/(name+'.pdf')),str(src)],check=True)

# Coordinate frame with clear numeric/tactile conversion.
b=[box(70,167,650,775)]
x0,y0,x1,y1=142,840,674,250
for n in range(6):
 x=x0+n*(x1-x0)/5
 b += [line(x,y0,x,y1,'#d0dad7',1),t(x-5,y0+33,n,16,700,COBALT)]
for n in range(0,26,5):
 y=y0-n*(y0-y1)/25
 b += [line(x0,y,x1,y,'#d0dad7',1),t(97,y+5,n,16,700,COBALT)]
b += [line(x0,y0,x1+12,y0,COBALT,3),line(x0,y0,x0,y1-13,COBALT,3),t(290,906,'Number of rooms (0–5)',17,700,COBALT),t(83,210,'Clue icons (0–25)',17,700,COBALT),t(96,982,'Two drafts may share the same x. Label each point and name the source.',16)]
emit('scatterplot-frame','GAME-MAP SCATTERPLOT','Source G · nine fictional drafts · rooms against clue icons','Blank high-contrast graph: horizontal room axis zero to five, vertical clue-icon axis zero to 25 in fives; no data points plotted.','\n'.join(b))

b=[box(44,169,706,770),t(60,210,'Draft',16,700),t(155,210,'Rooms x',16,700),t(275,210,'Listed y',16,700),t(405,210,'M(x)=3x+2',16,700),t(604,210,'y − M(x)',16,700)]
for i,(letter,x,y) in enumerate(zip('ABCDEFGHI',[1,1,2,2,3,3,4,4,5],[5,6,8,9,11,12,14,15,22])):
 yy=270+i*69
 b += [line(60,yy+19,734,yy+19,'#b5c2c5',1),t(65,yy,letter,18,700,TEAL),t(165,yy,x,18),t(290,yy,y,18),t(420,yy,'________',18),t(622,yy,'_____',18)]
b += [t(65,996,'A residual is a numerical difference, not an explanation of its cause.',15,700,GOLD)]
emit('residual-ruler','RESIDUAL RULER','Complete model and signed gap for each invented draft. Units: clue icons.','Nine-row table A to I with rooms and listed clue-icon values; model and residual columns blank.','\n'.join(b))

b=[box(44,169,706,680),t(57,219,'Theme label',17,700),t(291,219,'Two-sided',17,700),t(447,219,'One-sided',17,700),t(625,219,'Total',17,700)]
for i,row in enumerate(['Puzzle','Story','No theme assigned','All designs']):
 y=320+i*132
 b += [line(54,y+31,736,y+31,'#b5c2c5',1),t(62,y,row,19,700,TEAL if i==2 else COBALT),t(309,y,'____',18),t(465,y,'____',18),t(637,y,'____',18)]
b += [box(44,878,706,143,GOLD),t(61,921,'Check every margin twice:',19,700,GOLD),t(61,963,'row totals → grand total   and   column totals → grand total',15)]
emit('two-way-grid','TWO-WAY TABLE','Source C · 50 fictional designs · fill the cells and margins.','Blank four-row table with Puzzle, Story, No theme assigned and All designs; two-sided, one-sided and total headings.','\n'.join(b))

b=[box(44,167,706,180,COBALT),t(62,211,'CLAIM + SOURCE',21,700,COBALT),t(62,257,'Who counted what? Which exact words overreach?',16),box(44,367,706,175,TEAL),t(62,411,'REFERENCE GROUP',21,700,TEAL),t(62,457,'Numerator ____  of denominator ____  given ____',16),box(44,563,706,177,GOLD),t(62,607,'EXCLUDED OR UNASSIGNED',21,700,GOLD),t(62,653,'What still has a known second-variable value?',16),box(44,762,706,184,COBALT),t(62,806,'REPAIR + LIMIT',21,700,COBALT),t(62,854,'Write a scoped replacement and a missing method detail.',16)]
emit('claim-audit','CATEGORY CLAIM AUDIT','Keep the denominator and any unassigned row in view.','Four large numbered-style panels: claim and source, reference group, excluded or unassigned, repair and limit.','\n'.join(b))
