import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext

class MathFormulaQuery:
    def __init__(self, root):
        self.root = root
        self.root.title("数学公式查询工具")
        self.root.geometry("750x550")

        # 公式数据库：分类:{公式名称:公式内容}
        self.formula_data = {
            "基础代数": {
                "完全平方和": "(a+b)² = a² + 2ab + b²",
                "完全平方差": "(a-b)² = a² - 2ab + b²",
                "平方差": "a² - b² = (a+b)(a-b)",
                "立方和": "a³+b³=(a+b)(a²-ab+b²)",
                "立方差": "a³-b³=(a-b)(a²+ab+b²)",
                "一元二次方程求根": "x = [-b ± √(b²-4ac)] / 2a"
            },
            "三角函数": {
                "正弦定义": "sinα = 对边/斜边",
                "余弦定义": "cosα = 邻边/斜边",
                "正切定义": "tanα = sinα/cosα",
                "同角平方关系": "sin²α + cos²α = 1",
                "两角和正弦": "sin(α+β)=sinαcosβ+cosαsinβ",
                "两角和余弦": "cos(α+β)=cosαcosβ-sinαsinβ"
            },
            "几何公式": {
                "三角形面积": "S = 1/2 * 底 * 高",
                "圆周长": "C = 2πr",
                "圆面积": "S = πr²",
                "矩形面积": "S = 长 × 宽",
                "梯形面积": "S=(上底+下底)×高÷2",
                "球体体积": "V = 4/3 πr³"
            },
            "数列": {
                "等差数列通项": "an = a₁ + (n-1)d",
                "等差数列求和": "Sn = n(a₁+an)/2",
                "等比数列通项": "an = a₁·q^(n-1)",
                "等比数列求和": "Sn = a₁(1-qⁿ)/(1-q)  (q≠1)"
            }
        }

        # 构建界面布局
        self.create_widgets()

    def create_widgets(self):
        # 顶部搜索栏
        top_frame = tk.Frame(self.root, padx=10, pady=8)
        top_frame.pack(fill="x")

        tk.Label(top_frame, text="搜索公式：").pack(side="left")
        self.search_entry = tk.Entry(top_frame, width=45)
        self.search_entry.pack(side="left", padx=6)
        self.search_entry.bind("<Return>", self.search_formula)

        search_btn = tk.Button(top_frame, text="查找", command=self.search_formula)
        search_btn.pack(side="left", padx=4)

        # 主体左右分栏
        main_frame = tk.Frame(self.root, padx=10)
        main_frame.pack(fill="both", expand=True)

        # 左侧分类列表：width在创建Frame时指定，pack去掉width
        left_frame = tk.Frame(main_frame, width=180)
        left_frame.pack(side="left", fill="y")
        tk.Label(left_frame, text="公式分类", font=("黑体", 12)).pack()

        self.category_list = tk.Listbox(left_frame)
        for cat in self.formula_data.keys():
            self.category_list.insert(tk.END, cat)
        self.category_list.pack(fill="both", expand=True, pady=5)
        self.category_list.bind("<<ListboxSelect>>", self.show_category_formula)

        # 右侧公式展示区
        right_frame = tk.Frame(main_frame)
        right_frame.pack(side="right", fill="both", expand=True, padx=(10, 0))
        tk.Label(right_frame, text="公式详情", font=("黑体", 12)).pack(anchor="w")

        self.result_text = scrolledtext.ScrolledText(right_frame, wrap="word", font=("微软雅黑", 11))
        self.result_text.pack(fill="both", expand=True, pady=5)

        # 底部功能按钮
        bottom_frame = tk.Frame(self.root, padx=10, pady=6)
        bottom_frame.pack(fill="x")

        tk.Button(bottom_frame, text="复制选中公式", command=self.copy_text).pack(side="left", padx=5)
        tk.Button(bottom_frame, text="清空内容", command=self.clear_text).pack(side="left", padx=5)
        tk.Button(bottom_frame, text="添加自定义公式", command=self.add_formula).pack(side="left", padx=5)

    # 点击分类展示对应所有公式
    def show_category_formula(self, event):
        self.clear_text()
        select_idx = self.category_list.curselection()
        if not select_idx:
            return
        cat_name = self.category_list.get(select_idx[0])
        formula_dict = self.formula_data[cat_name]
        self.result_text.insert(tk.END, f"===== {cat_name} =====\n\n")
        for name, formula in formula_dict.items():
            self.result_text.insert(tk.END, f"【{name}】\n{formula}\n\n")

    # 关键词搜索公式
    def search_formula(self, event=None):
        keyword = self.search_entry.get().strip()
        if not keyword:
            messagebox.showwarning("提示", "请输入搜索关键词")
            return
        self.clear_text()
        has_result = False
        for category, formulas in self.formula_data.items():
            for name, content in formulas.items():
                if keyword in name or keyword in content:
                    has_result = True
                    self.result_text.insert(tk.END, f"[{category}] 【{name}】\n{content}\n\n")
        if not has_result:
            self.result_text.insert(tk.END, "未查询到匹配的公式\n")

    # 复制文本框选中内容
    def copy_text(self):
        try:
            sel = self.result_text.selection_get()
            self.root.clipboard_clear()
            self.root.clipboard_append(sel)
            messagebox.showinfo("成功", "已复制到剪贴板")
        except:
            messagebox.showerror("错误", "请先选中要复制的公式")

    # 清空文本框
    def clear_text(self):
        self.result_text.delete(1.0, tk.END)

    # 弹窗新增自定义公式
    def add_formula(self):
        add_win = tk.Toplevel(self.root)
        add_win.title("新增公式")
        add_win.geometry("380x260")

        tk.Label(add_win, text="分类名称：").place(x=20, y=15)
        cat_in = tk.Entry(add_win, width=32)
        cat_in.place(x=90, y=15)

        tk.Label(add_win, text="公式名称：").place(x=20, y=55)
        name_in = tk.Entry(add_win, width=32)
        name_in.place(x=90, y=55)

        tk.Label(add_win, text="公式内容：").place(x=20, y=95)
        con_in = tk.Text(add_win, width=30, height=5)
        con_in.place(x=90, y=95)

        def save_new():
            cat = cat_in.get().strip()
            fname = name_in.get().strip()
            fcont = con_in.get(1.0, tk.END).strip()
            if not (cat and fname and fcont):
                messagebox.showwarning("提示", "三项内容都不能为空")
                return
            # 分类不存在则新建
            if cat not in self.formula_data:
                self.formula_data[cat] = {}
                self.category_list.insert(tk.END, cat)
            self.formula_data[cat][fname] = fcont
            messagebox.showinfo("完成", "公式添加成功")
            add_win.destroy()

        tk.Button(add_win, text="保存添加", command=save_new).place(x=145, y=210)

if __name__ == "__main__":
    window = tk.Tk()
    app = MathFormulaQuery(window)
    window.mainloop()
