import tkinter as tk
from tkinter import font as tkfont
from tkinter import colorchooser, filedialog, simpledialog
from datetime import datetime
import ctypes
import os
import sys
import subprocess
import json
import re

# --- תיקון חדות (DPI Awareness) ---
try:
    ctypes.windll.shcore.SetProcessDpiAwareness(1) 
except Exception:
    try:
        ctypes.windll.user32.SetProcessDPIAware()
    except:
        pass

# --- לוגיקה לשונית (שעה) ---
HOURS_FEM = {
    1: "אַחַת", 2: "שְׁתַּיִם", 3: "שָׁלוֹשׁ", 4: "אַרְבַּע", 5: "חָמֵשׁ",
    6: "שֵׁשׁ", 7: "שֶׁבַע", 8: "שְׁמוֹנֶה", 9: "תֵּשַׁע", 10: "עֶשֶׂר",
    11: "אַחַת עֶשְׂרֵה", 12: "שְׁתֵּים עֶשְׂרֵה", 0: "שְׁתֵּים עֶשְׂרֵה"
}

MINUTES_FEM = {
    1: "אַחַת", 2: "שְׁתֵּי", 3: "שָׁלוֹשׁ", 4: "אַרְבַּע", 5: "חָמֵשׁ",
    6: "שֵׁשׁ", 7: "שֶׁבַע", 8: "שְׁמוֹנֶה", 9: "תֵּשַׁע", 10: "עֶשֶׂר",
    11: "אַחַת עֶשְׂרֵה", 12: "שְׁתֵּים עֶשְׂרֵה", 13: "שְׁלוֹשׁ עֶשְׂרֵה", 14: "אַרְבַּע עֶשְׂרֵה",
    15: "חֲמֵשׁ עֶשְׂרֵה", 16: "שֵׁשׁ עֶשְׂרֵה", 17: "שְׁבַע עֶשְׂרֵה", 18: "שְׁמוֹנֶה עֶשְׂרֵה",
    19: "תְּשַׁע עֶשְׂרֵה", 20: "עֶשְׂרִים", 21: "עֶשְׂרִים וְאַחַת", 22: "עֶשְׂרִים וּשְׁתַּיִם",
    23: "עֶשְׂרִים וְשָׁלוֹשׁ", 24: "עֶשְׂרִים וְאַרְבַּע", 25: "עֶשְׂרִים וְחָמֵשׁ",
    26: "עֶשְׂרִים וָשֵׁשׁ", 27: "עֶשְׂרִים וְשֶׁבַע", 28: "עֶשְׂרִים וּשְׁמוֹנֶה",
    29: "עֶשְׂרִים וְתֵשַׁע", 30: "שְׁלוֹשִׁים", 
    31: "שְׁלוֹשִׁים וְאַחַת", 32: "שְׁלוֹשִׁים וּשְׁתַּיִם", 33: "שְׁלוֹשִׁים וְשָׁלוֹשׁ",
    34: "שְׁלוֹשִׁים וְאַרְבַּע", 36: "שְׁלוֹשִׁים וָשֵׁשׁ", 37: "שְׁלוֹשִׁים וְשֶׁבַע",
    38: "שְׁלוֹשִׁים וּשְׁמוֹנֶה", 39: "שְׁלוֹשִׁים וְתֵשַׁע", 41: "אַרְבָּעִים וְאַחַת",
    42: "אַרְבָּעִים וּשְׁתַּיִם", 43: "אַרְבָּעִים וְשָׁלוֹשׁ", 44: "אַרְבָּעִים וְאַרְבַּע",
    46: "אַרְבָּעִים וָשֵׁשׁ", 47: "אַרְבָּעִים וְשֶׁבַע", 48: "אַרְבָּעִים וּשְׁמוֹנֶה",
    49: "אַרְבָּעִים וְתֵשַׁע", 51: "חֲמִשִּׁים וְאַחַת", 52: "חֲמִשִּׁים וּשְׁתַּיִם",
    53: "חֲמִשִּׁים וְשָׁלוֹשׁ", 54: "חֲמִשִּׁים וְאַרְבַּע", 56: "חֲמִשִּׁים וָשֵׁשׁ",
    57: "חֲמִשִּׁים וְשֶׁבַע", 58: "חֲמִשִּׁים וּשְׁמוֹנֶה", 59: "חֲמִשִּׁים וְתֵשַׁע"
}

MINUTES_MASC_SLANG = {
    5: "חֲמִשָּׁה", 10: "עֲשָׂרָה", 20: "עֶשְׂרִים", 25: "עֶשְׂרִים וַחֲמִשָּׁה"
}

def get_time_suffix(hour):
    if 2 <= hour < 5: return "לִפְנוֹת בֹּקֶר"
    elif 5 <= hour < 12: return "בַּבֹּקֶר"
    elif 12 <= hour < 16: return "בַּצָּהֳרַיִם"
    elif 16 <= hour < 19: return "אַחַר הַצָּהֳרַיִם"
    elif 19 <= hour < 21: return "בָּעֶרֶב"
    else: return "בַּלַּיְלָה"

def get_hebrew_time():
    now = datetime.now()
    h = now.hour
    m = now.minute
    h_12 = h if 1 <= h <= 12 else (h - 12 if h > 12 else 12)
    next_h = h + 1 if h < 23 else 0
    next_h_12 = next_h if 1 <= next_h <= 12 else (next_h - 12 if next_h > 12 else 12)
    suffix = get_time_suffix(h)
    if m >= 55: suffix = get_time_suffix(next_h)
    elif m >= 35 and m % 5 == 0: suffix = get_time_suffix(next_h)
    if m == 0:
        if h == 12: return "שְׁתֵּים עֶשְׂרֵה בַּצָּהֳרַיִם"
        if h == 0: return "חֲצוֹת"
        return f"{HOURS_FEM[h_12]} {suffix}"
    if m == 1: return f"{HOURS_FEM[h_12]} וְדַקָּה {suffix}"
    if m == 15: return f"{HOURS_FEM[h_12]} וָרֶבַע {suffix}"
    if m == 30: return f"{HOURS_FEM[h_12]} וָחֵצִי {suffix}"
    if m == 45: return f"רֶבַע לְ{HOURS_FEM[next_h_12]} {suffix}"
    if m >= 55:
        to_minute = 60 - m
        if to_minute == 5: return f"חֲמִשָּׁה לְ{HOURS_FEM[next_h_12]} {suffix}"
        elif to_minute == 1: return f"דַּקָּה לְ{HOURS_FEM[next_h_12]} {suffix}"
        else: return f"{MINUTES_FEM[to_minute]} דַּקּוֹת לְ{HOURS_FEM[next_h_12]} {suffix}"
    if m >= 35 and m % 5 == 0:
        to_minute = 60 - m
        min_str = MINUTES_MASC_SLANG.get(to_minute)
        return f"{min_str} לְ{HOURS_FEM[next_h_12]} {suffix}"
    is_round_5 = (m % 5 == 0)
    if is_round_5:
        min_str = MINUTES_MASC_SLANG.get(m, MINUTES_FEM[m])
        return f"{HOURS_FEM[h_12]} וְ{min_str} {suffix}"
    else:
        min_str = MINUTES_FEM[m]
        return f"{HOURS_FEM[h_12]} וְ{min_str} דַּקּוֹת {suffix}"

def get_hebrew_date_str():
    months = ["", "בְּיָנוּאָר", "בְּפֶבְּרוּאָר", "בְּמֶרְץ", "בְּאַפְּרִיל", "בְּמַאי", "בְּיוּנִי", "בְּיוּלִי", "בְּאוֹגוּסְט", "בְּסֶפְּטֶמְבֶּר", "בְּאוֹקְטוֹבֶּר", "בְּנוֹבֶמְבֶּר", "בְּדֵצֶמְבֶּר"]
    now = datetime.now()
    return f"{now.day} {months[now.month]} {now.year}"

def remove_niqqud(text):
    return re.sub(r'[\u0591-\u05C7]', '', text)
    
def get_startup_path():
    return os.path.join(os.getenv('APPDATA'), r'Microsoft\Windows\Start Menu\Programs\Startup', 'HebrewClock.lnk')

def create_shortcut():
    target = os.path.abspath(sys.argv[0])
    executable = sys.executable.replace("python.exe", "pythonw.exe")
    shortcut_path = get_startup_path()
    vbs_script = f"""
    Set oWS = WScript.CreateObject("WScript.Shell")
    Set oLink = oWS.CreateShortcut("{shortcut_path}")
    oLink.TargetPath = "{executable}"
    oLink.Arguments = Chr(34) & "{target}" & Chr(34)
    oLink.WorkingDirectory = "{os.path.dirname(target)}"
    oLink.Save
    """
    vbs_file = os.path.join(os.environ["TEMP"], "create_shortcut.vbs")
    with open(vbs_file, "w") as f: f.write(vbs_script)
    subprocess.call(["cscript", "//Nologo", vbs_file])
    os.remove(vbs_file)

def remove_shortcut():
    path = get_startup_path()
    if os.path.exists(path): os.remove(path)

def is_in_startup():
    return os.path.exists(get_startup_path())

class FloatingClock:
    def __init__(self):
        self.root = tk.Tk()
        self.config_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "clock_config.json")
        self.root.overrideredirect(True)
        self.root.wm_attributes("-topmost", True)
        self.root.wm_attributes("-toolwindow", True)
        
        self.font_family = "Segoe UI"
        self.font_weight = "normal" 
        self.custom_fonts_list = []
        self.custom_font_path = ""
        self.font_size = 14
        self.x_pos = 20
        self.y_pos = 0 
        self.text_color = "black"
        self.shadow_color = "white"
        self.show_bg = False
        self.custom_bg_color = "#404040"
        self.show_date = False
        self.show_shadow = True
        self.show_niqqud = True
        self.opacity = 1.0
        self.is_locked = False
        self.auto_color = False 
        
        self.current_text = ""
        self.current_date = ""
        
        self.load_config()
        self.update_transparent_color()
        self.root.wm_attributes("-alpha", self.opacity)
        
        self.canvas = tk.Canvas(self.root, highlightthickness=0)
        self.canvas.pack(fill=tk.BOTH, expand=True)

        self.shadow_id = self.canvas.create_text(2, 2, text="", fill=self.shadow_color, anchor="w")
        self.text_id = self.canvas.create_text(0, 0, text="", fill=self.text_color, anchor="w")
        self.date_shadow_id = self.canvas.create_text(2, 2, text="", fill=self.shadow_color, anchor="w")
        self.date_text_id = self.canvas.create_text(0, 0, text="", fill=self.text_color, anchor="w")

        self.menu = tk.Menu(self.root, tearoff=0)
        self.root.bind("<Button-3>", self.show_menu)
        self.root.bind("<Button-1>", self.start_move)
        self.root.bind("<B1-Motion>", self.do_move)
        self.root.bind("<ButtonRelease-1>", self.end_move) 
        self.root.bind("<MouseWheel>", self.resize_text)

        if self.y_pos == 0: self.calculate_initial_position()
        self.apply_background_state()
        self.update_clock()
        self.root.mainloop()

    def update_transparent_color(self):
        outer_color = self.shadow_color if self.show_shadow else self.text_color
        if outer_color in ["white", "yellow", "cyan", "#ffffff", "white"]:
            self.bg_color = "#FFFFFE" 
        else:
            self.bg_color = "#000001" 
        self.root.config(bg=self.bg_color)
        self.root.wm_attributes("-transparentcolor", self.bg_color)
        if hasattr(self, 'canvas') and not self.show_bg:
            self.canvas.config(bg=self.bg_color)

    def adapt_color_to_background(self):
        if not self.auto_color or self.show_bg: return
        try:
            hdc = ctypes.windll.user32.GetDC(None)
            x, y = self.root.winfo_x(), self.root.winfo_y()
            w, h = self.root.winfo_width(), self.root.winfo_height()
            
            points = [(x + 5, y + 5), (x + w - 5, y + 5), (x + 5, y + h - 5)]
            total_l = 0
            for px, py in points:
                pixel = ctypes.windll.gdi32.GetPixel(hdc, int(px), int(py))
                if pixel != -1:
                    r, g, b = pixel & 0xff, (pixel >> 8) & 0xff, (pixel >> 16) & 0xff
                    total_l += 0.299*r + 0.587*g + 0.114*b
            ctypes.windll.user32.ReleaseDC(None, hdc)
            
            target = "white" if (total_l / len(points)) < 128 else "black"
            if self.text_color != target: self._apply_color_internal(target)
        except: pass

    def load_config(self):
        if os.path.exists(self.config_file):
            try:
                with open(self.config_file, 'r') as f:
                    data = json.load(f)
                    self.x_pos, self.y_pos = data.get("x", 20), data.get("y", 0)
                    self.font_family = data.get("font_family", "Segoe UI")
                    self.font_weight = data.get("font_weight", "normal")
                    self.custom_fonts_list = data.get("custom_fonts_list", [])
                    self.custom_font_path = data.get("custom_font_path", "")
                    self.font_size = data.get("font_size", 14)
                    self.text_color = data.get("text_color", "black")
                    self.show_bg = data.get("show_bg", False)
                    self.custom_bg_color = data.get("custom_bg_color", "#404040")
                    self.show_date = data.get("show_date", False)
                    self.show_shadow = data.get("show_shadow", True)
                    self.show_niqqud = data.get("show_niqqud", True)
                    self.opacity = data.get("opacity", 1.0)
                    self.is_locked = data.get("is_locked", False)
                    self.auto_color = data.get("auto_color", False)
                    self.shadow_color = "white" if self.text_color == "black" else "black"
                    if self.custom_font_path and os.path.exists(self.custom_font_path):
                        ctypes.windll.gdi32.AddFontResourceExW(self.custom_font_path, 0x10, 0)
            except: pass 

    def save_config(self):
        data = {
            "x": self.root.winfo_x(), "y": self.root.winfo_y(), "font_family": self.font_family,
            "font_weight": self.font_weight, "custom_fonts_list": self.custom_fonts_list,
            "custom_font_path": self.custom_font_path, "font_size": self.font_size,
            "text_color": self.text_color, "show_bg": self.show_bg, "custom_bg_color": self.custom_bg_color,
            "show_date": self.show_date, "show_shadow": self.show_shadow, "show_niqqud": self.show_niqqud,
            "opacity": self.opacity, "is_locked": self.is_locked, "auto_color": self.auto_color
        }
        with open(self.config_file, 'w') as f: json.dump(data, f)

    def calculate_initial_position(self):
        self.y_pos = self.root.winfo_screenheight() - 100 

    def apply_background_state(self):
        self.canvas.config(bg=self.custom_bg_color if self.show_bg else self.bg_color)

    def update_clock(self):
        self.root.lift()
        self.root.wm_attributes("-topmost", True)
        if self.auto_color: self.adapt_color_to_background()
        raw_text, raw_date = get_hebrew_time(), get_hebrew_date_str()
        display_text = raw_text if self.show_niqqud else remove_niqqud(raw_text)
        display_date = raw_date if self.show_niqqud else remove_niqqud(raw_date)
        if display_text != self.current_text or display_date != self.current_date:
            self.current_text, self.current_date = display_text, display_date
            self.adjust_window_size(display_text, display_date)
        self.root.after(3000, self.update_clock)

    def adjust_window_size(self, time_text, date_text):
        tf = tkfont.Font(family=self.font_family, size=self.font_size, weight=self.font_weight)
        tw, th = tf.measure(time_text), tf.metrics("linespace")
        dfz = max(10, self.font_size - 2)
        df = tkfont.Font(family=self.font_family, size=dfz, weight="normal")
        dh = df.metrics("linespace") if self.show_date else 0
        w = max(tw, df.measure(date_text) if self.show_date else 0) + 20
        h = th + dh + 10
        self.canvas.config(width=w, height=h)
        self.root.geometry(f"{w}x{h}+{self.x_pos}+{self.y_pos}")
        ss = "normal" if self.show_shadow else "hidden"
        self.canvas.itemconfig(self.shadow_id, font=tf, text=time_text, state=ss)
        self.canvas.itemconfig(self.text_id, font=tf, text=time_text)
        self.canvas.coords(self.shadow_id, 4, th/2 + 2); self.canvas.coords(self.text_id, 2, th/2)
        if self.show_date:
            self.canvas.itemconfig(self.date_shadow_id, font=df, text=date_text, state=ss)
            self.canvas.itemconfig(self.date_text_id, font=df, text=date_text, state="normal")
            self.canvas.coords(self.date_shadow_id, 4, th + dh/2 + 2); self.canvas.coords(self.date_text_id, 2, th + dh/2)
        else:
            self.canvas.itemconfig(self.date_shadow_id, state="hidden"); self.canvas.itemconfig(self.date_text_id, state="hidden")

    def show_menu(self, event):
        self.menu.delete(0, tk.END)
        
        # תפריט גודל שעון
        size_menu = tk.Menu(self.menu, tearoff=0)
        size_menu.add_command(label="הגדל", command=lambda: self.menu_resize_text(1))
        size_menu.add_command(label="הקטן", command=lambda: self.menu_resize_text(-1))
        self.menu.add_cascade(label="גודל שעון", menu=size_menu)

        # תפריט גופן
        font_menu = tk.Menu(self.menu, tearoff=0)
        builtin_fonts = ["Segoe UI", "Arial", "Tahoma", "Calibri", "Times New Roman"]
        for f_name in builtin_fonts:
            font_menu.add_command(label=f_name, command=lambda val=f_name: self.change_font(val))
            
        if self.custom_fonts_list:
            font_menu.add_separator()
            for custom_f in self.custom_fonts_list:
                font_menu.add_command(label=custom_f, command=lambda val=custom_f: self.change_font(val))
                
        font_menu.add_separator()
        font_menu.add_command(label="טען קובץ פונט חדש...", command=self.pick_custom_font_file)
        self.menu.add_cascade(label="בחר גופן", menu=font_menu)

        # תפריט צבע טקסט
        color_menu = tk.Menu(self.menu, tearoff=0)
        
        auto_label = "✔ צבע אוטומטי (פעיל)" if self.auto_color else "הפעל התאמת צבע אוטומטית לרקע"
        color_menu.add_command(label=auto_label, command=self.toggle_auto_color)
        color_menu.add_separator()
        
        colors = [("שחור", "black"), ("לבן", "white"), ("אפור", "gray"), ("תכלת", "cyan"), ("צהוב", "yellow")]
        for c_name, c_val in colors:
            color_menu.add_command(label=c_name, command=lambda val=c_val: self.manual_change_color(val))
        color_menu.add_separator()
        color_menu.add_command(label="בחר צבע מותאם אישית...", command=self.pick_custom_text_color)
        self.menu.add_cascade(label="צבע טקסט", menu=color_menu)
        
        # תפריט נראות (ניקוד, משקל וצל)
        looks_menu = tk.Menu(self.menu, tearoff=0)
        
        weight_label = "הפוך לטקסט מודגש (Bold)" if self.font_weight == "normal" else "הפוך לטקסט רגיל (Normal)"
        looks_menu.add_command(label=weight_label, command=self.toggle_weight)
        
        shadow_label = "הסר צל לאותיות" if self.show_shadow else "הוסף צל לאותיות"
        looks_menu.add_command(label=shadow_label, command=self.toggle_shadow)
        
        niqqud_label = "הסר ניקוד" if self.show_niqqud else "הצג ניקוד"
        looks_menu.add_command(label=niqqud_label, command=self.toggle_niqqud)
        
        self.menu.add_cascade(label="תצוגה (משקל, ניקוד וצל)", menu=looks_menu)
        
        self.menu.add_separator()
        
        # תפריט צבע רקע
        bg_color_menu = tk.Menu(self.menu, tearoff=0)
        bg_colors = [("אפור כהה", "#404040"), ("שחור", "black"), ("לבן", "white"), ("כחול כהה", "#000040"), ("ירוק כהה", "#004000")]
        for c_name, c_val in bg_colors:
            bg_color_menu.add_command(label=c_name, command=lambda val=c_val: self.change_bg_color(val))
        bg_color_menu.add_separator()
        bg_color_menu.add_command(label="בחר צבע מותאם אישית...", command=self.pick_custom_bg_color)
        self.menu.add_cascade(label="בחר צבע רקע", menu=bg_color_menu)
        
        # הוספה/הסרת רקע
        bg_label = "הסר רקע (שקוף)" if self.show_bg else "הצג רקע צבוע (מונע טשטוש ופיקסול)"
        self.menu.add_command(label=bg_label, command=self.toggle_bg)

        self.menu.add_separator()
        
        # תפריט שקיפות חלון
        opacity_menu = tk.Menu(self.menu, tearoff=0)
        for pct, val in [("100%", 1.0), ("80%", 0.8), ("60%", 0.6), ("40%", 0.4)]:
            opacity_menu.add_command(label=pct, command=lambda v=val: self.change_opacity(v))
        self.menu.add_cascade(label="שקיפות חלון", menu=opacity_menu)
        
        # תפריט עגינה
        dock_menu = tk.Menu(self.menu, tearoff=0)
        dock_menu.add_command(label="ימין למעלה", command=lambda: self.dock("TR"))
        dock_menu.add_command(label="שמאל למעלה", command=lambda: self.dock("TL"))
        dock_menu.add_command(label="ימין למטה", command=lambda: self.dock("BR"))
        dock_menu.add_command(label="שמאל למטה", command=lambda: self.dock("BL"))
        self.menu.add_cascade(label="עגינה מהירה למסך", menu=dock_menu)
        
        self.menu.add_separator()
        
        # הוספה/הסרת תאריך
        date_label = "הסר תאריך" if self.show_date else "הצג תאריך"
        self.menu.add_command(label=date_label, command=self.toggle_date)
        
        # נעילת מיקום
        lock_label = "שחרר מיקום לגרירה" if self.is_locked else "נעל מיקום (מניעת הזזה)"
        self.menu.add_command(label=lock_label, command=self.toggle_lock)
        
        self.menu.add_separator()
        
        if is_in_startup():
            self.menu.add_command(label="הסר מהפעלה אוטומטית", command=self.toggle_startup)
        else:
            self.menu.add_command(label="הוסף להפעלה אוטומטית", command=self.toggle_startup)
        
        self.menu.add_separator()
        self.menu.add_command(label="סגור שעון", command=self.root.destroy)
        
        self.menu.post(event.x_root, event.y_root)

    def menu_resize_text(self, delta):
        self.font_size += delta
        self.save_config(); self.current_text = ""

    def change_font(self, new_font):
        self.font_family = new_font; self.save_config(); self.current_text = ""

    def pick_custom_font_file(self):
        path = filedialog.askopenfilename(filetypes=[("Font Files", "*.ttf *.otf")])
        if path:
            ctypes.windll.gdi32.AddFontResourceExW(path, 0x10, 0)
            fname = simpledialog.askstring("שם הפונט", "הקלד את שם הפונט המדויק:")
            if fname:
                if fname not in self.custom_fonts_list: self.custom_fonts_list.append(fname)
                self.change_font(fname)

    def toggle_auto_color(self):
        self.auto_color = not self.auto_color; self.save_config()

    def _apply_color_internal(self, new_color):
        self.text_color = new_color
        self.shadow_color = "white" if new_color == "black" else "black"
        self.update_transparent_color() 
        self.canvas.itemconfig(self.shadow_id, fill=self.shadow_color)
        self.canvas.itemconfig(self.text_id, fill=self.text_color)
        self.canvas.itemconfig(self.date_shadow_id, fill=self.shadow_color)
        self.canvas.itemconfig(self.date_text_id, fill=self.text_color)

    def manual_change_color(self, new_color):
        self.auto_color = False; self._apply_color_internal(new_color)

    def pick_custom_text_color(self):
        color = colorchooser.askcolor(color=self.text_color)
        if color[1]: self.manual_change_color(color[1])

    def toggle_weight(self):
        self.font_weight = "normal" if self.font_weight == "bold" else "bold"
        self.save_config(); self.current_text = ""

    def toggle_shadow(self):
        self.show_shadow = not self.show_shadow
        self.update_transparent_color(); self.save_config(); self.current_text = ""

    def toggle_niqqud(self):
        self.show_niqqud = not self.show_niqqud; self.save_config(); self.current_text = ""

    def change_bg_color(self, new_color):
        self.custom_bg_color = new_color; self.show_bg = True; self.save_config(); self.apply_background_state()

    def pick_custom_bg_color(self):
        color = colorchooser.askcolor(color=self.custom_bg_color)
        if color[1]: self.change_bg_color(color[1])

    def change_opacity(self, value):
        self.opacity = value; self.root.wm_attributes("-alpha", self.opacity); self.save_config()

    def dock(self, position):
        sw, sh = self.root.winfo_screenwidth(), self.root.winfo_screenheight()
        w, h = self.root.winfo_width(), self.root.winfo_height()
        m = 20
        if position == "TL": self.x_pos, self.y_pos = m, m
        elif position == "TR": self.x_pos, self.y_pos = sw - w - m, m
        elif position == "BL": self.x_pos, self.y_pos = m, sh - h - m
        elif position == "BR": self.x_pos, self.y_pos = sw - w - m, sh - h - m
        self.root.geometry(f"+{self.x_pos}+{self.y_pos}"); self.save_config()

    def toggle_date(self):
        self.show_date = not self.show_date; self.save_config(); self.current_text = ""

    def toggle_bg(self):
        self.show_bg = not self.show_bg; self.save_config()
        if not self.show_bg: self.update_transparent_color()
        else: self.apply_background_state()

    def toggle_lock(self):
        self.is_locked = not self.is_locked; self.save_config()

    def toggle_startup(self):
        if is_in_startup(): remove_shortcut()
        else: create_shortcut()

    def start_move(self, event):
        if not self.is_locked and (event.state & 0x0004):
            self.x_start, self.y_start = event.x, event.y

    def do_move(self, event):
        if not self.is_locked and (event.state & 0x0004):
            self.x_pos += event.x - self.x_start
            self.y_pos += event.y - self.y_start
            self.root.geometry(f"+{self.x_pos}+{self.y_pos}")

    def end_move(self, event):
        if not self.is_locked: self.save_config()

    def resize_text(self, event):
        if event.state & 0x0004:
            self.font_size += 1 if event.delta > 0 else -1
            self.save_config(); self.current_text = ""

if __name__ == "__main__":
    FloatingClock()