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

RESOLUTION = 1000
MAX_TIME = 6
A = 5
F = 1/6
PHI = -pi/2

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

        # 2. Panel de interacción con la gráfica
        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=7).pack(side='left', padx=GRAL_PAD)
        self.sliderTiempo = tk.Scale(self.panelTiempo, from_=0, to=MAX_TIME, resolution=0.001, font=SLIDER_FONT, orient='horizontal', command=self.__updateGraph)
        self.sliderTiempo.pack(side='left', fill='x', expand=True, padx=GRAL_PAD)
        self.sliderTiempo.set(0)

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

    def aCV(self, t):
        return A * sin(self.omega * t + PHI)

    def fasorRe(self, t):
        return -A * cos(pi * t / 3)

    def fasorIm(self, t):
        return -A * sin(pi * t / 3)

    def __updateGraph(self, _=None, *, init=False):
        if init:
            self.t = linspace(0, MAX_TIME, RESOLUTION)
            self.markT = self.t[0]
            self.omega = 2 * pi * F
            markY = self.aCV(self.markT)
            self.ejes[0].plot(self.t, [5] * 1000, color='red', label=rf'$V_{{DC}}(t)={A}$')
            self.ejes[0].plot(self.t, self.aCV(self.t), color='blue', label=rf'$V_{{AC}}(t)={A}\cdot\sin{{({self.omega:.3f}t{PHI:.3f})}}$')
            self.markPointAC, = self.ejes[0].plot(self.markT * 1000, markY, color='blue', marker='o', linewidth=0, label=rf'$({self.markT}, {markY:.3f})$')
            self.markPointDC, = self.ejes[0].plot(self.markT * 1000, A, color='red', marker='o', linewidth=0, label=rf'$({self.markT}, {A})$')
            fasorRe = self.fasorRe(self.markT)
            fasorIm = self.fasorIm(self.markT)
            self.fasorVectorAC = self.ejes[1].quiver(0, 0, fasorRe, fasorIm, angles='xy', scale_units='xy', scale=1, color='blue', label=rf'({fasorRe:.3f}, {fasorIm:.3f})')
            self.ejes[1].quiver(0, 0, A, 0, angles='xy', scale_units='xy', scale=1, color='red', label=rf'$({A}, 0)$')
            for i in range(2):        
                self.ejes[i].axhline(0, color='black', linestyle='dashed', zorder=0)
                self.ejes[i].axvline(0, color='black', linestyle='dashed', zorder=0)
                self.ejes[i].grid(True)
                self.ejes[i].legend()
            self.ejes[0].set_xlabel('Tiempo\n(ms)')
            self.ejes[0].set_ylabel('Voltaje\n(V)')
            self.ejes[1].set_xlabel('Parte real')
            self.ejes[1].set_ylabel('Parte imaginaria')
            self.ejes[1].set_xlim([-A-1, A+1])
            self.ejes[1].set_ylim([-A-1, A+1])
            plt.tight_layout()
        else:
            self.markT = self.sliderTiempo.get()
            markY = self.aCV(self.markT)
            self.markPointAC.set_data([self.markT], [markY])
            self.markPointAC.set_label(rf'$({self.markT}, {markY:.3f})$')
            self.markPointDC.set_data([self.markT], [A])
            self.markPointDC.set_label(rf'$({self.markT}, {A})$')
            fasorRe = self.fasorRe(self.markT)
            fasorIm = self.fasorIm(self.markT)
            self.fasorVectorAC.set_UVC(fasorRe, fasorIm)
            self.fasorVectorAC.set_label(rf'({fasorRe:.3f}, {fasorIm:.3f})')
            self.ejes[0].legend()
            self.ejes[1].legend()
            self.canvas.draw()

def main():
    app = Controlador(
        title='V. Números complejos — Corriente alterna vs. Corriente continua',
        firstFrame=ACDCFrame,
        height=725, width=1500
    )
    app.mainloop()

if __name__ == '__main__':
    main()
