"""Reproduce Figures 1–3 and equation images for the revised Menkaure manuscript.
Requires Python 3, matplotlib and numpy. Run from any writable directory.
Historical measurements and numerical results are unchanged. Figure panels are
schematics; they do not reconstruct individual block locations.
"""
from pathlib import Path
import math
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Rectangle, Polygon
ROOT = Path(__file__).resolve().parent
FIG = ROOT / "figures_coffer_states"
FIG.mkdir(exist_ok=True)
L, W, H = 96.0, 37.0, 35.0
TOTAL_W, TOTAL_H = 57.5, 57.0
GAP, RAMP_W, APERTURE_H = 35.5, 11.0, 28.0
BUILT_L = 201.0
PALM = 20.6 / 7.0
DIAG = math.hypot(W, H)
SOCKET_RESIDUAL = 40.0 - W
REACH_RESIDUAL = 54.0 - DIAG

def save_equation(name, text, width=6.0):
    fig = plt.figure(figsize=(width, .44), dpi=300)
    fig.patch.set_alpha(0)
    ax = fig.add_axes([0, 0, 1, 1]); ax.axis("off")
    ax.text(.5, .5, text, ha="center", va="center", fontsize=15.5, color="black")
    fig.savefig(FIG / name, dpi=300, transparent=True, bbox_inches="tight", pad_inches=.03)
    plt.close(fig)


def make_figures():
    navy, teal, red, grey = "#24577f", "#178b78", "#b7463f", "#65717a"
    pale, sand = "#edf3f6", "#eee6d8"

    fig, ax = plt.subplots(1, 3, figsize=(11.8, 3.5))
    # Perring's measured raw envelope and intermediate aperture.
    a = ax[0]
    a.add_patch(Rectangle((0, 0), TOTAL_W, TOTAL_H, facecolor=pale, edgecolor=navy, lw=2))
    a.annotate("57 in raw height", (TOTAL_W/2, 4), ha="center", color=navy, fontsize=9, weight="bold")
    a.text(TOTAL_W/2, 46, "Before narrowing", ha="center", color=navy, fontsize=9, weight="bold")
    a.set(xlim=(-4, 62), ylim=(-4, 63), aspect="equal", title="A  Before restriction")
    a.axis("off")

    # Perring's directly described 28 x 35.5 in residual aperture.
    a = ax[1]
    a.add_patch(Rectangle((0, 0), TOTAL_W, TOTAL_H, facecolor=pale, edgecolor=navy, lw=2))
    x0 = (TOTAL_W-GAP)/2
    a.add_patch(Rectangle((0, 0), x0, TOTAL_H, facecolor=sand, edgecolor=grey, lw=1.2))
    a.add_patch(Rectangle((TOTAL_W-x0, 0), x0, TOTAL_H, facecolor=sand, edgecolor=grey, lw=1.2))
    a.add_patch(Rectangle((x0, APERTURE_H), GAP, TOTAL_H-APERTURE_H, facecolor=sand, edgecolor=grey, lw=1.2))
    a.add_patch(Rectangle((x0, 0), GAP, APERTURE_H, fill=False, edgecolor=red, lw=2.8))
    a.text(TOTAL_W/2, 14, "28 × 35.5 in\nresidual aperture", ha="center", va="center", color=red, fontsize=9, weight="bold")
    a.set(xlim=(-4, 62), ylim=(-4, 63), aspect="equal", title="B  After coffer placement")
    a.axis("off")

    a = ax[2]
    labels = ["Minimum central\nspan of coffer", "Recorded opening\nheight"]
    vals = [H, APERTURE_H]
    bars = a.bar(labels, vals, color=[teal, red], width=.58)
    for b, v in zip(bars, vals):
        a.text(b.get_x()+b.get_width()/2, v+.6, f"{v:.0f} in", ha="center", weight="bold")
    a.annotate("7 in exclusion", xy=(1, 31), xytext=(.43, 39),
               arrowprops=dict(arrowstyle="->", color=red), color=red, weight="bold", fontsize=9)
    a.set_ylim(0, 42); a.set_ylabel("Height (in)")
    a.set_title("C  No orientation permits passage")
    a.spines[["top", "right"]].set_visible(False)
    fig.suptitle("The intermediate opening was too low for the coffer", fontsize=13.5, weight="bold")
    fig.tight_layout()
    fig.savefig(FIG / "figure2.png", dpi=300, bbox_inches="tight")
    fig.savefig(FIG / "figure2.tif", dpi=600, format="tiff", pil_kwargs={"compression": "tiff_lzw"}, bbox_inches="tight")
    plt.close(fig)

    fig, ax = plt.subplots(1, 2, figsize=(10.6, 3.45))
    a = ax[0]
    years = [1837, 1840, 1883, 1967]
    y = [0, 0, 0, 0]
    a.hlines(0, 1835, 1970, color=grey, lw=2)
    a.scatter(years, y, s=120, c=[teal, navy, red, grey], zorder=3)
    texts = ["Extraction\nintervention", "Perring dimensions\nand sequence", "Petrie survey\nafter removal", "M&R reconstructed\ngeneric section"]
    offsets = [.35, -.55, .35, -.55]
    for x, t, dy in zip(years, texts, offsets):
        a.text(x, dy, f"{x}\n{t}", ha="center", va="center", fontsize=8.3)
    a.set(xlim=(1830, 1975), ylim=(-.95, .78), title="A  Historical sources")
    a.axis("off")

    a = ax[1]
    labels = ["Aperture\nwidth", "Aperture\nheight", "Raw envelope\nheight"]
    vals = [GAP-H, APERTURE_H-H, TOTAL_H-W]
    colors = [teal, red, teal]
    bars = a.bar(labels, vals, color=colors, width=.6)
    a.axhline(0, color="#263640", lw=1)
    for b, v in zip(bars, vals):
        a.text(b.get_x()+b.get_width()/2, v + (.45 if v >= 0 else -.9), f"{v:+.1f} in", ha="center", weight="bold")
    a.set_ylim(-11, 22.5); a.set_ylabel("Clearance relative to coffer")
    a.set_title("B  Clearance relative to coffer")
    a.spines[["top", "right"]].set_visible(False)
    fig.suptitle("Historical sources describe different access conditions", fontsize=13.5, weight="bold")
    fig.tight_layout()
    fig.savefig(FIG / "figure3.png", dpi=300, bbox_inches="tight")
    fig.savefig(FIG / "figure3.tif", dpi=600, format="tiff", pil_kwargs={"compression": "tiff_lzw"}, bbox_inches="tight")
    plt.close(fig)

    equations = {
        "eq1.png": r"$a\times b=35.5\times28\ \mathrm{in}$",
        "eq2.png": r"$28-35=-7\ \mathrm{in}=-17.78\ \mathrm{cm}$",
        "eq3.png": r"$c(\mathbf{u})=\min_i\!\left(\frac{a_i}{|u_i|}\right)\geq\min_i(a_i)=35\ \mathrm{in}$",
        "eq4.png": r"$C\ \Longrightarrow\ 201>\sqrt{96^2+37^2+35^2}=108.7\ \mathrm{in}$",
        "eq5.png": r"$C\ \Longrightarrow\ 35.5\times28=994<37\times35=1295\ \mathrm{in}^2$",
        "eq6.png": r"$S=40-37=3.000\ \mathrm{in}\qquad R=54-\sqrt{37^2+35^2}=3.069\ \mathrm{in}$",
    }
    for name, text in equations.items():
        save_equation(name, text, 7.0 if name in {"eq3.png", "eq4.png", "eq5.png", "eq6.png"} else 5.2)



def make_context_figure(outdir, egypt_coords):
    outdir=Path(outdir);outdir.mkdir(exist_ok=True,parents=True)
    plt.rcParams.update({'font.family':'DejaVu Sans','font.size':10})
    fig=plt.figure(figsize=(12,4.5),facecolor='white')
    gs=fig.add_gridspec(1,3,width_ratios=[1,1,1.35],wspace=.22)
    ink='#263640';muted='#61717B';accent='#B84138';sand='#ECE7DA';blue='#285D7F'
    a=fig.add_subplot(gs[0]);a.set_title('A  Giza in Egypt',loc='left',fontweight='bold',pad=12)
    a.add_patch(Polygon(egypt_coords,facecolor=sand,edgecolor=muted,lw=1.3))
    a.scatter([31.134],[29.973],s=46,color=accent,zorder=3)
    a.annotate('Giza\nnear Cairo',(31.134,29.973),xytext=(25.5,30.3),ha='left',va='center',color=accent,fontweight='bold',arrowprops={'arrowstyle':'-','color':accent,'lw':1})
    a.text(28.4,26.7,'EGYPT',ha='center',color=ink,fontsize=12)
    a.text(28.9,32.1,'Mediterranean Sea',ha='center',color=muted,fontsize=9)
    a.text(35.1,25.6,'Red Sea',rotation=-58,ha='center',color=muted,fontsize=9)
    a.set_xlim(24,37);a.set_ylim(21.4,33.2);a.set_aspect(1.12);a.set_anchor('N');a.axis('off')
    b=fig.add_subplot(gs[1]);b.set_title('B  Three royal pyramids',loc='left',fontweight='bold',pad=12)
    for x,y,w,name,color in [(2.1,3.3,.94,'Khufu',muted),(1.12,2.03,.90,'Khafre',muted),(.28,.75,.49,'Menkaure',accent)]:
        b.add_patch(Rectangle((x,y),w,w,facecolor='#F4F5F5' if name!='Menkaure' else '#F5E5E1',edgecolor=color,lw=1.8))
        b.plot([x,x+w],[y,y+w],color=color,lw=.9);b.plot([x,x+w],[y+w,y],color=color,lw=.9)
        b.text(x+w/2,y-.14,name,ha='center',va='top',color=color,fontweight='bold')
    b.annotate('N',xy=(3.45,4.0),xytext=(3.45,4.58),ha='center',va='center',fontweight='bold',arrowprops={'arrowstyle':'<-','color':ink,'lw':1.5})
    b.text(1.85,.12,'Giza plateau\nSchematic plan, not to scale',ha='center',va='top',color=muted,fontsize=9)
    b.set_xlim(-.1,3.9);b.set_ylim(-.45,4.9);b.set_aspect('equal');b.set_anchor('N');b.axis('off')
    c=fig.add_subplot(gs[2]);c.set_title('C  The lost stone coffer',loc='left',fontweight='bold',pad=12)
    A=np.array([.25,1.50]);u=np.array([3.65,0]);v=np.array([.80,.70]);z=np.array([0,1.25])
    c.add_patch(Polygon([A,A+u,A+u+z,A+z],fc='#BBC4C7',ec=ink,lw=1.3))
    c.add_patch(Polygon([A+u,A+u+v,A+u+v+z,A+u+z],fc='#98A7AE',ec=ink,lw=1.3))
    top=np.array([A+z,A+u+z,A+u+v+z,A+v+z]);c.add_patch(Polygon(top,fc='#E4E9EA',ec=ink,lw=1.3))
    centre=top.mean(axis=0);inner=centre+(top-centre)*np.array([.84,.60]);c.add_patch(Polygon(inner,fc='#657982',ec=ink,lw=1))
    c.annotate('',xy=(.25,1.22),xytext=(3.90,1.22),arrowprops={'arrowstyle':'|-|','lw':1,'color':blue})
    c.text(2.08,1.05,'96 in (2.44 m)',ha='center',va='top',color=blue,fontsize=10)
    c.text(2.55,.32,'Outer size: 96 × 37 × 35 in\n(2.44 × 0.94 × 0.89 m)',ha='center',va='center',color=ink,fontsize=10)
    c.text(2.55,4.05,'Recorded in 1837\nLost aboard Beatrice in 1838',ha='center',va='center',color=ink,fontsize=10)
    c.text(2.55,-.26,'Rectangular model; decoration not reconstructed',ha='center',va='center',color=muted,fontsize=8.6)
    c.set_xlim(-.1,5.2);c.set_ylim(-.5,4.6);c.axis('off')
    fig.subplots_adjust(left=.025,right=.985,bottom=.08,top=.87)
    fig.savefig(outdir/'figure1.png',dpi=300,bbox_inches='tight')
    fig.savefig(outdir/'figure1.tif',dpi=600,bbox_inches='tight',pil_kwargs={'compression':'tiff_lzw'})
    plt.close(fig)


# Modern locator outline: Natural Earth ne_110m_admin_0_countries, public domain.
# https://www.naturalearthdata.com/about/terms-of-use/
EGYPT_OUTLINE = [[36.86623, 22], [32.9, 22], [29.02, 22], [25, 22], [25, 25.6825], [25, 29.238655], [24.70007, 30.04419], [24.95762, 30.6616], [24.80287, 31.08929], [25.16482, 31.56915], [26.49533, 31.58568], [27.45762, 31.32126], [28.45048, 31.02577], [28.91353, 30.87005], [29.68342, 31.18686], [30.09503, 31.4734], [30.97693, 31.55586], [31.68796, 31.4296], [31.96041, 30.9336], [32.19247, 31.26034], [32.99392, 31.02407], [33.7734, 30.96746], [34.265435, 31.219357], [34.26544, 31.21936], [34.823243, 29.761081], [34.9226, 29.50133], [34.64174, 29.09942], [34.42655, 28.34399], [34.15451, 27.8233], [33.92136, 27.6487], [33.58811, 27.97136], [33.13676, 28.41765], [32.42323, 29.85108], [32.32046, 29.76043], [32.73482, 28.70523], [33.34876, 27.69989], [34.10455, 26.14227], [34.47387, 25.59856], [34.79507, 25.03375], [35.69241, 23.92671], [35.49372, 23.75237], [35.52598, 23.10244], [36.69069, 22.20485], [36.86623, 22]]

if __name__ == "__main__":
    make_figures()
    make_context_figure(FIG, EGYPT_OUTLINE)
