import cv2
import csv
import os
import numpy as np

# Chemin vers la vidéo
eye ='right'
nb = 1

video_path = f'.\\recording{nb}\\recording{nb}__{eye}.avi'
frame_folder = f'.\\recording{nb\\output_frames_{eye}'
contour_output_folder = f'.\\recording{nb}\\\\contour_frames_{eye}'


# Chemin du fichier CSV pour sauvegarder les centroïdes
csv_file_path = f'.\\recording{nb}\\centroids_{eye}.csv'
centroids_list, timestamps=[], []

# Créer un dossier pour sauvegarder les images binaires et un dossier pour sauvegarder les images avec les contours
if not os.path.exists(frame_folder):
    os.makedirs(frame_folder)
if not os.path.exists(contour_output_folder):
    os.makedirs(contour_output_folder)

# Lire la vidéo
cap = cv2.VideoCapture(video_path)

frame_number = 0

while True:
    # Lire la vidéo frame par frame
    ret, frame = cap.read()
    
    timestamp = cap.get(cv2.CAP_PROP_POS_MSEC) / 1000.0  # Get timestamp in seconds
    timestamps.append(timestamp)

    # Si la vidéo est terminée, on arrête la boucle
    if not ret:
        break
    
    # Convertir la frame en niveaux de gris
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    # Appliquer une transformation binaire avec un seuil
    _, binary_frame = cv2.threshold(gray_frame, 127, 255, cv2.THRESH_BINARY)
    
    # Sauvegarder l'image binaire
    frame_output_path = os.path.join(frame_folder, f'frame_{frame_number:04d}.png')
    cv2.imwrite(frame_output_path, binary_frame)


  
    # Détecter les contours
    contours, hierarchy = cv2.findContours(binary_frame, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    centroids = []

    # Trier les contours par taille (aire décroissante)
    contours = sorted(contours, key=cv2.contourArea, reverse=True)
    # Calculer les centroïdes des contours
    for contour in contours:
        M = cv2.moments(contour)
        if M["m00"] != 0:
            cX = int(M["m10"] / M["m00"])
            cY = int(M["m01"] / M["m00"])
            centroids.append((cX, cY))
        else:
            centroids.append((0, 0))

    # Initialiser les coordonnées, les tailles des deux plus gros centroïdes et leur distance
    x1, y1, x2, y2, s1, s2, d = None, None, None, None,
    None, None, None

    # Vérifier s'il y a au moins un centroid
    if len(centroids) > 0:
        x1, y1 = centroids[0]

    # Vérifier s'il y a au moins deux centroides
    if len(centroids) > 1:
        x2, y2 = centroids[1]

    # Vérifier si les coordonnées des centroïdes doivent être échangées
    if frame_number > 0 and centroids_list:
        prev_x1, prev_y1, prev_x2, prev_y2 = None, None, None, None
        for prev_centroid in reversed(centroids_list):
            if prev_x1 is None and prev_centroid[1] is not None:
                prev_x1 = prev_centroid[1]
            if prev_y1 is None and prev_centroid[2] is not None:
                prev_y1 = prev_centroid[2]
            if prev_x2 is None and prev_centroid[3] is not None:
                prev_x2 = prev_centroid[3]
            if prev_y2 is None and prev_centroid[4] is not None:
                prev_y2 = prev_centroid[4]
            if prev_x1 is not None and prev_y1 is not None and prev_x2 is not None and prev_y2 is not None:
                break
        if x1 is not None and y1 is not None and x2 is not None and y2 is not None:
            dist_s1_prev_s2 = np.sqrt((x1 - prev_x2) ** 2 + (y1 - prev_y2) ** 2)
            dist_s2_prev_s1 = np.sqrt((x2 - prev_x1) ** 2 + (y2 - prev_y1) ** 2)
            dist_s1_prev_s1 = np.sqrt((x1 - prev_x1) ** 2 + (y1 - prev_y1) ** 2)
            dist_s2_prev_s2 = np.sqrt((x2 - prev_x2) ** 2 + (y2 - prev_y2) ** 2)

            if dist_s1_prev_s1 > dist_s1_prev_s2 and dist_s2_prev_s2 > dist_s2_prev_s1:
                x2, y2 = centroids[0]
                x1, y1 = centroids[1]

    # Si le premier centroid disparaît, le deuxième reste en position 2
    if x1 == 0 and y1 == 0 and (x2 != 0 or y2 != 0):
        x1, y1 = x2, y2
        x2, y2 = None, None


    if x1 is not None and y1 is not None and x2 is not None and y2 is not None:
        d=np.sqrt((x1-x2)**2 + (y1-y2)**2)
    else :
        d=None
    centroids_list.append([timestamp, x1, y1, x2, y2, d])

    # Créer une image en couleur pour dessiner les contours
    contour_image = cv2.cvtColor(binary_frame, cv2.COLOR_GRAY2BGR)
    
    # Dessiner les contours sur l'image (couleur rouge)
    cv2.drawContours(contour_image, contours, -1, (0, 0, 255), 2)
    cv2.circle(contour_image, (x1, y1), 1, (0, 255, 0), -1)  # Dessiner le premier centroïde en vert
    cv2.circle(contour_image, (x2, y2), 1, (0, 255, 0), -1)  # Dessiner le premier centroïde en vert
    cv2.putText(contour_image, f'({x1},{y1}); ({x2}, {y2})', (5, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (0, 255, 0), 1)  # Ajouter un label au premier centroïde

    # Sauvegarder l'image avec les contours
    contour_output_path = os.path.join(contour_output_folder, f'contour_{frame_number:04d}.png')
    cv2.imwrite(contour_output_path, contour_image)
    
    frame_number += 1
    print(f'Processed frame {frame_number}')

# Libérer les ressources
cap.release()
cv2.destroyAllWindows()

# Écrire les centroïdes dans un fichier CSV
with open(csv_file_path, mode='w', newline='') as csv_file:
    csv_writer = csv.writer(csv_file)
    csv_writer.writerow(['time', 'x1', 'y1', 'x2', 'y2', 'd'])  # Écrire l'en-tête
    for centroid in centroids_list:
        csv_writer.writerow(centroid)