"""f02_timeline -- horizontal timeline 1662 -> 2020s of EOS milestones.
Colour code: navy = classical, amber = molecular, teal = data-driven.
Schematic; dates and attributions are historical facts, not computed data.
"""
import sys
sys.path.insert(0, "/home/claude/eos_lecture/code")
from eosstyle import *

# Canvas proportioned to the slide box the picture is placed in (12.09 x 3.45
# in), so the point sizes below are close to what the audience actually sees;
# the vertical space freed by the shorter canvas is what lets the labels grow.
fig, ax = blank(13.0, 3.9)

FS_EV    = 14.0   # timeline event labels
FS_LEG   = 13.0   # category key
FS_TITLE = 17.0

# Line breaks are chosen so that no label is wider than the 1.75 in of clear
# paper between two events sharing the same side of the axis.
events = [
    (1662, "Boyle's law", "classical"),
    (1834, "Ideal gas law\n(Clapeyron)", "classical"),
    (1869, "Andrews: critical\npoint observed", "classical"),
    (1873, "van der Waals\nEOS", "classical"),
    (1901, "Virial expansion\n(Kamerlingh\nOnnes)", "classical"),
    (1939, "Corresponding\nstates (Pitzer,\nrefined)", "classical"),
    (1949, "Redlich-Kwong", "classical"),
    (1955, "Pitzer acentric\nfactor ω", "classical"),
    (1972, "Soave (SRK)", "classical"),
    (1976, "Peng-Robinson", "classical"),
    (1985, "Wertheim theory\n(1984-86)", "molecular"),
    (1990, "SAFT\n(Chapman et al.)", "molecular"),
    (2001, "PC-SAFT\n(Gross-\nSadowski)", "molecular"),
    (2010, "ePC-SAFT\n(electrolytes)", "molecular"),
    (2020, "ML / physics-\ninformed EOS", "data"),
]

cat_color = {"classical": NAVY, "molecular": AMBER, "data": TEAL}
cat_label = {"classical": "classical macroscopic", "molecular": "molecular / perturbation theory",
             "data": "data-driven / ML"}

# NOTE: events are spaced by rank (equal steps), not true calendar-linear
# position, because the true year scale crushes the 1949-2020s cluster into
# illegibility on a 1662-2026 axis. This is a schematic timeline; each
# marker still carries its exact year as a text label.
n = len(events)
def xmap(i):
    return 0.035 + 0.940 * i / (n - 1)

yline = 0.50
ax.plot([0.012, 0.985], [yline, yline], color=GRAPHITE, lw=1.4, zorder=2,
        solid_capstyle="round")

# small arrowhead at the right end of the axis
ax.annotate("", xy=(0.997, yline), xytext=(0.985, yline),
            arrowprops=dict(arrowstyle="-|>", color=GRAPHITE, lw=1.4, mutation_scale=14),
            zorder=2)

# alternate labels above / below to avoid collisions
for i, (yr, name, cat) in enumerate(events):
    x = xmap(i)
    above = (i % 2 == 0)
    color = cat_color[cat]
    ax.plot([x], [yline], marker="o", ms=8.5, color=color, zorder=4,
            markeredgecolor="white", markeredgewidth=1.0)
    if above:
        ytext = yline + 0.075
        ax.plot([x, x], [yline + 0.022, ytext - 0.012], color=SLATE, lw=0.9, zorder=1)
        ax.text(x, ytext, f"{yr}\n{name}", ha="center", va="bottom", fontsize=FS_EV,
                color=INK, zorder=5, linespacing=1.25)
    else:
        ytext = yline - 0.075
        ax.plot([x, x], [yline - 0.022, ytext + 0.012], color=SLATE, lw=0.9, zorder=1)
        ax.text(x, ytext, f"{name}\n{yr}", ha="center", va="top", fontsize=FS_EV,
                color=INK, zorder=5, linespacing=1.25)

# category key: a single horizontal row along the empty foot of the canvas,
# well clear of the title (which it used to sit on top of)
leg_x = [0.185, 0.400, 0.700]
ly = 0.085
for lx, cat in zip(leg_x, ["classical", "molecular", "data"]):
    ax.plot([lx], [ly], marker="o", ms=9, color=cat_color[cat], markeredgecolor="white",
            markeredgewidth=1.0, zorder=6)
    ax.text(lx + 0.014, ly, cat_label[cat], ha="left", va="center",
            fontsize=FS_LEG, color=INK)

ax.text(0.5, 0.995, "One hundred fifty years of the equation of state, 1662-2020s",
        ha="center", va="top", fontsize=FS_TITLE, color=NAVY, weight="bold")

ax.set_xlim(0, 1)
ax.set_ylim(0.0, 1.0)

save(fig, "f02_timeline")
