#!/usr/bin/env python3
"""Rebuild an explicitly approximate, source-bounded redraw of TM-87740 Fig. 24."""
from html import escape
from pathlib import Path
import csv
import json

ROOT = Path(__file__).resolve().parent
METHODS = json.loads((ROOT / "tm87740-figure24-methods.json").read_text(encoding="utf-8"))
RECORDS = METHODS["records"]
COLORS = {
    "Measured heat shield": "#ec4ab4",
    "Measured structural panel": "#41cae8",
    "Predicted heat-shield temperature": "#ffd16a",
    "Predicted panel temperature": "#9aafff",
    "Unprotected-panel response": "#ff927e",
}

with (ROOT / "tm87740-figure24-digitized.csv").open("w", newline="", encoding="utf-8") as stream:
    writer = csv.writer(stream)
    writer.writerow(["series", "kind", "time_s_approx", "temperature_degF_approx", "time_reading_allowance_s", "temperature_reading_allowance_degF", "source_figure", "classification"])
    for record in RECORDS:
        for time_s, temp_f in record["values_source_decimal"]:
            writer.writerow([record["series"], record["kind"], time_s, temp_f,
                             METHODS["analyst_reading_allowance"]["time_seconds"],
                             METHODS["analyst_reading_allowance"]["temperature_degrees_fahrenheit"],
                             "NASA TM-87740 Fig. 24, PDF p. 50 / printed p. 49",
                             "approximate visual graph reading; not raw or tabulated data"])

def svg(mobile=False):
    if mobile:
        width, height = 430, 980
        left, right, top, bottom = 76, 22, 98, 670
        font, tick_font, label_font = 15, 14, 17
    else:
        width, height = 1120, 780
        left, right, top, bottom = 105, 38, 86, 515
        font, tick_font, label_font = 18, 15, 20
    plot_w, plot_h = width-left-right, bottom-top
    x=lambda t: left + t/400*plot_w
    y=lambda v: bottom - v/1800*plot_h
    desc=("Approximate redraw of NASA TM-87740 Figure 24. Open circles and squares are approximate visual readings of the reported measured average heat-shield and structural-panel temperatures. Solid colored curves redraw the labeled one-dimensional predictions; the dashed coral curve is the calculated unprotected-panel response. The source provides no numeric table or instrument uncertainty. Analyst reading allowances are plus or minus 5 seconds and 30 degrees Fahrenheit, not NASA uncertainties. This ground-test thermal case is separate from X-43A flight data.")
    p=[f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {width} {height}" role="img" aria-labelledby="title desc">',
       '<title id="title">Approximate graph readings: NASA TM-87740 Figure 24</title>',
       f'<desc id="desc">{escape(desc)}</desc>',
       '<rect width="100%" height="100%" rx="18" fill="#08172d"/>',
       f'<text x="{left}" y="34" fill="#f2f6ff" font-family="Arial,sans-serif" font-size="{label_font}" font-weight="700">Cooling-loss abort heating · ground test</text>']
    for temp in range(0,1801,200):
        yy=y(temp)
        p += [f'<line x1="{left}" y1="{yy:.1f}" x2="{width-right}" y2="{yy:.1f}" stroke="#334563" stroke-width="1"/>',
              f'<text x="{left-9}" y="{yy+5:.1f}" text-anchor="end" fill="#dce8fa" font-family="Arial,sans-serif" font-size="{tick_font}">{temp}</text>']
    for time in range(0,401,50 if mobile else 100):
        xx=x(time)
        p += [f'<line x1="{xx:.1f}" y1="{top}" x2="{xx:.1f}" y2="{bottom}" stroke="#263955" stroke-width="1"/>',
              f'<text x="{xx:.1f}" y="{bottom+23}" text-anchor="middle" fill="#dce8fa" font-family="Arial,sans-serif" font-size="{tick_font}">{time}</text>']
    p += [f'<path d="M {left} {top} V {bottom} H {width-right}" fill="none" stroke="#eaf1ff" stroke-width="2"/>',
          f'<text x="{width/2}" y="{bottom+53}" text-anchor="middle" fill="#f2f6ff" font-family="Arial,sans-serif" font-size="{label_font}">Time (seconds)</text>',
          f'<text transform="translate({20 if mobile else 27} {top+plot_h/2}) rotate(-90)" text-anchor="middle" fill="#f2f6ff" font-family="Arial,sans-serif" font-size="{label_font}">Temperature (°F)</text>']
    if mobile:
        legend_y=bottom+106; row_gap=27; legend_x=24
    else:
        legend_y=bottom+97; row_gap=25; legend_x=left
    for idx, rec in enumerate(RECORDS):
        color=COLORS[rec["series"]]
        values=rec["values_source_decimal"]
        if rec["kind"] == "calculated_curve":
            coords=" ".join(f'{x(t):.1f},{y(v):.1f}' for t,v in values)
            dash=' stroke-dasharray="9 7"' if rec["symbol"] == "dashed line" else ''
            p.append(f'<polyline points="{coords}" fill="none" stroke="{color}" stroke-width="4" stroke-linejoin="round"{dash}/>')
        else:
            for t,v in values:
                if rec["symbol"] == "open circle":
                    p.append(f'<circle cx="{x(t):.1f}" cy="{y(v):.1f}" r="6.5" fill="#08172d" stroke="{color}" stroke-width="3"/>')
                else:
                    p.append(f'<rect x="{x(t)-6:.1f}" y="{y(v)-6:.1f}" width="12" height="12" rx="1" fill="#08172d" stroke="{color}" stroke-width="3"/>')
        ly=legend_y+idx*row_gap
        if rec["kind"] == "measured_marker":
            if rec["symbol"] == "open circle": p.append(f'<circle cx="{legend_x+7}" cy="{ly-5}" r="5" fill="#08172d" stroke="{color}" stroke-width="2.5"/>')
            else: p.append(f'<rect x="{legend_x+2}" y="{ly-10}" width="10" height="10" fill="#08172d" stroke="{color}" stroke-width="2.5"/>')
        else:
            dash=' stroke-dasharray="6 5"' if rec["symbol"] == "dashed line" else ''
            p.append(f'<line x1="{legend_x}" y1="{ly-5}" x2="{legend_x+26}" y2="{ly-5}" stroke="{color}" stroke-width="3"{dash}/>')
        p.append(f'<text x="{legend_x+36}" y="{ly}" fill="#f2f6ff" font-family="Arial,sans-serif" font-size="{font}">{escape(rec["series"])}</text>')
    if mobile:
        p.append(f'<text x="24" y="{height-40}" fill="#f3b560" font-family="Arial,sans-serif" font-size="{tick_font}">Approximate graph readings</text>')
        p.append(f'<text x="24" y="{height-18}" fill="#f3b560" font-family="Arial,sans-serif" font-size="{tick_font}">Analyst allowance ±5 s / ±30 °F; not NASA uncertainty</text>')
    else:
        p.append(f'<text x="{left}" y="{height-18}" fill="#f3b560" font-family="Arial,sans-serif" font-size="{tick_font}">Approximate graph readings · analyst allowance ±5 s / ±30 °F</text>')
    p.append('</svg>')
    return '\n'.join(p)+'\n'

for name, mobile in [("tm87740-figure24-digitized.svg", False), ("tm87740-figure24-digitized-mobile.svg", True)]:
    (ROOT/name).write_text(svg(mobile), encoding="utf-8")

rows=[]
for rec in RECORDS:
    for time_s,temp_f in rec["values_source_decimal"]:
        rows.append(f'<tr><th scope="row">{escape(rec["series"])}</th><td>{time_s}</td><td>{temp_f}</td><td>{escape(rec["kind"])}</td></tr>')
table='''<details class="thermal-readings"><summary>Open the approximate readings behind this graph</summary><div class="table-wrap" tabindex="0" role="region" aria-label="Approximate graph readings from NASA TM-87740 Figure 24"><table><caption>Approximate visual readings from the published graph; not raw or tabulated measurements. Analyst allowance: ±5 s and ±30 °F, not NASA-reported uncertainty.</caption><thead><tr><th scope="col">Trace</th><th scope="col">Time (s)</th><th scope="col">Temperature (°F)</th><th scope="col">Trace class</th></tr></thead><tbody>'''+''.join(rows)+'''</tbody></table></div></details>'''
(ROOT/"tm87740-figure24-readable-table.html").write_text(table, encoding="utf-8")
