#!/usr/bin/env python3
"""Deterministically draw original A4 vector aids, then render their PDFs."""

from __future__ import annotations

import html
import subprocess
from pathlib import Path

HERE = Path(__file__).resolve().parent
BLUE = "#0b5267"
INK = "#182931"
LIGHT = "#f1f7f7"


def t(x: float, y: float, content: str, size: float = 4.2, weight: int = 400,
      anchor: str = "start", fill: str = INK) -> str:
    return (f'<text x="{x}" y="{y}" font-family="DejaVu Sans" font-size="{size}" '
            f'font-weight="{weight}" text-anchor="{anchor}" fill="{fill}">'
            f'{html.escape(content)}</text>')


def rect(x: float, y: float, w: float, h: float, fill: str = "#fff",
         stroke: str = INK, sw: float = .5, rx: float = 0) -> str:
    return f'<rect x="{x}" y="{y}" width="{w}" height="{h}" fill="{fill}" stroke="{stroke}" stroke-width="{sw}" rx="{rx}"/>'


def line(x1: float, y1: float, x2: float, y2: float, stroke: str = INK,
         sw: float = .5) -> str:
    return f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" stroke="{stroke}" stroke-width="{sw}"/>'


def page(title: str, description: str, body: list[str]) -> str:
    return (f'<svg xmlns="http://www.w3.org/2000/svg" width="210mm" height="297mm" '
            f'viewBox="0 0 210 297" role="img" aria-labelledby="title desc">'
            f'<title id="title">{html.escape(title)}</title>'
            f'<desc id="desc">{html.escape(description)}</desc>'
            + rect(0, 0, 210, 297) + "".join(body)
            + '</svg>\n')


def map_a() -> str:
    features = [
        ["reading nook", "art cart", "water point", "quiet table"],
        ["puzzle shelf", "open mat", "handwash", "plant"],
        ["book returns", "build table", "doorway", "help desk"],
        ["coat hooks", "garden tray", "display", "recycling"],
    ]
    a = [t(18, 20, "MAP A · THE MADE-UP SHARED HUB", 6.3, 700, fill=BLUE),
         t(18, 30, "Page top is UP. Move one adjacent square per step; no diagonals.", 3.6),
         t(18, 38, "Columns A–D run left to right. Rows 1–4 run top to bottom.", 3.6),
         t(18, 48, "Place a dot on your start. Trace each move. Mark your finish.", 3.6)]
    x0, y0, cw, ch = 21, 57, 42, 27
    for c, name in enumerate("ABCD"):
        a.append(t(x0 + cw * (c + .5), 54, name, 4.5, 700, "middle", BLUE))
    for r in range(4):
        a.append(t(15, y0 + ch * (r + .55), str(r + 1), 4.5, 700, "middle", BLUE))
        for c in range(4):
            x, y = x0 + cw * c, y0 + ch * r
            a.append(rect(x, y, cw, ch, LIGHT if (r + c) % 2 == 0 else "#fff"))
            a.append(t(x + 2.5, y + 5, f"{chr(65+c)}{r+1}", 3.4, 700, fill=BLUE))
            label = features[r][c].split()
            if len(label) == 1:
                a.append(t(x + cw / 2, y + 17, label[0], 3.25, anchor="middle"))
            else:
                a.append(t(x + cw / 2, y + 14, label[0], 3.15, anchor="middle"))
                a.append(t(x + cw / 2, y + 19.5, " ".join(label[1:]), 3.15, anchor="middle"))
    a.extend([t(18, 178, "MY ROUTE ON A BLANK GRID", 5, 700, fill=BLUE),
              t(18, 185, "Start: ________   Finish: ________   Words/arrows: __________________", 3.5)])
    x0, y0, cw, ch = 21, 197, 42, 20
    for c, name in enumerate("ABCD"):
        a.append(t(x0 + cw * (c + .5), 194, name, 4.2, 700, "middle", BLUE))
    for r in range(4):
        a.append(t(15, y0 + ch * (r + .55), str(r + 1), 4.2, 700, "middle", BLUE))
        for c in range(4):
            a.append(rect(x0 + cw * c, y0 + ch * r, cw, ch))
    a.append(t(18, 286, "Text/tactile version: see TEXT-ALTERNATIVES.md · Original SubjectNest aid · CC BY 4.0", 2.7))
    return page("Map A route grid", "A4 map of 16 fictional hub places in four labelled rows and columns, followed by an empty route grid. Full text alternative is provided separately.", a)


def exchange_mat() -> str:
    a = [t(18, 20, "SAME AMOUNT · DIFFERENT GROUPS", 6.3, 700, fill=BLUE),
         t(18, 30, "Build, sketch or tell your groups. Open a bundle; count everything again.", 3.6),
         t(18, 39, "H = hundreds   T = tens   O = ones", 4.3, 700),
         t(18, 48, "One hundred = ten tens. One ten = ten ones.", 3.7)]
    cols = [(18, "H", "hundreds"), (77, "T", "tens"), (136, "O", "ones")]
    for x, code, word in cols:
        a.append(rect(x, 59, 56, 74, LIGHT))
        a.append(t(x + 28, 69, f"{code} · {word}", 4.1, 700, "middle", BLUE))
    a.extend([t(18, 146, "First grouping:", 4.2, 700),
              t(18, 163, "H _______     T _______     O _______", 4.0),
              line(18, 170, 192, 170),
              t(18, 181, "What did you open?   □ one hundred   □ one ten", 3.8),
              t(18, 195, "New grouping:", 4.2, 700),
              t(18, 212, "H _______     T _______     O _______", 4.0),
              line(18, 219, 192, 219),
              t(18, 233, "Check the same total:", 4.2, 700),
              t(18, 249, "_______ + _______ + _______ = _______", 4.0),
              t(18, 263, "What stayed the same? __________________________________", 3.7),
              t(18, 286, "Text/tactile version: see TEXT-ALTERNATIVES.md · Original SubjectNest aid · CC BY 4.0", 2.7)])
    return page("Hundreds tens ones exchange mat", "A4 worksheet with three labelled empty place-value columns and spaces for first grouping, one exchange, new grouping and total check. Full text alternative is provided separately.", a)


def main() -> None:
    for stem, svg in (("route-grid", map_a()), ("exchange-mat", exchange_mat())):
        svg_path = HERE / f"{stem}.svg"
        pdf_path = HERE / f"{stem}.pdf"
        svg_path.write_text(svg, encoding="utf-8")
        subprocess.run(["rsvg-convert", "-f", "pdf", "-o", str(pdf_path), str(svg_path)], check=True)
        print(f"wrote {svg_path.name} and {pdf_path.name}")


if __name__ == "__main__":
    main()
