import tkinter as tk
from tkinter import ttk
import math


class CelestialBody:
    """行星数据类"""

    def __init__(self, name, description, diameter, distance, orbital_period, image_color):
        self.name = name
        self.description = description
        self.diameter = diameter
        self.distance = distance
        self.orbital_period = orbital_period
        self.image_color = image_color


class SolarSystemApp:
    def __init__(self, root):
        self.root = root
        self.root.title("八大行星探索系统")
        self.root.geometry("1200x800")
        self.root.configure(bg='#0a0a1a')

        # 设置网格权重，使窗口可调整大小
        self.root.grid_rowconfigure(0, weight=1)
        self.root.grid_columnconfigure(0, weight=1)

        # 行星数据
        self.planets = [
            CelestialBody("水星", "最靠近太阳的行星，表面温差极大", 4879, 57.9, 88, "#8C7853"),
            CelestialBody("金星", "最亮的行星，有浓厚的大气层", 12104, 108.2, 225, "#FFC649"),
            CelestialBody("地球", "我们的家园，已知唯一有生命的行星",
                          12756, 149.6, 365, "#2E6EFF"),
            CelestialBody("火星", "红色星球，可能有水的痕迹", 6792, 227.9, 687, "#FF5733"),
            CelestialBody("木星", "最大的行星，拥有壮丽的大红斑", 142984,
                          778.6, 4333, "#E0AA70"),
            CelestialBody("土星", "拥有美丽的光环系统", 120536, 1433.5, 10759, "#FAD5A5"),
            CelestialBody("天王星", "躺着自转的冰巨星", 51118, 2872.5, 30687, "#4FD0E7"),
            CelestialBody("海王星", "最遥远的行星，风速极高", 49528,
                          4495.1, 60190, "#4169E1")
        ]

        self.current_planet_index = 2

        # 操纵杆状态
        self.joystick_active = False
        self.joystick_x = 0
        self.joystick_y = 0

        # 创建界面
        self.setup_ui()

        # 创建独立信息窗口
        self.create_info_window()

        # 初始绘制
        self.root.after(100, self.draw_planet)

    def setup_ui(self):
        """设置用户界面"""
        # 主框架
        main_frame = tk.Frame(self.root, bg="#0a0a1a")
        main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)

        # 标题
        title_label = tk.Label(
            main_frame,
            text="八大行星探索系统",
            font=("Microsoft YaHei", 24, "bold"),
            fg="white",
            bg="#0a0a1a"
        )
        title_label.pack(pady=(0, 20))

        # 内容框架
        content_frame = tk.Frame(main_frame, bg="#0a0a1a")
        content_frame.pack(fill=tk.BOTH, expand=True)

        # 左侧行星展示区域
        left_frame = tk.Frame(content_frame, bg="#0a0a1a")
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 20))

        # 行星画布
        self.planet_canvas = tk.Canvas(
            left_frame,
            bg="#1a1a2e",
            highlightthickness=1,
            highlightbackground="#2a2a4e"
        )
        self.planet_canvas.pack(fill=tk.BOTH, expand=True)

        # 右侧控制面板
        right_frame = tk.Frame(content_frame, bg="#0a0a1a", width=350)
        right_frame.pack(side=tk.RIGHT, fill=tk.Y)

        # 行星选择列表
        list_frame = tk.LabelFrame(
            right_frame,
            text="选择行星",
            font=("Microsoft YaHei", 12, "bold"),
            fg="white",
            bg="#0a0a1a",
            padx=10,
            pady=10
        )
        list_frame.pack(fill=tk.X, pady=(0, 20))

        # 创建行星列表
        self.planet_listbox = tk.Listbox(
            list_frame,
            height=8,
            font=("Microsoft YaHei", 11),
            bg="#1a1a2e",
            fg="white",
            selectbackground="#4169E1",
            activestyle="none"
        )
        self.planet_listbox.pack(fill=tk.X)

        for planet in self.planets:
            self.planet_listbox.insert(tk.END, planet.name)

        self.planet_listbox.selection_set(self.current_planet_index)
        self.planet_listbox.bind("<<ListboxSelect>>", self.on_planet_select)

        # 操纵杆框架
        joystick_frame = tk.LabelFrame(
            right_frame,
            text="虚拟操纵杆",
            font=("Microsoft YaHei", 12, "bold"),
            fg="white",
            bg="#0a0a1a",
            padx=10,
            pady=10
        )
        joystick_frame.pack(fill=tk.X, pady=(0, 20))

        # 操纵杆画布
        self.joystick_canvas = tk.Canvas(
            joystick_frame,
            width=200,
            height=200,
            bg="#1a1a2e",
            highlightthickness=0
        )
        self.joystick_canvas.pack(pady=10)

        # 绘制操纵杆
        self.draw_joystick()

        # 绑定鼠标事件
        self.joystick_canvas.bind("<Button-1>", self.start_joystick)
        self.joystick_canvas.bind("<B1-Motion>", self.move_joystick)
        self.joystick_canvas.bind("<ButtonRelease-1>", self.release_joystick)

        # 控制按钮框架
        button_frame = tk.Frame(right_frame, bg="#0a0a1a")
        button_frame.pack(fill=tk.X, pady=(0, 20))

        # 控制按钮
        tk.Button(
            button_frame,
            text="显示详细信息",
            command=self.show_details,
            font=("Microsoft YaHei", 11),
            bg="#4169E1",
            fg="white",
            padx=20,
            pady=8,
            relief=tk.RAISED,
            bd=2
        ).pack(fill=tk.X, pady=5)

        tk.Button(
            button_frame,
            text="重置视图",
            command=self.reset_view,
            font=("Microsoft YaHei", 11),
            bg="#2a2a4e",
            fg="white",
            padx=20,
            pady=8,
            relief=tk.RAISED,
            bd=2
        ).pack(fill=tk.X, pady=5)

        # 信息标签
        self.info_label = tk.Label(
            right_frame,
            text="使用操纵杆旋转行星视图",
            font=("Microsoft YaHei", 10),
            fg="#88aaff",
            bg="#0a0a1a",
            wraplength=300
        )
        self.info_label.pack(fill=tk.X, pady=10)

        # 状态标签
        self.status_label = tk.Label(
            right_frame,
            text="就绪",
            font=("Microsoft YaHei", 9),
            fg="#66CC66",
            bg="#0a0a1a"
        )
        self.status_label.pack(fill=tk.X)

    def create_info_window(self):
        """创建独立信息窗口"""
        self.info_window = tk.Toplevel(self.root)
        self.info_window.title("行星详细信息")
        self.info_window.geometry("500x400")
        self.info_window.configure(bg='#0a0a1a')
        self.info_window.protocol("WM_DELETE_WINDOW", self.hide_info_window)

        # 信息窗口标题
        info_title = tk.Label(
            self.info_window,
            text="行星详细信息",
            font=("Microsoft YaHei", 18, "bold"),
            fg="white",
            bg="#0a0a1a"
        )
        info_title.pack(pady=20)

        # 详细信息文本
        self.detail_text = tk.Text(
            self.info_window,
            width=60,
            height=20,
            font=("Microsoft YaHei", 11),
            bg="#1a1a2e",
            fg="white",
            wrap=tk.WORD,
            padx=10,
            pady=10
        )
        self.detail_text.pack(padx=20, pady=10, fill=tk.BOTH, expand=True)

        # 滚动条
        scrollbar = tk.Scrollbar(self.detail_text)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.detail_text.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.detail_text.yview)

        # 初始隐藏信息窗口
        self.info_window.withdraw()

    def draw_joystick(self):
        """绘制操纵杆"""
        self.joystick_canvas.delete("all")

        # 绘制外圈
        self.joystick_canvas.create_oval(
            10, 10, 190, 190,
            fill="#2a2a4e",
            outline="#4169E1",
            width=2
        )

        # 绘制中心点和坐标轴
        center_x, center_y = 100, 100
        self.joystick_canvas.create_line(
            center_x, 20, center_x, 180,
            fill="#4169E1",
            width=1,
            dash=(2, 2)
        )
        self.joystick_canvas.create_line(
            20, center_y, 180, center_y,
            fill="#4169E1",
            width=1,
            dash=(2, 2)
        )

        # 绘制操纵杆手柄
        self.joystick_handle = self.joystick_canvas.create_oval(
            center_x - 20, center_y - 20,
            center_x + 20, center_y + 20,
            fill="#FF5733",
            outline="#FF8C00",
            width=2
        )

        # 添加标签
        self.joystick_canvas.create_text(
            center_x, 30, text="上", fill="#88aaff", font=("Microsoft YaHei", 9))
        self.joystick_canvas.create_text(
            center_x, 170, text="下", fill="#88aaff", font=("Microsoft YaHei", 9))
        self.joystick_canvas.create_text(
            30, center_y, text="左", fill="#88aaff", font=("Microsoft YaHei", 9))
        self.joystick_canvas.create_text(
            170, center_y, text="右", fill="#88aaff", font=("Microsoft YaHei", 9))

    def start_joystick(self, event):
        """开始操纵杆控制"""
        self.joystick_active = True
        self.move_joystick(event)

    def move_joystick(self, event):
        """移动操纵杆"""
        if not self.joystick_active:
            return

        center_x, center_y = 100, 100
        joystick_radius = 70

        # 计算相对于中心点的位置
        dx = event.x - center_x
        dy = event.y - center_y

        # 限制在圆形范围内
        distance = math.sqrt(dx*dx + dy*dy)
        if distance > joystick_radius:
            dx = dx * joystick_radius / distance
            dy = dy * joystick_radius / distance

        # 更新手柄位置
        self.joystick_canvas.coords(
            self.joystick_handle,
            center_x + dx - 20,
            center_y + dy - 20,
            center_x + dx + 20,
            center_y + dy + 20
        )

        # 更新行星视图
        self.joystick_x = dx / joystick_radius
        self.joystick_y = dy / joystick_radius
        self.update_planet_view()

        # 更新信息
        self.info_label.config(
            text=f"操纵杆位置: X={self.joystick_x:.2f}, Y={self.joystick_y:.2f}"
        )
        self.status_label.config(text="操纵杆控制中")

    def release_joystick(self, event):
        """释放操纵杆"""
        self.joystick_active = False

        # 手柄回到中心
        center_x, center_y = 100, 100
        self.joystick_canvas.coords(
            self.joystick_handle,
            center_x - 20, center_y - 20,
            center_x + 20, center_y + 20
        )

        # 重置位置
        self.joystick_x = 0
        self.joystick_y = 0
        self.info_label.config(text="使用操纵杆旋转行星视图")
        self.status_label.config(text="就绪")

    def draw_planet(self):
        """绘制当前行星"""
        self.planet_canvas.delete("all")

        planet = self.planets[self.current_planet_index]

        # 获取画布尺寸
        canvas_width = self.planet_canvas.winfo_width()
        canvas_height = self.planet_canvas.winfo_height()

        if canvas_width <= 1 or canvas_height <= 1:
            canvas_width, canvas_height = 600, 400

        # 计算行星大小（基于实际直径比例，适当缩放）
        base_size = min(canvas_width, canvas_height) * 0.4
        planet_scale = planet.diameter / 142984
        planet_size = max(base_size * planet_scale, 30)

        # 中心坐标
        center_x, center_y = canvas_width // 2, canvas_height // 2

        # 应用操纵杆旋转
        rotation_x = self.joystick_x * 30
        rotation_y = self.joystick_y * 30

        # 绘制行星
        planet_x1 = center_x - planet_size + rotation_x
        planet_y1 = center_y - planet_size + rotation_y
        planet_x2 = center_x + planet_size + rotation_x
        planet_y2 = center_y + planet_size + rotation_y

        # 创建渐变效果
        self.planet_canvas.create_oval(
            planet_x1, planet_y1, planet_x2, planet_y2,
            fill=planet.image_color,
            outline="#FFFFFF",
            width=2
        )

        # 添加高光效果
        highlight_size = planet_size * 0.3
        self.planet_canvas.create_oval(
            planet_x1 + highlight_size, planet_y1 + highlight_size,
            planet_x1 + highlight_size * 2, planet_y1 + highlight_size * 2,
            fill="white",
            stipple="gray50"
        )

        # 添加行星名称
        self.planet_canvas.create_text(
            center_x, planet_y2 + 40,
            text=planet.name,
            font=("Microsoft YaHei", 24, "bold"),
            fill="white"
        )

        # 添加行星基本信息
        info_text = f"直径: {planet.diameter:,} km\n距离太阳: {planet.distance} 百万km\n公转周期: {planet.orbital_period} 天"
        self.planet_canvas.create_text(
            center_x, planet_y2 + 100,
            text=info_text,
            font=("Microsoft YaHei", 12),
            fill="#88aaff",
            justify=tk.CENTER
        )

        # 绘制轨道示意
        orbit_radius = planet_size + 50
        self.planet_canvas.create_oval(
            center_x - orbit_radius, center_y - orbit_radius,
            center_x + orbit_radius, center_y + orbit_radius,
            outline="#4169E1",
            width=1,
            dash=(5, 5)
        )

        # 太阳示意
        sun_size = 20
        sun_distance = orbit_radius + 50
        self.planet_canvas.create_oval(
            center_x - sun_size, center_y - sun_distance - sun_size,
            center_x + sun_size, center_y - sun_distance + sun_size,
            fill="#FFD700",
            outline="#FFA500",
            width=2
        )
        self.planet_canvas.create_text(
            center_x, center_y - sun_distance - 30,
            text="太阳",
            font=("Microsoft YaHei", 10),
            fill="#FFA500"
        )

        # 添加坐标系指示
        self.planet_canvas.create_line(
            center_x - 50, center_y, center_x + 50, center_y,
            fill="#6666FF",
            width=1,
            arrow=tk.BOTH
        )
        self.planet_canvas.create_line(
            center_x, center_y - 50, center_x, center_y + 50,
            fill="#66FF66",
            width=1,
            arrow=tk.BOTH
        )

    def update_planet_view(self):
        """更新行星视图"""
        self.draw_planet()

    def on_planet_select(self, event):
        """选择行星事件"""
        selection = self.planet_listbox.curselection()
        if selection:
            self.current_planet_index = selection[0]
            self.draw_planet()
            self.status_label.config(
                text=f"已选择: {self.planets[self.current_planet_index].name}")

    def show_details(self):
        """显示详细信息窗口"""
        planet = self.planets[self.current_planet_index]

        # 更新详细信息文本
        self.detail_text.delete(1.0, tk.END)

        # 获取自转周期
        rotation_periods = {
            "水星": "58.6 天",
            "金星": "243 天（逆向自转）",
            "地球": "23小时56分钟",
            "火星": "24小时37分钟",
            "木星": "9小时55分钟",
            "土星": "10小时33分钟",
            "天王星": "17小时14分钟（躺着自转）",
            "海王星": "16小时6分钟"
        }

        # 获取行星特征
        planet_features = {
            "水星": "• 表面温差极大（-173°C 到 427°C）\n• 没有大气层\n• 表面布满陨石坑",
            "金星": "• 大气压强是地球的92倍\n• 表面温度约462°C\n• 大气主要由二氧化碳组成",
            "地球": "• 已知唯一有生命的行星\n• 表面71%被水覆盖\n• 拥有一个天然卫星（月球）",
            "火星": "• 被称为'红色星球'\n• 有太阳系最大的火山\n• 可能有地下水和冰",
            "木星": "• 太阳系最大的行星\n• 拥有79颗已知卫星\n• 著名的大红斑是巨大的风暴",
            "土星": "• 拥有壮观的行星环\n• 密度小于水，可以漂浮在水上\n• 拥有62颗卫星",
            "天王星": "• 自转轴倾斜98度\n• 呈蓝绿色是因为甲烷\n• 拥有暗淡的行星环",
            "海王星": "• 风速可达2100 km/h\n• 有太阳系最强的风暴\n• 发现的第一颗通过计算预测的行星"
        }

        detail_text = f"""
【{planet.name}】

基本参数：
• 直径：{planet.diameter:,} 千米
• 与太阳平均距离：{planet.distance} 百万千米
• 公转周期：{planet.orbital_period} 天
• 自转周期：{rotation_periods.get(planet.name, "未知")}

详细描述：
{planet.description}

天文特征：
{planet_features.get(planet.name, "")}
        """

        self.detail_text.insert(1.0, detail_text)

        # 显示窗口
        self.info_window.deiconify()
        self.info_window.lift()
        self.status_label.config(text=f"显示详细信息: {planet.name}")

    def reset_view(self):
        """重置视图"""
        self.joystick_x = 0
        self.joystick_y = 0
        self.draw_planet()
        self.draw_joystick()
        self.info_label.config(text="视图已重置")
        self.status_label.config(text="视图已重置")

    def hide_info_window(self):
        """隐藏信息窗口"""
        self.info_window.withdraw()
        self.status_label.config(text="就绪")

    def run(self):
        """运行应用"""
        self.root.mainloop()


def main():
    """主函数"""
    try:
        root = tk.Tk()
        app = SolarSystemApp(root)
        app.run()
    except Exception as e:
        print(f"程序启动时发生错误: {e}")
        print("请确保已正确安装Python和Tkinter")


if __name__ == "__main__":
    main()
