# GESP等级：二级 | GESP Python 二级考点
"""
================================================================
  第二关: 添加选项 (★★☆☆☆)
  学习目标:
    1. 使用 EasyGUI 创建菜单交互
    2. 实现工具切换（画笔 / 圆形 / 矩形 / 星形 / 三角形）
    3. 实现颜色选择
    4. 实现画笔粗细调整
    5. 用函数组织代码，逻辑清晰
================================================================

【与第一关的区别】
  - 使用 EasyGUI 弹出菜单代替固定图形
  - 支持多种绘图工具切换
  - 可以自由选择颜色和画笔大小
  - 代码按功能拆分为独立函数
"""

import turtle
import easygui


# =============================================================
# 一、全局状态管理
# =============================================================

# 使用字典管理全局配置，便于扩展和维护
config = {
    "tool": "画笔",       # 当前工具
    "color": "black",    # 当前颜色
    "size": 3,           # 画笔粗细
}


# =============================================================
# 二、画布与画笔初始化
# =============================================================

def setup_screen():
    """配置画布"""
    screen = turtle.Screen()
    screen.title("画图编辑器 - 第二关: 添加选项")
    screen.bgcolor("white")
    screen.setup(width=800, height=600)
    screen.setworldcoordinates(-400, -300, 400, 300)
    return screen


def setup_pen():
    """创建画笔"""
    pen = turtle.Turtle()
    pen.shape("circle")
    pen.shapesize(0.5)
    pen.speed(0)
    pen.color(config["color"])
    pen.pensize(config["size"])
    pen.penup()
    return pen


def update_pen_style(pen):
    """根据当前配置更新画笔样式"""
    pen.color(config["color"])
    pen.pensize(config["size"])


# =============================================================
# 三、EasyGUI 菜单函数
# =============================================================

def choose_tool():
    """
    弹出工具选择菜单。
    返回 True 表示成功选择，False 表示用户取消。
    """
    tools = ["画笔", "圆形", "矩形", "星形", "三角形"]
    title = "🎨 选择绘图工具"
    msg = "请选择你想要使用的绘图工具："
    choice = easygui.choicebox(msg, title, tools)
    if choice is None:
        return False
    config["tool"] = choice
    return True


def choose_color():
    """
    弹出颜色选择菜单。
    """
    colors = {
        "红色": "red",
        "蓝色": "blue",
        "绿色": "green",
        "橙色": "orange",
        "紫色": "purple",
        "黑色": "black",
        "粉色": "pink",
        "棕色": "brown",
    }
    color_names = list(colors.keys())
    title = "🎨 选择画笔颜色"
    msg = "请选择画笔颜色："
    choice = easygui.choicebox(msg, title, color_names)
    if choice is None:
        return False
    config["color"] = colors[choice]
    return True


def choose_size():
    """
    弹出画笔粗细选择菜单。
    """
    sizes = ["1 (极细)", "2 (细)", "3 (适中)", "5 (粗)", "8 (极粗)", "10 (特粗)"]
    title = "✏️ 选择画笔粗细"
    msg = "请选择画笔粗细："
    choice = easygui.choicebox(msg, title, sizes)
    if choice is None:
        return False
    # 提取数字部分
    config["size"] = int(choice.split()[0])
    return True


def show_main_menu():
    """
    显示主菜单，让用户选择操作。
    返回选择的操作名称，或 None（取消）。
    """
    title = "🎨 画图编辑器 - 主菜单"
    msg = f"当前设置 → 工具: {config['tool']}  |  颜色: {config['color']}  |  粗细: {config['size']}\n\n请选择操作："
    choices = [
        "开始画图",
        "切换工具",
        "切换颜色",
        "调整粗细",
        "清空画布",
        "退出程序",
    ]
    choice = easygui.choicebox(msg, title, choices)
    return choice


# =============================================================
# 四、图形绘制函数（核心绘图逻辑）
# =============================================================

def draw_pen(pen, x, y):
    """画笔模式：从当前位置画线到目标点"""
    pen.pendown()
    pen.goto(x, y)
    pen.penup()


def draw_circle_shape(pen, x, y):
    """在指定位置画圆"""
    update_pen_style(pen)
    pen.penup()
    pen.goto(x, y - 50)  # 移到圆的底部
    pen.pendown()
    pen.circle(50)
    pen.penup()
    pen.goto(x, y)
    pen.dot(5)           # 标记圆心


def draw_rectangle_shape(pen, x, y):
    """在指定位置画矩形 (120x80)"""
    update_pen_style(pen)
    width, height = 120, 80
    pen.penup()
    pen.goto(x - width // 2, y - height // 2)  # 以点击点为中心
    pen.pendown()
    for _ in range(2):
        pen.forward(width)
        pen.left(90)
        pen.forward(height)
        pen.left(90)
    pen.penup()


def draw_star_shape(pen, x, y):
    """在指定位置画五角星"""
    update_pen_style(pen)
    pen.penup()
    pen.goto(x, y + 40)  # 从顶部开始
    pen.pendown()
    pen.right(90 - 36)    # 调整起始角度
    for _ in range(5):
        pen.forward(80)
        pen.right(144)    # 五角星外角 144°
    pen.penup()
    # 恢复角度
    pen.setheading(0)


def draw_triangle_shape(pen, x, y):
    """在指定位置画等边三角形"""
    update_pen_style(pen)
    side = 80
    pen.penup()
    pen.goto(x - side // 2, y - side // 3)  # 使点击点接近中心
    pen.pendown()
    for _ in range(3):
        pen.forward(side)
        pen.left(120)
    pen.penup()


# =============================================================
# 五、工具分发器（根据当前工具选择绘图函数）
# =============================================================

# 工具名称 -> 绘图函数的映射字典
TOOL_FUNCTIONS = {
    "画笔": draw_pen,
    "圆形": draw_circle_shape,
    "矩形": draw_rectangle_shape,
    "星形": draw_star_shape,
    "三角形": draw_triangle_shape,
}


def on_click_handler(x, y):
    """
    鼠标点击事件回调：
    根据当前选择的工具，调用对应的绘图函数。
    """
    # 画笔模式特殊处理：需要移动画笔到点击位置再画线
    if config["tool"] == "画笔":
        draw_pen(pen, x, y)
    else:
        # 其他工具：将画笔移到点击位置再画图形
        pen.penup()
        pen.goto(x, y)
        draw_func = TOOL_FUNCTIONS.get(config["tool"])
        if draw_func:
            draw_func(pen, x, y)


# =============================================================
# 六、工具函数
# =============================================================

def clear_canvas():
    """清空画布并重置画笔位置"""
    pen.clear()
    pen.penup()
    pen.home()
    update_pen_style(pen)
    show_status()


def exit_program():
    """退出程序"""
    turtle.bye()


def show_status():
    """在画布顶部显示当前设置状态"""
    pen.penup()
    pen.goto(0, 260)
    pen.color("gray")
    pen.write(
        f"工具: {config['tool']}  |  颜色: {config['color']}  |  粗细: {config['size']}  |  "
        f"点击画布绘图  |  ESC:菜单  C:清空  Q:退出",
        align="center",
        font=("SimHei", 12, "normal"),
    )


def show_welcome():
    """显示欢迎提示"""
    pen.penup()
    pen.goto(0, 200)
    pen.color("#888888")
    pen.write("按 ESC 键打开主菜单选择工具和颜色",
              align="center", font=("SimHei", 14, "bold"))
    pen.goto(0, 170)
    pen.write("或直接在画布上点击开始画图（默认: 画笔工具）",
              align="center", font=("SimHei", 11, "normal"))


# =============================================================
# 七、主流程控制
# =============================================================

def main_loop():
    """
    主循环：显示菜单 -> 用户选择 -> 执行操作。
    循环直到用户选择退出。
    """
    while True:
        choice = show_main_menu()

        if choice is None or choice == "退出程序":
            # 确认退出
            if easygui.ccbox("确定要退出画图编辑器吗？", "确认退出"):
                exit_program()
                break

        elif choice == "开始画图":
            easygui.msgbox(
                f"当前工具: {config['tool']}\n"
                f"当前颜色: {config['color']}\n"
                f"画笔粗细: {config['size']}\n\n"
                "请在画布上点击鼠标开始绘图！\n"
                "按 ESC 键可随时返回菜单。",
                "开始画图",
            )
            show_status()

        elif choice == "切换工具":
            choose_tool()

        elif choice == "切换颜色":
            choose_color()
            update_pen_style(pen)

        elif choice == "调整粗细":
            choose_size()
            update_pen_style(pen)

        elif choice == "清空画布":
            clear_canvas()


def on_esc_pressed():
    """ESC 键回调：进入主菜单"""
    main_loop()


# =============================================================
# 八、程序入口
# =============================================================

def main():
    global pen

    # 1. 先弹出工具和颜色选择（让用户在画图前先设置）
    easygui.msgbox(
        "欢迎使用画图编辑器！\n\n"
        "第一步: 选择绘图工具\n"
        "第二步: 选择画笔颜色\n"
        "第三步: 在画布上点击画图\n\n"
        "点击「确定」开始设置。",
        "🎨 画图编辑器 - 第二关",
    )

    choose_tool()
    choose_color()
    choose_size()

    # 2. 初始化画布
    screen = setup_screen()
    pen = setup_pen()

    # 3. 绑定事件
    screen.onclick(on_click_handler)     # 鼠标点击绘图
    screen.onkey(on_esc_pressed, "Escape")  # ESC 打开菜单
    screen.onkey(clear_canvas, "c")      # C 清空
    screen.onkey(exit_program, "q")      # Q 退出
    screen.listen()

    # 4. 显示欢迎信息
    show_welcome()

    # 5. 进入主循环 - 让用户选择下一步操作
    main_loop()

    # 6. 启动 turtle 主循环（实际不会执行到这里，但保留兼容）
    screen.mainloop()


if __name__ == "__main__":
    main()
