from .interfaz import *
from numpy import linspace, sin, pi
from sympy import symbols, sympify, solve, latex

RESOLUTION = 1000
A = 220
MAX_FREQUENCY = 120
MAX_TIME = 0.04

class TrigonometriaVoltajeFrame(SimpleInteractiveGraphFrame):
    def __init__(self, controlador):
        self.controlador = controlador
        super().__init__(controlador)
        
        # 1. Inicialización de interfaz general
        self.setPanels(toolBar=False)

        # 2. Paneles de interacción con la gráfica
        # 2.1. Panel de frecuencia
        self.panelFrecuencia = tk.Frame(self.panelDown)
        self.panelFrecuencia.pack(fill='x', expand=True)
        tk.Label(self.panelFrecuencia, text='Frecuencia\n(Hz)', font=TEXT_FONT, width=LABEL_GRAL_WIDTH).pack(side='left', padx=GRAL_PAD)
        self.sliderFrecuencia = tk.Scale(self.panelFrecuencia, from_=1, to=MAX_FREQUENCY, font=SLIDER_FONT, resolution=1, orient='horizontal', command=self.__updateFrecuencia)
        self.sliderFrecuencia.pack(side='left', fill='x', expand=True, padx=GRAL_PAD)
        self.sliderFrecuencia.set(50)

        # 2.1. Panel de tiempo
        self.panelTiempo = tk.Frame(self.panelDown)
        self.panelTiempo.pack(fill='x', expand=True)
        tk.Label(self.panelTiempo, text='Tiempo\n(ms)', font=TEXT_FONT, width=LABEL_GRAL_WIDTH).pack(side='left', padx=GRAL_PAD)
        self.sliderTiempo = tk.Scale(self.panelTiempo, from_=0, to=MAX_TIME * 1000, font=SLIDER_FONT, resolution=0.1, orient='horizontal', command=self.__updateTiempo)
        self.sliderTiempo.pack(side='left', fill='x', expand=True, padx=GRAL_PAD)
        self.sliderTiempo.set(0)

        # 3. Gráfica
        self.__updateGraph(init=True)

    def v(self, t):
        return A * sin(self.omega * t)

    def __updateGraph(self, _=None, *, init=False):
        if init:
            self.t = np.linspace(0, MAX_TIME, RESOLUTION)
            self.markT = 0
            self.f = 50
            self.omega = 2 * pi * self.f
            vY = self.v(self.t)
            self.lineV, = self.ejes.plot(self.t * 1000, vY, color='blue', label=rf'$V(t)={A}\cdot\sin{{({self.omega:.3g}t)}}$')
            markY = self.v(self.markT)
            self.markPoint, = self.ejes.plot(self.markT * 1000, markY, color='red', marker='o', linewidth=0, label=rf'$({self.markT:.3g}, {markY:.3g})$')
            self.setLineasEjes(self.ejes)
            self.ejes.set_xlabel('Tiempo\n(ms)')
            self.ejes.set_ylabel('Voltaje\n(V)')
            self.ejes.grid(True)
            plt.legend()
            plt.tight_layout()
        else:
            markY = self.v(self.markT)
            self.lineV.set_data(self.t * 1000, self.v(self.t))
            self.lineV.set_label(rf'$V(t)={A}*\sin{{({self.omega:.3g}t)}}$')
            self.markPoint.set_data([self.markT * 1000], [markY])
            self.markPoint.set_label(rf'$({self.markT:.3g}, {markY:.3g})$')
            plt.legend()
            self.canvas.draw()

    def __updateFrecuencia(self, _=None):
        self.f = self.sliderFrecuencia.get()
        self.omega = 2 * pi * self.f
        self.__updateGraph()

    def __updateTiempo(self, _=None):
        self.markT = self.sliderTiempo.get() / 1000
        self.__updateGraph()

def main():
    app = Controlador(
        title='III. Funciones — Voltaje',
        firstFrame=TrigonometriaVoltajeFrame,
        height=800, width=775
    )
    app.mainloop()

if __name__ == '__main__':
    main()
