from .interfaz import *
from numpy import linspace, sin, cos, pi, radians, degrees

RESOLUTION = 1000

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

        # 2. Paneles de interacción con la gráfica        
        # 2.1. Slider del ángulo alpha
        self.panelAlpha = tk.Frame(self.panelDown)
        self.panelAlpha.pack(side='top', fill='x', expand=True)
        tk.Label(self.panelAlpha, text='α\n(grados)', font=TEXT_FONT, width=LABEL_GRAL_WIDTH).pack(side='left', padx=GRAL_PAD)
        self.sliderAlpha = tk.Scale(self.panelAlpha, from_=10, to=60, resolution=0.1, font=SLIDER_FONT, orient='horizontal', command=self.__updateAlpha)
        self.sliderAlpha.pack(side='left', fill='x', expand=True, padx=GRAL_PAD)
        self.sliderAlpha.set(60)
        self.alpha = radians(60)

        # 2.2. Slider del ángulo beta
        self.panelBeta = tk.Frame(self.panelDown)
        self.panelBeta.pack(side='top', fill='x', expand=True)
        tk.Label(self.panelBeta, text='β\n(grados)', font=TEXT_FONT, width=LABEL_GRAL_WIDTH).pack(side='left', padx=GRAL_PAD)
        self.sliderBeta = tk.Scale(self.panelBeta, from_=10, to=60, resolution=0.1, font=SLIDER_FONT, orient='horizontal', command=self.__updateBeta)
        self.sliderBeta.pack(side='left', fill='x', expand=True, padx=GRAL_PAD)
        self.sliderBeta.set(60)
        self.beta = radians(60)

        # 2.3. Slider del lado a
        self.panelA = tk.Frame(self.panelDown)
        self.panelA.pack(side='top', fill='x', expand=True)
        tk.Label(self.panelA, text='a', font=TEXT_FONT, width=LABEL_GRAL_WIDTH).pack(side='left', padx=GRAL_PAD)
        self.sliderA = tk.Scale(self.panelA, from_=3, to=10, resolution=0.01, font=SLIDER_FONT, orient='horizontal', command=self.__updateA)
        self.sliderA.pack(side='left', fill='x', expand=True, padx=GRAL_PAD)
        self.sliderA.set(10)
        self.a = 10

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

    def __checkReal(self, lado):
        if lado == 0 or isinstance(lado, complex):
           self.controlador.warningField(self.panelActual)
           return False
        return True

    def __getTriangulo(self):
        self.gamma = pi - (self.alpha + self.beta)
        self.b = self.a * sin(self.beta) / sin(self.alpha)
        self.c = self.a * sin(self.gamma) / sin(self.alpha)
        self.puntoA = [0, 0]
        self.puntoB = [self.c, 0]
        self.d = self.b * cos(self.alpha)
        self.e = self.a * cos(self.beta)
        self.h = (self.b**2 - self.d**2)**0.5
        self.puntoC = [self.d, self.h]
        return zip(self.puntoA, self.puntoB, self.puntoC, self.puntoA)

    def __updateGraph(self, _=None, *, init=False):
        x, y = self.__getTriangulo()
        scale = (self.a + self.b + self.c) / 100
        arcoAlphaX = [scale * cos(t) for t in linspace(0, self.alpha, 100)]
        arcoAlphaY = [scale * sin(t) for t in linspace(0, self.alpha, 100)]
        arcoBetaX = [self.c - scale * cos(t) for t in linspace(0, self.beta, 100)]
        arcoBetaY = [scale * sin(t) for t in linspace(0, self.beta, 100)]
        arcoGammaX = [self.d + scale * cos(t + pi + self.alpha) for t in linspace(0, self.gamma, 100)]
        arcoGammaY = [self.h + scale * sin(t + pi + self.alpha) for t in linspace(0, self.gamma, 100)]
        if init:
            self.ejes.set_aspect('equal')
            self.triangulo, = self.ejes.plot(x, y, color='black')
            self.textLadoC = self.ejes.text(self.c/2, 0, rf'$c={self.c:.3g}$', bbox=WHITE_TEXT_BBOX)
            self.textLadoA = self.ejes.text(self.d + self.e/2, self.h/2, rf'$a={self.a:.3g}$', bbox=WHITE_TEXT_BBOX)
            self.textLadoB = self.ejes.text(self.d/2, self.h/2, rf'$b={self.b:.3g}$', bbox=WHITE_TEXT_BBOX)
            self.arcoAlpha, = self.ejes.plot(arcoAlphaX, arcoAlphaY, color='red', label=rf'$\alpha={degrees(self.alpha):.3g}°$')
            self.arcoBeta, = self.ejes.plot(arcoBetaX, arcoBetaY, color='green', label=rf'$\beta={degrees(self.beta):.3g}°$')
            self.arcoGamma, = self.ejes.plot(arcoGammaX, arcoGammaY, color='blue', label=rf'$\gamma={degrees(self.gamma):.3g}°$')
            plt.legend()
        else:
            self.triangulo.set_data(x, y)
            self.textLadoC.set_position((self.c/2, 0))
            self.textLadoC.set_text(rf'$c={self.c:.3g}$')
            self.textLadoA.set_position((self.d + self.e/2, self.h/2))
            self.textLadoA.set_text(rf'$a={self.a:.3g}$')
            self.textLadoB.set_position((self.d/2, self.h/2))
            self.textLadoB.set_text(rf'$b={self.b:.3g}$')
            self.arcoAlpha.set_data(arcoAlphaX, arcoAlphaY)
            self.arcoBeta.set_data(arcoBetaX, arcoBetaY)
            self.arcoGamma.set_data(arcoGammaX, arcoGammaY)
            self.arcoAlpha.set_label(rf'$\alpha={degrees(self.alpha):.3g}°$')
            self.arcoBeta.set_label(rf'$\beta={degrees(self.beta):.3g}°$')
            self.arcoGamma.set_label(rf'$\gamma={degrees(self.gamma):.3g}°$')
            self.ejes.relim()
            self.ejes.autoscale_view()
            plt.legend()
            self.canvas.draw()

    def __updateA(self, _=None):
        self.a = self.sliderA.get()
        self.__updateGraph()

    def __updateAlpha(self, _=None):
        self.alpha = radians(self.sliderAlpha.get())
        self.__updateGraph()

    def __updateBeta(self, _=None):
        self.beta = radians(self.sliderBeta.get())
        self.__updateGraph()

def main():
    app = Controlador(
        title='III. Funciones — Teorema del Seno',
        firstFrame=TrigonometriaOperacionesBasicas,
        height=800, width=775
    )
    app.mainloop()
    
if __name__ == '__main__':
    main()
