import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

# --- Demande à l'utilisateur ---
user_input = input("GIF ? (o/n) : ").strip().lower()
GENERATE_GIF = user_input == 'o'

# --- Fichiers ---
ref_file = "constellation_ref.dat"   # constellation de référence
rx_file = "constellation.dat"        # symboles corrigés par la PLL

# Charger les données
ref_constel = np.loadtxt(ref_file)  # colonnes I Q
rx_data = np.loadtxt(rx_file)       # colonnes I Q

# Paramètres
window_size = 50   # nombre de symboles à afficher dans la fenêtre
speed_factor = 5   # pour accélérer l'animation
N_frames = len(rx_data)

# Figure
fig, ax = plt.subplots(figsize=(6,6))
ax.set_title("Rolling Constellation avec PLL")
ax.set_xlabel("I")
ax.set_ylabel("Q")
ax.grid(True)

# Constellation de référence
ax.scatter(ref_constel[:,0], ref_constel[:,1], c='red', marker='x', label='Référence')

# Points PLL
scat = ax.scatter([], [], c='blue', s=20, label='Points récents')
last_point = ax.scatter([], [], c='green', s=50, label='Dernier symbole')

ax.set_xlim(np.min(ref_constel[:,0])-0.5, np.max(ref_constel[:,0])+0.5)
ax.set_ylim(np.min(ref_constel[:,1])-0.5, np.max(ref_constel[:,1])+0.5)
ax.legend()

# Initialisation
def init():
    scat.set_offsets(np.empty((0,2)))
    last_point.set_offsets(np.empty((0,2)))
    return scat, last_point

# Mise à jour
def update(frame):
    idx = min(frame*speed_factor, N_frames)
    start_idx = max(0, idx - window_size)
    data_window = rx_data[start_idx:idx]
    
    scat.set_offsets(data_window)
    if len(data_window) > 0:
        last_point.set_offsets(data_window[-1:])
    return scat, last_point

# Création de l'animation
ani = FuncAnimation(fig, update, frames=int(N_frames/speed_factor)+1,
                    init_func=init, blit=True, interval=20)

# --- Sauvegarde GIF conditionnelle ---
if GENERATE_GIF:
    ani.save("pll_constellation.gif", writer='pillow', fps=30)
    print("GIF généré : pll_constellation.gif")

# Affichage à l'écran
plt.show()

