import numpy as np

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from Codigo3D_Coefs import SHD,mcart_msph,msph_mcart
from colorama import Fore, Style 

import orthopoly
import Codigo3D_AjusteHelfrich as c3

def calculate_al(Datos,Lmaximo):
    
    cdata = SHD(name="SPH",Lmin=0,Lmax=Lmaximo,expansionMode="abs",radiusMode="expansion") # def clase
    
    ### CARGAMOS DATOS A LA CLASE
    
    factor = 7*10**5
    d1 = mcart_msph(Datos) # datos en esfericas
    d1[:,:,0] = d1[:,:,0]/factor # normalizamos el radio al orden de 10**-5 como los datos experimentales
    d1cart = msph_mcart(d1) # convertimos de nuevo a cartesianas pero con el cambio
    
    cdata.traj2 = d1cart # asignamos la trayectoria de la clase
    
    print(f"Tenemos: {Style.BRIGHT + Fore.GREEN}{Datos.shape[1]}{Style.RESET_ALL} partículas")
    print(f"En {Style.BRIGHT + Fore.GREEN}{Datos.shape[0]}{Style.RESET_ALL} instantes temporales")
    
    ### GENERAMOS UN GRID
    
    cdata.generateIcosahedralGrid(3)

    G2esf = cdata.gridVectorssph  # Puntos del grid en esfericas
    G2cart = cdata.gridVectors # Puntos del grid en cartesianas (sera exportado)

    print(f"Nuestro grid tiene: {Style.BRIGHT + Fore.GREEN}{G2cart.shape[0]}{Style.RESET_ALL} puntos")
    
    #### DISTRIBUIMOS TRAYECTORIA SOBRE GRID
    
    print("------")
    cdata.distributeTrajPointsAlongGrid()

    ProyeccionGrid = cdata.trajGrid # en cartesianas (sera exportado)
    
    #### CALCULAMOS LA VARIACION CON RESPECTO A LA SUPERFICIE PROMEDIO
    
    Superficie = np.mean(cdata.trajGridSph[:,:,0],axis = 0)
    
    VariacionSuper = cdata.trajGridSph
    VariacionSuper[:,:,0] = VariacionSuper[:,:,0] - Superficie # Por defecto resta en cada fila
    
    #### DESARROLLO EN ARMONICOS ESFERICOS
    
    '''
    NOTA: los armonicos esfericos se hacen a partir de la variacion no directamente de la proyeccion del grid
    '''
    
    cdata.sphericalHarmonicExpansion(VariacionSuper) 
    
    cdata.trajGridSph = mcart_msph(ProyeccionGrid) # Solucion a un bug, que asigna a la proyeccion variacion super
    
    #### CALCULO DE LOS VALORES MEDIOS Y DETERMINACION DE AL
    
    cdata.valoresmedios(cdata.trajGridSph) # solo tiene el input para calcular R0. Se calcula R0 del general no de la variacion

    coefs_al2 = cdata.VM_AlCuadrado
    r0 = cdata.R0
    
    lmain = np.linspace(0,Lmaximo,Lmaximo+1)
    terminol = lmain*(lmain+1)*(lmain-1)*(lmain+2)
    
    return G2cart,ProyeccionGrid,terminol,coefs_al2,r0