#!/usr/bin/env python3
"""Rebuild an accessible chart from the abstract of Ling et al. (2024).

The source reports four magnetic-field cases and two distinct percentages.
The paper's full methods/results were not available for this bounded chart;
the figure therefore preserves the abstract's values without inferring a
whole-engine or net-efficiency result.
"""

from pathlib import Path
import csv
import html


OUT = Path(__file__).resolve().parent
DATA = [
    (1, 22.5, 0.026),
    (2, 22.3, 0.10),
    (3, 22.0, 0.21),
    (4, 21.5, 0.34),
]


def svg(mobile=False):
    width, height = (760, 1030) if mobile else (1200, 700)
    margin_left, margin_right = (92, 40) if mobile else (105, 60)
    panel_w = width - margin_left - margin_right
    if mobile:
        usable_width = width - margin_left - margin_right
        panels = [(130, usable_width, "Reported generation efficiency", 20, 24, 2),
                  (610, usable_width, "Reported enthalpy extraction rate", 0, .4, .1)]
    else:
        gap = 70
        panel_w = (width - margin_left - margin_right - gap) / 2
        panels = [(130, panel_w, "Reported generation efficiency", 20, 24, 2),
                  (130, panel_w, "Reported enthalpy extraction rate", 0, .4, .1)]

    def map_point(v, lo, hi, start, span):
        return start + (v - lo) / (hi - lo) * span

    ink, blue, magenta = "#10264a", "#1979a8", "#c53585"
    parts = [f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {width} {height}" role="img" aria-labelledby="title desc">',
             '<title id="title">Two reported measures in a 2024 scramjet MHD generator-channel simulation</title>',
             '<desc id="desc">The article abstract reports generation efficiency declining from 22.5 to 21.5 percent and enthalpy extraction rate rising from 0.026 to 0.34 percent as magnetic field rises from 1 to 4 tesla. These are simulation values, not measurements or whole-engine efficiency.</desc>',
             '<rect width="100%" height="100%" rx="28" fill="#f5f8fe"/>',
             f'<text x="38" y="52" fill="{ink}" font-family="Arial,sans-serif" font-size="30" font-weight="700">Conversion is not extraction</text>',
             f'<text x="38" y="86" fill="#405a80" font-family="Arial,sans-serif" font-size="19">The simulated flow gives up at most 0.34% of its enthalpy.</text>']

    for idx, (top, pwidth, heading, lo, hi, step) in enumerate(panels):
        x0 = margin_left if idx == 0 or mobile else margin_left + panel_w + 70
        plot_top = top + (55 if not mobile else 52)
        plot_h = 210 if not mobile else 260
        parts.append(f'<text x="{x0}" y="{top+25}" fill="{ink}" font-family="Arial,sans-serif" font-size="21" font-weight="700">{html.escape(heading)} (%)</text>')
        tick = lo
        while tick <= hi + 1e-9:
            y = plot_top + plot_h - (tick - lo) / (hi - lo) * plot_h
            parts.append(f'<line x1="{x0}" y1="{y:.1f}" x2="{x0+pwidth:.1f}" y2="{y:.1f}" stroke="#d7e1ef" stroke-width="2"/>')
            parts.append(f'<text x="{x0-12}" y="{y+6:.1f}" text-anchor="end" fill="#52698b" font-family="Arial,sans-serif" font-size="15">{tick:g}</text>')
            tick += step
        points = []
        vals = [row[1] if idx == 0 else row[2] for row in DATA]
        for i, (field, eff, extraction) in enumerate(DATA):
            x = x0 + 25 + i * (pwidth - 50) / (len(DATA) - 1)
            value = eff if idx == 0 else extraction
            y = map_point(value, lo, hi, plot_top + plot_h, -plot_h)
            points.append((x, y, value, field))
        color = blue if idx == 0 else magenta
        points_attr = " ".join(f"{x:.1f},{y:.1f}" for x, y, _, _ in points)
        parts.append(f'<polyline points="{points_attr}" fill="none" stroke="{color}" stroke-width="4" stroke-linejoin="round"/>')
        for x, y, value, field in points:
            label = f"{value:g}" if idx == 0 else f"{value:.3g}"
            parts.append(f'<circle cx="{x:.1f}" cy="{y:.1f}" r="8" fill="{color}"/>')
            parts.append(f'<text x="{x:.1f}" y="{y-15:.1f}" text-anchor="middle" fill="{color}" font-family="Arial,sans-serif" font-size="15" font-weight="700">{label}</text>')
            parts.append(f'<text x="{x:.1f}" y="{plot_top+plot_h+28:.1f}" text-anchor="middle" fill="#405a80" font-family="Arial,sans-serif" font-size="15">{field} T</text>')
        parts.append(f'<text x="{x0+pwidth/2:.1f}" y="{plot_top+plot_h+58:.1f}" text-anchor="middle" fill="{ink}" font-family="Arial,sans-serif" font-size="16">Applied magnetic field</text>')
        if mobile:
            parts.append('<line x1="40" y1="560" x2="720" y2="560" stroke="#ccd8e8" stroke-width="2"/>')
    footer_y = 1010 if mobile else 660
    parts.append(f'<text x="38" y="{footer_y}" fill="#405a80" font-family="Arial,sans-serif" font-size="15">Simulation results transcribed from the publisher’s abstract; not measured engine performance.</text>')
    parts.append('</svg>')
    return "\n".join(parts)


def main():
    (OUT / "scramjet-generator-study-2024.svg").write_text(svg(), encoding="utf-8")
    (OUT / "scramjet-generator-study-2024-mobile.svg").write_text(svg(True), encoding="utf-8")
    with (OUT / "scramjet-generator-study-2024.csv").open("w", newline="", encoding="utf-8") as f:
        w = csv.writer(f)
        w.writerow(["magnetic_field_T", "reported_generation_efficiency_percent", "reported_enthalpy_extraction_rate_percent", "evidence_status"])
        w.writerows([*row, "simulation value reported in 2024 article abstract"] for row in DATA)
    print("Wrote two responsive SVGs and an abstract-derived CSV.")


if __name__ == "__main__":
    main()
