"""flashcards.py - a Thai/English word trainer with a real window.

Nothing to install. tkinter comes inside Python.

    python3 flashcards.py

It saves your words and your score to words.json, next to this file.
Close it, open it tomorrow, and it still knows which words are hard for you.
"""
import json
import tkinter as tk
from tkinter import font as tkfont
from pathlib import Path

WORDS_PATH = Path(__file__).with_name("words.json")

STARTER_WORDS = [
    {"en": "temple",    "th": "วัด",        "misses": 0},
    {"en": "mountain",  "th": "ภูเขา",      "misses": 0},
    {"en": "market",    "th": "ตลาด",       "misses": 0},
    {"en": "river",     "th": "แม่น้ำ",      "misses": 0},
    {"en": "teacher",   "th": "ครู",        "misses": 0},
    {"en": "rain",      "th": "ฝน",         "misses": 0},
]


def pick_font():
    """Find a font on THIS computer that can show Thai.

    Different computers have different fonts. We try a few names and use the
    first one that is really here. If none are, we use whatever Python picked,
    which usually still works but is very small.
    """
    here = set(tkfont.families())
    for name in ("Leelawadee UI", "Noto Sans Thai", "Thonburi", "Tahoma", "Arial Unicode MS"):
        if name in here:
            return name
    return tkfont.nametofont("TkDefaultFont").actual("family")


def load_words():
    if WORDS_PATH.exists():
        return json.loads(WORDS_PATH.read_text(encoding="utf-8"))
    return [dict(w) for w in STARTER_WORDS]


def save_words(words):
    WORDS_PATH.write_text(json.dumps(words, ensure_ascii=False, indent=2),
                          encoding="utf-8")


class Flashcards:
    def __init__(self, root):
        self.words = load_words()
        self.index = 0
        self.right = 0
        self.wrong = 0
        family = pick_font()

        root.title("คำศัพท์ Flash")
        root.configure(bg="#e7f1ef")

        self.word = tk.Label(root, text="", bg="#e7f1ef", fg="#0f3835",
                             font=(family, 34, "bold"))
        self.answer = tk.Label(root, text="", bg="#e7f1ef", fg="#1e6660",
                               font=(family, 26))
        self.score = tk.Label(root, text="", bg="#e7f1ef", fg="#5f7370",
                              font=(family, 11))

        # command=self.flip  -- NOT self.flip(). With the () it runs once at
        # startup and the button then does nothing for ever.
        self.show_btn = tk.Button(root, text="Show", width=10, command=self.flip)
        self.knew_btn = tk.Button(root, text="I knew it", width=10, command=self.knew)
        self.miss_btn = tk.Button(root, text="I missed it", width=10, command=self.missed)

        self.entry = tk.Entry(root, font=(family, 12), width=26)
        self.add_btn = tk.Button(root, text="Add  en=th", width=10, command=self.add_word)

        self.word.grid(row=0, column=0, columnspan=3, padx=30, pady=(26, 6))
        self.answer.grid(row=1, column=0, columnspan=3, pady=(0, 14))
        self.show_btn.grid(row=2, column=0, padx=6, pady=6)
        self.knew_btn.grid(row=2, column=1, padx=6, pady=6)
        self.miss_btn.grid(row=2, column=2, padx=6, pady=6)
        self.score.grid(row=3, column=0, columnspan=3, pady=(10, 4))
        self.entry.grid(row=4, column=0, columnspan=2, padx=(12, 4), pady=(4, 18))
        self.add_btn.grid(row=4, column=2, padx=(4, 12), pady=(4, 18))

        self.show_card()

    # ----- the card ------------------------------------------------------
    def show_card(self):
        card = self.words[self.index]
        self.word.config(text=card["en"])
        self.answer.config(text="?")
        self.score.config(text="Right %d    Missed %d    Card %d of %d"
                               % (self.right, self.wrong, self.index + 1, len(self.words)))

    def flip(self):
        self.answer.config(text=self.words[self.index]["th"])

    def next_card(self):
        # Hard words first: the ones you miss most come round again sooner.
        self.words.sort(key=lambda w: -w["misses"])
        self.index = (self.index + 1) % len(self.words)
        self.show_card()

    def knew(self):
        self.right += 1
        self.after_answer()

    def missed(self):
        self.wrong += 1
        self.words[self.index]["misses"] += 1
        self.after_answer()

    def after_answer(self):
        save_words(self.words)
        self.next_card()

    # ----- adding your own ----------------------------------------------
    def add_word(self):
        text = self.entry.get().strip()
        if "=" not in text:
            self.score.config(text="Type it like this:  cat=แมว")
            return
        en, th = text.split("=", 1)
        en, th = en.strip(), th.strip()
        if not en or not th:
            self.score.config(text="Both sides are needed:  cat=แมว")
            return
        self.words.append({"en": en, "th": th, "misses": 0})
        save_words(self.words)
        self.entry.delete(0, tk.END)
        self.score.config(text="Added %s = %s   (%d words now)" % (en, th, len(self.words)))


def main():
    root = tk.Tk()
    Flashcards(root)
    root.mainloop()


if __name__ == "__main__":
    main()
