import tkinter as tk
from tkinter import messagebox, filedialog
import os

ROWS, COLS = 15, 20
CELL = 30

# 地形类型：名称 / 颜色 / 可通过
TERRAIN = {
    0: ("草地", "#7EC850", True),
    1: ("水域", "#4A90D9", False),
    2: ("山地", "#A0522D", False),
    3: ("道路", "#D2B48C", True),
    4: ("建筑", "#8B4513", False),
}

class MapEditor:
    def __init__(self, root):
        self.root = root
        self.root.title("042. 二维地图编辑器")
        self.root.resizable(False, False)

        self.map_data = [[0] * COLS for _ in range(ROWS)]
        self.current_terrain = 0
        self.drawing = False

        self.build_ui()
        self.draw_map()

    # ========== UI ==========
    def build_ui(self):
        # 标题
        tk.Label(
            self.root, text="🗺️ 二维地图编辑器",
            font=("微软雅黑", 18, "bold")
        ).pack(pady=10)

        # ===== 工具栏 =====
        toolbar = tk.Frame(self.root)
        toolbar.pack(pady=5)

        tk.Label(toolbar, text="选择地形：", font=("微软雅黑", 10)).pack(side=tk.LEFT, padx=5)

        self.terrain_buttons = []
        for tid, (name, color, _) in TERRAIN.items():
            btn = tk.Button(
                toolbar, text=name, width=8,
                bg=color, fg="white" if tid != 0 else "black",
                font=("微软雅黑", 9, "bold"),
                command=lambda t=tid: self.select_terrain(t)
            )
            btn.pack(side=tk.LEFT, padx=2)
            self.terrain_buttons.append(btn)

        # ===== 画布 =====
        canvas_frame = tk.Frame(self.root, relief=tk.RAISED, bd=2)
        canvas_frame.pack(padx=10, pady=5)

        self.canvas = tk.Canvas(
            canvas_frame,
            width=COLS * CELL, height=ROWS * CELL,
            bg="white", cursor="crosshair"
        )
        self.canvas.pack()

        self.canvas.bind("<Button-1>", self.start_draw)
        self.canvas.bind("<B1-Motion>", self.draw_cell)
        self.canvas.bind("<ButtonRelease-1>", self.stop_draw)

        # ===== 图例 =====
        legend = tk.Frame(self.root)
        legend.pack(pady=5)

        tk.Label(legend, text="图例：", font=("微软雅黑", 9, "bold")).pack(side=tk.LEFT, padx=5)
        for tid, (name, color, passable) in TERRAIN.items():
            f = tk.Frame(legend)
            f.pack(side=tk.LEFT, padx=8)
            tk.Label(f, text="  ", bg=color, relief=tk.RAISED, bd=1).pack(side=tk.LEFT)
            tk.Label(f, text=f" {name}", font=("微软雅黑", 8)).pack(side=tk.LEFT)

        # ===== 按钮区 =====
        btn_frame = tk.Frame(self.root)
        btn_frame.pack(pady=8)

        tk.Button(btn_frame, text="清空地图", width=10,
                  bg="#FF9800", fg="white",
                  command=self.clear_map).pack(side=tk.LEFT, padx=5)

        tk.Button(btn_frame, text="保存地图", width=10,
                  bg="#4CAF50", fg="white",
                  command=self.save_map).pack(side=tk.LEFT, padx=5)

        tk.Button(btn_frame, text="加载地图", width=10,
                  bg="#2196F3", fg="white",
                  command=self.load_map).pack(side=tk.LEFT, padx=5)

        tk.Button(btn_frame, text="退出", width=10,
                  bg="#f44336", fg="white",
                  command=self.root.quit).pack(side=tk.LEFT, padx=5)

        # ===== 状态栏 =====
        self.status = tk.Label(
            self.root, text="就绪 | 当前地形：草地",
            anchor="w", relief=tk.SUNKEN
        )
        self.status.pack(side=tk.BOTTOM, fill=tk.X)

        # 选中第一个
        self.select_terrain(0)

    # ========== 核心逻辑 ==========
    def select_terrain(self, tid):
        self.current_terrain = tid
        for i, btn in enumerate(self.terrain_buttons):
            btn.config(relief=tk.SUNKEN if i == tid else tk.RAISED)
        name = TERRAIN[tid][0]
        self.status.config(text=f"就绪 | 当前地形：{name}")

    def start_draw(self, e):
        self.drawing = True
        self.draw_at(e.x, e.y)

    def draw_cell(self, e):
        if self.drawing:
            self.draw_at(e.x, e.y)

    def stop_draw(self, e):
        self.drawing = False

    def draw_at(self, x, y):
        col = x // CELL
        row = y // CELL
        if 0 <= row < ROWS and 0 <= col < COLS:
            self.map_data[row][col] = self.current_terrain
            self.draw_map()

    def draw_map(self):
        self.canvas.delete("all")
        for r in range(ROWS):
            for c in range(COLS):
                tid = self.map_data[r][c]
                color = TERRAIN[tid][1]
                x1, y1 = c * CELL, r * CELL
                x2, y2 = x1 + CELL, y1 + CELL
                self.canvas.create_rectangle(
                    x1, y1, x2, y2,
                    fill=color, outline="#CCCCCC"
                )

    def clear_map(self):
        if messagebox.askyesno("确认", "清空整个地图？"):
            self.map_data = [[0] * COLS for _ in range(ROWS)]
            self.draw_map()
            self.status.config(text="地图已清空")

    def save_map(self):
        path = filedialog.asksaveasfilename(
            defaultextension=".txt",
            filetypes=[("文本文件", "*.txt")]
        )
        if not path:
            return

        try:
            with open(path, "w", encoding="utf-8") as f:
                f.write(f"ROWS={ROWS}\n")
                f.write(f"COLS={COLS}\n")
                for row in self.map_data:
                    f.write(",".join(str(c) for c in row) + "\n")
            messagebox.showinfo("成功", f"地图已保存到：\n{path}")
        except Exception as e:
            messagebox.showerror("错误", f"保存失败：{e}")

    def load_map(self):
        path = filedialog.askopenfilename(
            filetypes=[("文本文件", "*.txt")]
        )
        if not path:
            return

        try:
            with open(path, "r", encoding="utf-8") as f:
                lines = f.readlines()

            new_map = []
            for line in lines:
                line = line.strip()
                if line.startswith("ROWS=") or line.startswith("COLS="):
                    continue
                if line:
                    row = [int(x) for x in line.split(",")]
                    new_map.append(row)

            if not new_map:
                messagebox.showwarning("提示", "文件格式不正确！")
                return

            # 检查尺寸
            r = len(new_map)
            c = len(new_map[0])
            if r != ROWS or c != COLS:
                messagebox.showwarning(
                    "提示",
                    f"地图尺寸不匹配！\n当前：{ROWS}×{COLS}\n文件：{r}×{c}"
                )
                return

            self.map_data = new_map
            self.draw_map()
            messagebox.showinfo("成功", "地图已加载！")
        except Exception as e:
            messagebox.showerror("错误", f"加载失败：{e}")


if __name__ == "__main__":
    root = tk.Tk()
    MapEditor(root)
    root.mainloop()