# ②（記憶の店）を、寸法つきの平面図（CAD 風）として描く
# 元：公開している店の形のデータ（public/sim/layouts/unity/p0_memory.json。版 9b8dae7ebf8c）。読むだけで変えない
# 実際の店の図面にないもの（ロボットの待機場所・道・止まる位置・会計の列など）は描かない
# 使い方: python3 draw_plan.py <出力png>
import json, sys, math
import matplotlib; matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle, Circle, Arc, Polygon

SRC = "/home/claude/p2m-site/public/sim/layouts/unity/p0_memory.json"
U = json.load(open(SRC))
plt.rcParams["font.family"] = "Noto Sans CJK JP"
K = "#111111"
fig, ax = plt.subplots(figsize=(16, 13.5), dpi=150)
ax.set_aspect("equal"); ax.axis("off")
W, D = U["outer"]["w"], U["outer"]["d"]

def rect(r, lw=0.8, fc="none", ec=K, z=2, hatch=None):
    ax.add_patch(Rectangle((r[0], r[1]), r[2] - r[0], r[3] - r[1], fc=fc, ec=ec, lw=lw, zorder=z, hatch=hatch))

def label(r, s, fs=9, rot=0):
    ax.text((r[0] + r[2]) / 2, (r[1] + r[3]) / 2, s, ha="center", va="center", fontsize=fs, rotation=rot, zorder=6,
            bbox=dict(fc="white", ec=K, lw=0.6, pad=2))

# 外壁（入口は開ける）
for r in U["outer_walls"]:
    rect(r, lw=0.6, fc=K, z=3)
# 内壁・仕切り
for w in U["walls"]:
    tall = w.get("height", 2.7) > 2.0
    rect(w["rect"], lw=0.6, fc=K if tall else "white", z=3, hatch=None if tall else "////")
# 部屋（厨房側は輪郭と名前だけ。建物の外は描かない）
for r in U["rooms"]:
    if r["kind"] == "outside":
        continue
    lab = r["label"]
    if lab in ("レジ", "ドリンクバー", "待合"):
        rect(r["rect"], lw=1.0, z=4)
        label(r["rect"], {"レジ": "レジ", "ドリンクバー": "ドリンクバー", "待合": "待合"}[lab], fs=8)
    elif lab == "レジ内":
        continue
    else:
        rect(r["rect"], lw=1.2, z=2)
        x0, y0, x1, y1 = r["rect"]
        label(r["rect"], lab, fs=10 if (x1 - x0) > 1.5 else 8, rot=90 if (y1 - y0) > 2.5 * (x1 - x0) else 0)
# 料理の受け渡し口（台）
for p in U.get("places", []):
    pass
for d in json.load(open("/home/claude/p2m-site/public/sim/layouts/p0_memory.json"))["layout"]["dish_up"]:
    rect(d["rect"], lw=1.2, fc="white", z=5, hatch="xxxx")
    x0, y0, x1, y1 = d["rect"]
    ax.text((x0 + x1) / 2, y0 - 0.35 if "下" in d["label"] else y1 + 0.35, "受け渡し口", ha="center", va="center", fontsize=8, zorder=6)
# 店員の出入り口（扉ありは開く向き、なしは開口）
for d in U["doors"]:
    x0, y0, x1, y1 = d["rect"]
    rect(d["rect"], lw=0, fc="white", ec="white", z=4)
    if d["door"]:
        w = x1 - x0
        ax.add_patch(Arc((x0, y0), 2 * w, 2 * w, theta1=270, theta2=360, lw=0.7, ec=K, zorder=5))
        ax.plot([x0, x0], [y0, y0 - w], color=K, lw=0.9, zorder=5)
# トイレの入口
L0 = json.load(open("/home/claude/p2m-site/public/sim/layouts/p0_memory.json"))["layout"]
for t in L0["toilet_doors"]:
    x0, y0, x1, y1 = t
    rect(t, lw=0, fc="white", ec="white", z=4)
    w = x1 - x0 if (x1 - x0) > (y1 - y0) else y1 - y0
    if (x1 - x0) >= (y1 - y0):
        ax.add_patch(Arc((x0, y0), 2 * w, 2 * w, theta1=270, theta2=360, lw=0.7, ec=K, zorder=5))
    else:
        ax.add_patch(Arc((x0, y0), 2 * w, 2 * w, theta1=0, theta2=90, lw=0.7, ec=K, zorder=5))
# 入口の扉（両開き）
e = U["entrance"]
a0, a1 = e["a0"], e["a1"]; h = (a1 - a0) / 2
ax.add_patch(Arc((a0, 0), 2 * h, 2 * h, theta1=270, theta2=360, lw=0.7, ec=K, zorder=5))
ax.add_patch(Arc((a1, 0), 2 * h, 2 * h, theta1=180, theta2=270, lw=0.7, ec=K, zorder=5))
ax.plot([a0, a0], [0, -h], color=K, lw=0.9); ax.plot([a1, a1], [0, -h], color=K, lw=0.9)
ax.text((a0 + a1) / 2, -1.6, "入口", ha="center", va="center", fontsize=11,
        bbox=dict(fc="white", ec=K, lw=0.6, pad=2))
# 卓：天板・椅子・ソファ
for t in U["tables"]:
    P = t["parts"]
    for b in P.get("benches", []):
        rect(b, lw=0.8, z=4)
    top = P["top"]
    if P.get("top_shape") == "circle":
        ax.add_patch(Circle(((top[0] + top[2]) / 2, (top[1] + top[3]) / 2), (top[2] - top[0]) / 2, fc="white", ec=K, lw=0.9, zorder=5))
    else:
        rect(top, lw=0.9, fc="white", z=5)
    for c in P.get("chairs", []):
        r = c["rect"]
        if c.get("stool"):
            ax.add_patch(Circle(((r[0] + r[2]) / 2, (r[1] + r[3]) / 2), (r[2] - r[0]) / 2, fc="white", ec=K, lw=0.7, zorder=4))
        else:
            rect(r, lw=0.7, fc="white", z=4)

# 寸法線（mm）
def dim_h(xs, y, tick=0.25, fs=9):
    ax.plot([xs[0], xs[-1]], [y, y], color=K, lw=0.6)
    for x in xs:
        ax.plot([x, x], [y - tick, y + tick], color=K, lw=0.6)
    for a, b in zip(xs, xs[1:]):
        ax.text((a + b) / 2, y + 0.3, f"{round((b - a) * 1000)}", ha="center", va="bottom", fontsize=fs)
def dim_v(ys, x, tick=0.25, fs=9):
    ax.plot([x, x], [ys[0], ys[-1]], color=K, lw=0.6)
    for y in ys:
        ax.plot([x - tick, x + tick], [y, y], color=K, lw=0.6)
    for a, b in zip(ys, ys[1:]):
        ax.text(x - 0.3, (a + b) / 2, f"{round((b - a) * 1000)}", ha="right", va="center", fontsize=fs, rotation=90)
def guide(x0, y0, x1, y1):
    ax.plot([x0, x1], [y0, y1], color=K, lw=0.4, ls=(0, (6, 4)), zorder=1)

xs = [0.0, 7.6, 9.8, 12.0, 19.0, 24.0]          # 通り芯（建物の角・パントリー・キッチンの境）
ys_l = [0.0, 8.6, 17.0]                          # 左：仕切り・建物の上の端
ys_r = [0.0, 6.0, 17.0, 19.2]                    # 右：厨房の下の端・洗い場の下の端
for x in xs:
    guide(x, -0.6, x, D + 1.6)
for y in sorted(set(ys_l + ys_r)):
    guide(-1.6, y, W + 1.6, y)
dim_h(xs, D + 1.2)
dim_v(ys_l, -1.2)
dim_v(ys_r, W + 1.6)
ax.text(W + 2.3, D / 2, f"{round(D * 1000)}", rotation=90, ha="left", va="center", fontsize=10)
dim_h([0.0, a0, a1, W], -2.6)
dim_h([0.0, W], -3.5)
ax.text(W / 2, -4.3, "単位 mm　点線は通り芯", ha="center", fontsize=9)

ax.set_xlim(-3.0, W + 3.4); ax.set_ylim(-4.8, D + 2.4)
fig.savefig(sys.argv[1], bbox_inches="tight", facecolor="white")
print("ok", sys.argv[1])
