import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext

# 示例公式库（可按需扩展）
FORMULAS = {
    "代数": [
        {
            "title": "一元二次方程求根公式",
            "formula": "x = (-b ± sqrt(b^2 - 4ac)) / (2a)",
            "desc": "对于 ax^2 + bx + c = 0 (a ≠ 0)，判别式 Δ = b^2 - 4ac。若 Δ ≥ 0 有实根。"
        },
        {
            "title": "完全平方式",
            "formula": "a^2 + 2ab + b^2 = (a + b)^2",
            "desc": "将二次多项式写成平方的形式。"
        },
    ],
    "几何": [
        {
            "title": "三角形面积（底×高/2）",
            "formula": "S = (b × h) / 2",
            "desc": "b 为底边长，h 为对应高。"
        },
        {
            "title": "勾股定理",
            "formula": "a^2 + b^2 = c^2",
            "desc": "直角三角形中，两直角边 a、b 与斜边 c 的关系。"
        },
    ],
    "微积分": [
        {
            "title": "导数定义",
            "formula": "f'(x) = lim_{h→0} (f(x+h)-f(x))/h",
            "desc": "函数在一点的瞬时变化率。"
        },
        {
            "title": "不定积分线性性",
            "formula": "∫(a f(x) + b g(x)) dx = a ∫ f(x) dx + b ∫ g(x) dx",
            "desc": "积分的线性性质。"
        },
    ],
    "线性代数": [
        {
            "title": "行列式（2×2）",
            "formula": "|A| = ad - bc  (A = [[a, b],[c, d]])",
            "desc": "2×2 矩阵的行列式计算。"
        },
        {
            "title": "向量点积",
            "formula": "u · v = Σ u_i v_i",
            "desc": "两个同维向量的内积。"
        },
    ]
}

class FormulaApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("数学公式查询")
        self.geometry("800x500")
        self.create_widgets()
        self.populate_categories()

    def create_widgets(self):
        # 左侧分类列表
        left_frame = ttk.Frame(self)
        left_frame.pack(side=tk.LEFT, fill=tk.Y, padx=10, pady=10)

        lbl_cat = ttk.Label(left_frame, text="类别")
        lbl_cat.pack(anchor=tk.NW)

        self.cat_listbox = tk.Listbox(left_frame, height=20, width=20)
        self.cat_listbox.pack(fill=tk.Y, expand=True)
        self.cat_listbox.bind("<<ListboxSelect>>", self.on_category_select)

        # 中间公式列表和搜索
        mid_frame = ttk.Frame(self)
        mid_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=False, padx=10, pady=10)

        lbl_search = ttk.Label(mid_frame, text="搜索公式")
        lbl_search.pack(anchor=tk.NW)

        search_frame = ttk.Frame(mid_frame)
        search_frame.pack(fill=tk.X, pady=5)
        self.search_var = tk.StringVar()
        search_entry = ttk.Entry(search_frame, textvariable=self.search_var, width=30)
        search_entry.pack(side=tk.LEFT, padx=(0,5))
        search_entry.bind("<Return>", self.on_search)

        search_btn = ttk.Button(search_frame, text="搜索", command=self.on_search)
        search_btn.pack(side=tk.LEFT)

        lbl_list = ttk.Label(mid_frame, text="公式列表")
        lbl_list.pack(anchor=tk.NW, pady=(10,0))

        self.formula_listbox = tk.Listbox(mid_frame, height=20, width=40)
        self.formula_listbox.pack(fill=tk.BOTH, expand=True)
        self.formula_listbox.bind("<<ListboxSelect>>", self.on_formula_select)

        # 右侧详细显示
        right_frame = ttk.Frame(self)
        right_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10)

        lbl_detail = ttk.Label(right_frame, text="公式详情")
        lbl_detail.pack(anchor=tk.NW)

        self.title_var = tk.StringVar()
        title_lbl = ttk.Label(right_frame, textvariable=self.title_var, font=("Arial", 14, "bold"))
        title_lbl.pack(anchor=tk.NW, pady=(5,5))

        self.formula_text = scrolledtext.ScrolledText(right_frame, wrap=tk.WORD, height=10)
        self.formula_text.pack(fill=tk.BOTH, expand=True)
        self.formula_text.configure(state=tk.DISABLED)

    def populate_categories(self):
        self.cat_listbox.delete(0, tk.END)
        for cat in FORMULAS.keys():
            self.cat_listbox.insert(tk.END, cat)
        # 默认选中第一个
        if self.cat_listbox.size() > 0:
            self.cat_listbox.selection_set(0)
            self.on_category_select()

    def on_category_select(self, event=None):
        sel = self.cat_listbox.curselection()
        if not sel:
            return
        cat = self.cat_listbox.get(sel[0])
        self.current_category = cat
        self.update_formula_list(FORMULAS.get(cat, []))

    def update_formula_list(self, formulas):
        self.formula_listbox.delete(0, tk.END)
        for f in formulas:
            self.formula_listbox.insert(tk.END, f["title"])
        # 清空详情
        self.clear_detail()

    def on_formula_select(self, event=None):
        sel = self.formula_listbox.curselection()
        if not sel:
            return
        idx = sel[0]
        cat = getattr(self, "current_category", None)
        if cat is None:
            return
        formulas = FORMULAS.get(cat, [])
        if idx < 0 or idx >= len(formulas):
            return
        f = formulas[idx]
        self.show_detail(f)

    def on_search(self, event=None):
        kw = self.search_var.get().strip().lower()
        if not kw:
            # 显示当前类别全部
            cat = getattr(self, "current_category", None)
            if cat:
                self.update_formula_list(FORMULAS.get(cat, []))
            return
        # 在所有公式中查找匹配项（标题、公式、说明）
        results = []
        for cat, flist in FORMULAS.items():
            for f in flist:
                if kw in f["title"].lower() or kw in f["formula"].lower() or kw in f["desc"].lower():
                    results.append((cat, f))
        # 如果有结果，显示它们（前缀类别名）
        self.formula_listbox.delete(0, tk.END)
        self.search_results = results
        for cat, f in results:
            self.formula_listbox.insert(tk.END, f"{f['title']} [{cat}]")
        self.clear_detail()

    def show_detail(self, f):
        self.title_var.set(f["title"])
        self.formula_text.configure(state=tk.NORMAL)
        self.formula_text.delete("1.0", tk.END)
        self.formula_text.insert(tk.END, "公式：\n" + f["formula"] + "\n\n")
        self.formula_text.insert(tk.END, "说明：\n" + f["desc"])
        self.formula_text.configure(state=tk.DISABLED)

    def clear_detail(self):
        self.title_var.set("")
        self.formula_text.configure(state=tk.NORMAL)
        self.formula_text.delete("1.0", tk.END)
        self.formula_text.configure(state=tk.DISABLED)

if __name__ == "__main__":
    app = FormulaApp()
    app.mainloop()