import tkinter as tk
from tkinter import ttk
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

# Función para graficar
def actualizar_grafico(*args):
    try:
        n_motor = rpm_var.get()
        cpr = int(entry_cpr.get())
        fSampleo = float(entry_fs.get())
        desfase = float(entry_desfase.get())
        numCiclos = float(entry_ciclos.get())
    except ValueError:
        return

    fEncoder = n_motor * cpr / 60
    samples = 1000

    if fEncoder == 0:
        ax.clear()
        ax.set_title("RPM = 0, no hay señal.")
        canvas.draw()
        return

    t = np.linspace(0, numCiclos / fEncoder, samples, endpoint=False)
    desfase_rad = desfase * np.pi / 180

    ChnA = signal.square(2 * np.pi * fEncoder * t + desfase_rad)
    ChnB = signal.square(2 * np.pi * fEncoder * t + desfase_rad - np.pi/2)

    periodo = 1 / fSampleo
    puntos_verticales = np.arange(0, numCiclos / fEncoder, periodo)

    ax.clear()
    if var_sampleo.get():
        for x in puntos_verticales:
            ax.axvline(x=x, color='red', linestyle='--', linewidth=1.2)

    if var_chnA.get():
        ax.plot(t, ChnA, label='Canal A')
    if var_chnB.get():
        ax.plot(t, ChnB, label='Canal B')

    ax.set_title(f"RPM={n_motor}, CPR={cpr}, fs={fSampleo/1000:.1f}kHz, desfase={desfase}°, ciclos={numCiclos}")
    ax.set_xlabel("Tiempo [s]")
    ax.set_ylabel("Amplitud")
    ax.legend()
    canvas.draw()

# Crear ventana principal
root = tk.Tk()
root.title("Visualizador de Encoder y Sampleo")

# Frame izquierdo con padding
frame = ttk.Frame(root, padding=10)
frame.pack(side=tk.LEFT, fill=tk.Y)

font = ("Arial", 11)

# Slider de RPM con paso de 10
ttk.Label(frame, text="RPM:", font=font).pack(anchor="w", pady=5)
rpm_var = tk.DoubleVar(value=100)

def actualizar_rpm_label(val):
    val = float(val)
    stepped_val = round(val / 10) * 10
    rpm_var.set(stepped_val)
    label_rpm_val.config(text=f"{stepped_val:.0f}")
    actualizar_grafico()

slider_rpm = ttk.Scale(frame, from_=10, to=3000, orient='horizontal',
                       variable=rpm_var, command=actualizar_rpm_label)
slider_rpm.pack(fill=tk.X, pady=2)

label_rpm_val = ttk.Label(frame, text="100", font=font)
label_rpm_val.pack(pady=(0, 10))

# Entrada CPR
ttk.Label(frame, text="CPR:", font=font).pack(anchor="w", pady=5)
entry_cpr = ttk.Entry(frame, font=font)
entry_cpr.insert(0, "500")
entry_cpr.pack(fill=tk.X)

# Entrada Frecuencia de sampleo
ttk.Label(frame, text="Frecuencia de sampleo (Hz):", font=font).pack(anchor="w", pady=5)
entry_fs = ttk.Entry(frame, font=font)
entry_fs.insert(0, "25000")
entry_fs.pack(fill=tk.X)

# Entrada Desfase
ttk.Label(frame, text="Desfase (grados):", font=font).pack(anchor="w", pady=5)
entry_desfase = ttk.Entry(frame, font=font)
entry_desfase.insert(0, "0")
entry_desfase.pack(fill=tk.X)

# Entrada Número de ciclos
ttk.Label(frame, text="Número de ciclos:", font=font).pack(anchor="w", pady=5)
entry_ciclos = ttk.Entry(frame, font=font)
entry_ciclos.insert(0, "3")
entry_ciclos.pack(fill=tk.X)

# Checkboxes
var_chnA = tk.BooleanVar(value=True)
chk_chnA = ttk.Checkbutton(frame, text="Mostrar Canal A", variable=var_chnA, command=actualizar_grafico)
chk_chnA.pack(anchor="w", pady=5)

var_chnB = tk.BooleanVar(value=True)
chk_chnB = ttk.Checkbutton(frame, text="Mostrar Canal B", variable=var_chnB, command=actualizar_grafico)
chk_chnB.pack(anchor="w", pady=5)

var_sampleo = tk.BooleanVar(value=True)
chk_sampleo = ttk.Checkbutton(frame, text="Mostrar líneas de sampleo", variable=var_sampleo, command=actualizar_grafico)
chk_sampleo.pack(anchor="w", pady=5)

# Botón actualizar
ttk.Button(frame, text="Actualizar", command=actualizar_grafico).pack(pady=15)

# Canvas matplotlib
fig, ax = plt.subplots(figsize=(8.8, 4.4))  # Aumentado un 10%
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.get_tk_widget().pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)

# Inicializar
actualizar_grafico()
root.mainloop()
