#!/usr/bin/env python3
# GUI: сохраняет control.json, отправляет UDP; добавлена смена тем, фурьей-мордочка и управление ушами
import sys, os, json, threading, time, socket
try:
    import tkinter as tk
    from tkinter import ttk, colorchooser, messagebox
except Exception as e:
    print("tkinter ошибка:", e)
    sys.exit(1)

# Pillow (опционально, для картинки)
try:
    from PIL import Image, ImageTk
    PIL_AVAILABLE = True
except Exception:
    PIL_AVAILABLE = False

modules_dir = sys.argv[1] if len(sys.argv) > 1 else "./Modules"
controls_dir = os.path.join(modules_dir, "controls")
os.makedirs(controls_dir, exist_ok=True)
control_file = os.path.join(controls_dir, "control.json")
status_file = os.path.join(controls_dir, "status.json")

# UDP settings (must match module)
UDP_STATUS_PORT = 6000  # receive statuses here
UDP_CONTROL_PORT = 6001 # send controls to module here
UDP_HOST = "127.0.0.1"

DEFAULTS = {
    "enabled": True,
    "audiolinkEnabled": False,
    "audiolinkIntensity": 0.6,
    "audiolinkColor": "#00ffcc",
    "emotions": {"smile":0.0, "frown":0.0, "surprise":0.0},
    "mouthSliders": {"mouthOpen":0.1, "mouthSmileLeft":0.0, "mouthSmileRight":0.0},
    # ear params
    "ears": {
        "left": {"angle": -10.0, "offset_x": -30.0, "offset_y": -20.0, "scale": 1.0},
        "right": {"angle": 10.0,  "offset_x": 30.0,  "offset_y": -20.0, "scale": 1.0}
    }
}

def load_control():
    if os.path.isfile(control_file):
        try:
            with open(control_file, "r", encoding="utf-8") as f:
                data = json.load(f)
            # ensure ears exist
            if "ears" not in data:
                data["ears"] = DEFAULTS["ears"]
            return data
        except Exception as e:
            print(f"Error loading control file: {e}")
    return DEFAULTS.copy()

def save_control(data):
    try:
        with open(control_file, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2, ensure_ascii=False)
    except Exception as e:
        print(f"Error saving control file: {e}")

def send_udp(message, port):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.sendto(message.encode('utf-8'), (UDP_HOST, port))
    except Exception as e:
        print(f"UDP send error: {e}")

def udp_listener(port, callback):
    def listen():
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            sock.bind((UDP_HOST, port))
            while True:
                data, _ = sock.recvfrom(1024)
                callback(data.decode('utf-8'))
        except Exception as e:
            print(f"UDP listener error: {e}")
    threading.Thread(target=listen, daemon=True).start()

class App:
    def init(self, root):
        self.root = root
        self.control_data = load_control()
        self.setup_ui()
        udp_listener(UDP_STATUS_PORT, self.on_status)

    def setup_ui(self):
        # ... (UI setup code)

    def on_status(self, status):
        # ... (status handling code)

if name == "main":
    root = tk.Tk()
    app = App(root)
    root.mainloop()
