#!/usr/bin/env python3
"""Rebuild a clearly labelled, approximate redraw of HVEPS Figure 11."""
from __future__ import annotations

import csv
import json
from html import escape
from pathlib import Path

OUT = Path(__file__).resolve().parent
X = [20.0, 25.0, 30.0, 34.5]
DATA = {
    "conductivity": {
        "85% combustion efficiency": [0.8, 3.9, 6.8, 8.0],
        "95% combustion efficiency": [2.4, 7.0, 10.5, 12.0],
        "100% combustion efficiency": [4.5, 10.2, 14.0, 15.6],
    },
    "diagonal_power_density": {
        "85% combustion efficiency": [0.02, 0.085, 0.155, 0.19],
        "95% combustion efficiency": [0.05, 0.16, 0.255, 0.30],
        "100% combustion efficiency": [0.10, 0.245, 0.35, 0.40],
    },
}
COLORS = {"85% combustion efficiency": "#58c7c5", "95% combustion efficiency": "#f3b85c", "100% combustion efficiency": "#e987cf"}
SHAPES = {"85% combustion efficiency": "triangle", "95% combustion efficiency": "square", "100% combustion efficiency": "diamond"}
ORDER = ["100% combustion efficiency", "95% combustion efficiency", "85% combustion efficiency"]


def csv_data() -> None:
    with (OUT / "hveps-figure11-design-redraw.csv").open("w", newline="", encoding="utf-8") as stream:
        writer = csv.writer(stream)
        writer.writerow(["oxygen_enrichment_percent_graph_read", "combustion_efficiency_percent", "conductivity_S_per_m_graph_read_approx", "conductivity_read_allowance_S_per_m", "diagonal_power_density_MW_per_m3_per_T2_graph_read_approx", "power_density_read_allowance_MW_per_m3_per_T2", "record_class"])
        for name in ("85% combustion efficiency", "95% combustion efficiency", "100% combustion efficiency"):
            efficiency = int(name.split("%", 1)[0])
            for index, oxygen in enumerate(X):
                writer.writerow([oxygen, efficiency, DATA["conductivity"][name][index], 0.2, DATA["diagonal_power_density"][name][index], 0.01, "published design calculation; digitized from raster plot, not measurement"])


def label(x: float, y: float, value: str, size: int = 14, color: str = "#eaf0fa", weight: str = "400", anchor: str = "middle") -> str:
    return f'<text x="{x:.1f}" y="{y:.1f}" text-anchor="{anchor}" font-family="Arial,Helvetica,sans-serif" font-size="{size}" font-weight="{weight}" fill="{color}">{escape(value)}</text>'


def make_svg(mobile: bool = False) -> str:
    width, height = (390, 1040) if mobile else (1200, 680)
    charts = [(10, 140, 300, 405), (10, 565, 300, 405)] if mobile else [(62, 140, 500, 440), (638, 140, 500, 440)]
    parts = [f'<svg xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc" viewBox="0 0 {width} {height}">',
             '<title id="title">HVEPS Figure 11 design estimates redrawn from a published plot</title>',
             '<desc id="desc">Two plots show approximate graph-read design calculations for conductivity and diagonal MHD power density versus pre-heater oxygen enrichment at 85, 95 and 100 percent combustion efficiency. These are not measured test results.</desc>',
             '<rect width="100%" height="100%" rx="22" fill="#101a31"/>',
             label(width / 2, 48, "A design calculation, before the generator test", 25, "#ffffff", "700"),
             label(width / 2, 78, "Approximate readings from Figure 11 · calculated design cases, not measured output", 15, "#bdc9df")]
    if mobile:
        parts = parts[:4] + [label(width / 2, 39, "Design calculation", 18, "#ffffff", "700"), label(width / 2, 61, "before the generator test", 18, "#ffffff", "700"), label(width / 2, 91, "Approximate Figure 11 readings", 12, "#bdc9df"), label(width / 2, 109, "Calculated cases, not measured output", 12, "#bdc9df")]
    for panel, (x0, y0, cw, ch) in enumerate(charts):
        power = panel == 1
        ymax, step = (0.45, 0.05) if power else (18.0, 2.0)
        xmin, xmax = 20.0, 36.0
        left, right = x0 + (60 if mobile else 72), x0 + cw - (10 if mobile else 22)
        top, bottom = y0 + 46, y0 + ch - 58
        parts.append(f'<rect x="{x0}" y="{y0}" width="{cw}" height="{ch}" rx="14" fill="#172542" stroke="#364969"/>')
        title = ("Diagonal power density / B²" if mobile else "Diagonal MHD power density, normalized by B²") if power else "Electrical conductivity"
        units = "MW m⁻³ T⁻²" if power else "S/m"
        parts += [label(x0 + cw / 2, y0 + 25, title, 13 if mobile else 16, "#ffffff", "700"), label(x0 + cw / 2, y0 + ch - 10, "Pre-heater oxygen enrichment (%)", 11 if mobile else 13, "#bdc9df")]
        for tick in range(round(ymax / step) + 1):
            value = tick * step
            y = bottom - value / ymax * (bottom - top)
            parts += [f'<line x1="{left}" y1="{y:.1f}" x2="{right}" y2="{y:.1f}" stroke="#405273"/>', label(left - 9, y + 4, f"{value:.2f}" if power else f"{value:.0f}", 11, "#bdc9df", anchor="end")]
        for value in range(20, 37, 2):
            x = left + (value - xmin) / (xmax - xmin) * (right - left)
            parts += [f'<line x1="{x:.1f}" y1="{top}" x2="{x:.1f}" y2="{bottom}" stroke="#354664"/>', label(x, bottom + 18, str(value), 11, "#bdc9df")]
        parts += [f'<line x1="{left}" y1="{top}" x2="{left}" y2="{bottom}" stroke="#aab9d1"/>', f'<line x1="{left}" y1="{bottom}" x2="{right}" y2="{bottom}" stroke="#aab9d1"/>',
                  f'<text x="{x0 + 19}" y="{(top + bottom) / 2:.1f}" transform="rotate(-90 {x0 + 19} {(top + bottom) / 2:.1f})" text-anchor="middle" font-family="Arial,Helvetica,sans-serif" font-size="12" fill="#bdc9df">{escape(units)}</text>']
        for series_index, name in enumerate(ORDER):
            values = DATA["diagonal_power_density" if power else "conductivity"][name]
            points = [(left + (oxygen - xmin) / (xmax - xmin) * (right - left), bottom - value / ymax * (bottom - top)) for oxygen, value in zip(X, values)]
            color, shape = COLORS[name], SHAPES[name]
            parts.append(f'<polyline fill="none" stroke="{color}" stroke-width="3" stroke-linejoin="round" points="{" ".join(f"{x:.1f},{y:.1f}" for x, y in points)}"/>')
            for x, y in points:
                if shape == "square":
                    parts.append(f'<rect x="{x-5:.1f}" y="{y-5:.1f}" width="10" height="10" fill="{color}"/>')
                elif shape == "diamond":
                    parts.append(f'<path d="M {x:.1f} {y-6:.1f} l 6 6 l -6 6 l -6 -6 z" fill="{color}"/>')
                else:
                    parts.append(f'<path d="M {x:.1f} {y-6:.1f} l 6 11 h -12 z" fill="{color}"/>')
            ly = top + 20 + series_index * 20
            parts += [f'<line x1="{left+10}" y1="{ly}" x2="{left+35}" y2="{ly}" stroke="{color}" stroke-width="3"/>', label(left + 42, ly + 4, name.replace(" combustion efficiency", ""), 11, "#eaf0fa", anchor="start")]
    if mobile:
        parts += [label(width / 2, height - 37, "Lines connect read marker centres.", 11, "#bdc9df"), label(width / 2, height - 19, "They add no unsampled model results.", 11, "#bdc9df")]
    else:
        parts += [label(width / 2, height - 35, "Lines connect four read marker centres; they do not add unsampled model results.", 13, "#bdc9df")]
    parts.append('</svg>')
    return "\n".join(parts) + "\n"


def main() -> None:
    csv_data()
    (OUT / "hveps-figure11-design-redraw.svg").write_text(make_svg(), encoding="utf-8")
    (OUT / "hveps-figure11-design-redraw-mobile.svg").write_text(make_svg(True), encoding="utf-8")
    methods = {
        "title": "HVEPS Figure 11: oxygen-enrichment design-property plot (graph-read redraw)",
        "source": "Lineberry et al., AFRL-PR-WP-TP-2007-233 / NTIS-NTRL ADA471429, Figure 11, PDF p.12 / printed p.10",
        "source_record": "https://ntrl.ntis.gov/NTRL/dashboard/searchResults/titleDetail/ADA471429.xhtml",
        "source_file_sha256": "ccbc90c0bc0626328b058023d153d2f268767f85dafd8bfd2a0dbffaccfa1521",
        "source_plot_class": "Published design calculations for planned UTRC scramjet-rig operation; not experimental measurement data.",
        "calculation_provenance": "The report says Table II was calculated using PWR RASCAL code with LyTec thermochemical code. It describes Figure 11 as design-level inlet conductivity and diagonal power-density parameters.",
        "digitization": "Four visible marker centres per efficiency series were read approximately from the source PDF raster at about 20, 25, 30 and 34.5 percent oxygen enrichment. Values are rounded to graph resolution; connecting lines are visual guides and do not represent newly calculated intermediate points.",
        "visual_read_allowance": {"oxygen_enrichment_percentage_points": 0.2, "conductivity_S_per_m": 0.2, "diagonal_power_density_MW_per_m3_per_T2": 0.01, "status": "Analyst visual-read allowances only; not source, instrument, or model uncertainty."},
        "series": DATA,
        "distinction_from_table_ii": "Table II gives target cases at 35% oxygen enrichment for 75%, 85% and 95% efficiency. Its 85% entry lists 8.06 S/m and a Faraday power-density parameter of 7.81 MW/m^3/T^2. Figure 11 instead plots approximate diagonal power density normalized by B^2 (about 0.19 MW/m^3/T^2 at the 34.5%, 85% design point); these are different power-density definitions and must not be conflated.",
        "design_point": "The report identifies 34.5% oxygen enrichment at 85% combustion efficiency as the selected MHD-channel mechanical design point. Table II is a calculated target table; it separately notes a March 2006 baseline measured mean combustion efficiency of 84%, an unseeded baseline result, not validation of Figure 11 curves.",
        "what_this_shows": "Why oxygen enrichment and combustion efficiency mattered when selecting an intended hot, conductive test flow.",
        "what_this_does_not_show": ["measured HVEPS electrical output", "measured MHD power-density values", "a validated reproduction of RASCAL or LyTec", "a flight result, net vehicle benefit, or closed generator-to-accelerator energy loop", "complete solver inputs, native pointwise model output, or propagated uncertainty"],
        "reproduction": "python hveps-figure11-design-redraw.py",
        "source_graph_artwork_embedded": False,
        "rights_note": "This is an independently drawn approximate numerical redraw with attribution, not a copy of the source figure artwork. Public reuse rights for the source report figures have not been separately assessed.",
    }
    (OUT / "hveps-figure11-design-redraw-methods.json").write_text(json.dumps(methods, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")


if __name__ == "__main__":
    main()
