import tkinter as tk
import serial
import time
import math

# -------------------------
# CONFIGURATION
# -------------------------
SERIAL_PORT = "COM6"   # Change as needed
BAUD_RATE = 115200

GRID_SIZE = 10
BUTTON_COUNT = GRID_SIZE * GRID_SIZE


# -------------------------
# SERIAL SETUP
# -------------------------
ser = None
try:
    ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
    time.sleep(2)
except Exception as e:
    print("Could not open serial port:", e)


# -------------------------
# TKINTER SETUP
# -------------------------
root = tk.Tk()
root.title("Frequency Controller")

status_label = tk.Label(root, text="Ready", font=("Arial", 14))
status_label.grid(row=GRID_SIZE + 1, column=0, columnspan=GRID_SIZE, pady=10)

buttons = []


# -------------------------
# SEND
# -------------------------
def send_serial(msg):
    global ser
    if ser:
        ser.write(f"{msg}\n".encode())
        status_label.config(text=f"Sent: {msg}")
    else:
        status_label.config(text="Serial not available!")


# -------------------------
# TRUE LOG FREQUENCY MAPPING
# -------------------------
def log_frequency(i):
    """
    Logarithmic spacing from 0 to 1000 Hz.
    Using formula:

        f(i) = 1000 * (10^(i/99) - 1) / 9

    This ensures:
        f(0) = 0
        f(99) = 1000
    """

    if i == 0:
        return 0.0  # exact zero

    f = 1000 * (10**(i / (BUTTON_COUNT - 1)) - 1) / 9
    return f  # float, unique values


# -------------------------
# BUTTON PRESS HANDLER
# -------------------------
def handle_button_press(idx):
    freq = log_frequency(idx)
    freq_int = round(freq)

    # Reset colors
    for b in buttons:
        b.config(bg="SystemButtonFace")

    # Highlight active
    buttons[idx].config(bg="lightgreen")

    send_serial(freq_int)


# -------------------------
# CREATE 10×10 GRID
# -------------------------
index = 0
for r in range(GRID_SIZE):
    for c in range(GRID_SIZE):
        f = log_frequency(index)
        label = str(round(f))  # label rounded, internal value float

        btn = tk.Button(
            root,
            text=label,
            width=8,
            height=2,
            command=lambda i=index: handle_button_press(i)
        )
        btn.grid(row=r, column=c, padx=2, pady=2)

        buttons.append(btn)
        index += 1


root.mainloop()
