# -*- coding: utf-8 -*-
"""
action d'un filtre passe-bas d'ordre 1 sur un créneau
avec un contrôle externe sur la pulsation de coupure.
"""

import cmath
from math import *
from typing import Callable

import matplotlib.pyplot as plt
import numpy as np
import scipy.integrate as integr
from matplotlib.widgets import Button, Slider

def analyze_filter(input_signal: Callable[[float], float], period: float, sample_period: float, recording_periods: float):
    T=period      #periode du signal
    w=2*pi/T #pulsation du signal
    w0=1.0*w #pulsation de coupure du filtre
    Te=sample_period  #periode d'échantillonage
    D=recording_periods*T #durée d'acquisition
    Nb=int(D//Te) #nombre de points échantillonnés
    print(Nb, D, Te)
    fonc=input_signal

    
    # échantillonage signal d'entrée
    xn = np.zeros(Nb)
    for k in range(0,Nb):
        xn[k] = fonc(k*Te)


    ###################
    # ZONE A MODIFIER #
    ###################
        
    # calcul du signal filtré avec linéarisation d'Euler p=1/Te.(1-z^-1)
    def passe_bas(w00):
        values = [0.0] * len(xn)
        for k in range(1, len(values)):
            values[k] = 1/( 1+2/(Te*w00)
            )*(
                (2/(Te*w00))*values[k-1] + xn[k] + xn[k-1]
            )
        return values
        
    ##########################
    # FIN DE ZONE A MODIFIER #
    ##########################  


    #calcul de la FFT et troncage à la moitié pour ne pas visualiser le spectre miroir
    def fast_fourier(z):
        zf = abs(np.fft.fft(z))
        return(zf[0:Nb//2])

    #spectre du signal d'entrée
    print(xn)
    xft = fast_fourier(xn)
        
    # échelle des temps
    tt = np.linspace(0,D,Nb)

    #filtrage passe-bas
    yn = passe_bas(w0)
    print(yn)

    #spectre du signal de sortie
    yft = fast_fourier(yn)

    # échelle des fréquences
    f = np.linspace(0,1/(2*Te),Nb//2)

    fig,ax=plt.subplots()
    #plt.subplots()
    plt.subplots_adjust(bottom=0.25,wspace=0.3)


    plt.subplot(2,2,1)
    plt.title(u'''signal d'entrée échantillonné''')
    #dessin du signal échantillonné
    plt.plot(tt,xn,'bo')
    #plt.ylim(-0.2,1.2)

    plt.subplot(2,2,2)
    plt.title(u'réponse')
    #dessin du la réponse
    plt.grid()
    lrep,=plt.plot(tt,yn,'k-')


    plt.subplot(2,2,3)
    plt.title(u'''spectre du signal d'entrée''')
    #dessin du spectre du signal échantillonné
    plt.plot(f,xft)

    plt.subplot(2,2,4)
    plt.title(u'''spectre du signal de sortie''')
    #dessin du spectre du signal échantillonné
    lf,=plt.plot(f,yft,'r')      

    #boîte contenant le contrôle dynamique
    axcolor='yellow'
    axw0=plt.axes([0.15,0.1,0.6,0.03],facecolor=axcolor)

    sw0=Slider(axw0, r'$\omega_0/\omega$',0.1,10,valinit=w0/w)

    #action lorsque le contrôle dynamique est modifié
    #attention à changer les appels à la fonction si on change le nom passe_bas

    def update(val):
        w0=w*sw0.val
        lrep.set_ydata(passe_bas(w0))
        lf.set_ydata(fast_fourier(passe_bas(w0)))
        fig.canvas.draw_idle()

    sw0.on_changed(update)
    plt.show() 
