import numpy as np
import math
import statistics
from matplotlib import pyplot as plt

def convertPixelToCm (calibration, fps, xLE, yLE, xRE, yRE):
    # Calibration interval separated to invidudual position
    calibrationFull = list(range(calibration[0], calibration[1]))
    
    def split_list_into_intervals(calibrationFull, fps):
        interval_size = int(2 * fps)  # Calculate the number of elements for each interval
        num_intervals = len(calibrationFull) // interval_size  # Calculate the number of intervals
        
        intervals = []
        for i in range(num_intervals):
            start_index = i * interval_size
            end_index = (i + 1) * interval_size
            interval = calibrationFull[start_index:end_index - 1]
            intervals.append(interval)
        
        return intervals
    
    intervals = split_list_into_intervals(calibrationFull, fps)
    
    modified_intervals = []

    for interval in intervals:
        first_value = interval[0]
        last_value = interval[-1]
        modified_interval = [first_value, last_value + 1]
        modified_intervals.append(modified_interval)
        
    calibrationXLE = []

    for interval in modified_intervals:
        start_index = interval[0]
        end_index = interval[1]
        sublist = xLE[start_index:end_index]
        calibrationXLE.append(sublist)
        
    calibrationYLE = []

    for interval in modified_intervals:
        start_index = interval[0]
        end_index = interval[1]
        sublist = yLE[start_index:end_index]
        calibrationYLE.append(sublist)
        
    calibrationXRE = []

    for interval in modified_intervals:
        start_index = interval[0]
        end_index = interval[1]
        sublist = xRE[start_index:end_index]
        calibrationXRE.append(sublist)
        
    calibrationYRE = []

    for interval in modified_intervals:
        start_index = interval[0]
        end_index = interval[1]
        sublist = yRE[start_index:end_index]
        calibrationYRE.append(sublist)
    
    time_axis = range(fps * 2)
    time_axis = [x / fps for x in time_axis]
    
    for interval in calibrationXLE:
        plt.plot(time_axis[:len(interval)], interval)

    num = 9
    plt.plot(time_axis[:len(calibrationXLE[num])], calibrationXLE[num])

    plt.xlabel('Time [seconds]')
    plt.ylabel('Pixel Value')
    plt.title('Calibration curves of position x for Left Eye over time')
    
    # plt.legend(range(1, len(calibrationXLE) + 1))
    plt.savefig("CalibrationOverTime.pdf")
    plt.show()
    
    centerPointPixelOneLE = [statistics.median(calibrationXLE[0]), statistics.median(calibrationYLE[0])]
    centerPointPixelTwoLE = [statistics.median(calibrationXLE[9]), statistics.median(calibrationYLE[9])]
    centerPointPixelOneRE = [statistics.median(calibrationXRE[0]), statistics.median(calibrationYRE[0])]
    centerPointPixelTwoRE = [statistics.median(calibrationXRE[9]), statistics.median(calibrationYRE[9])]
    
    leftUpPointPixelOneLE = [statistics.median(calibrationXLE[1]), statistics.median(calibrationYLE[1])]
    leftUpPointPixelTwoLE = [statistics.median(calibrationXLE[5]), statistics.median(calibrationYLE[5])]
    leftUpPointPixelOneRE = [statistics.median(calibrationXRE[1]), statistics.median(calibrationYRE[1])]
    leftUpPointPixelTwoRE = [statistics.median(calibrationXRE[5]), statistics.median(calibrationYRE[5])]

    rightUpPointPixelOneLE = [statistics.median(calibrationXLE[2]), statistics.median(calibrationYLE[2])]
    rightUpPointPixelTwoLE = [statistics.median(calibrationXLE[6]), statistics.median(calibrationYLE[6])]
    rightUpPointPixelOneRE = [statistics.median(calibrationXRE[2]), statistics.median(calibrationYRE[2])]
    rightUpPointPixelTwoRE = [statistics.median(calibrationXRE[6]), statistics.median(calibrationYRE[6])]
       
    rightDownPointPixelOneLE = [statistics.median(calibrationXLE[3]), statistics.median(calibrationYLE[3])]
    rightDownPointPixelTwoLE = [statistics.median(calibrationXLE[7]), statistics.median(calibrationYLE[7])]
    rightDownPointPixelOneRE = [statistics.median(calibrationXRE[3]), statistics.median(calibrationYRE[3])]
    rightDownPointPixelTwoRE = [statistics.median(calibrationXRE[7]), statistics.median(calibrationYRE[7])]
 
    leftDownPointPixelOneLE = [statistics.median(calibrationXLE[4]), statistics.median(calibrationYLE[4])]
    leftDownPointPixelTwoLE = [statistics.median(calibrationXLE[8]), statistics.median(calibrationYLE[8])]
    leftDownPointPixelOneRE = [statistics.median(calibrationXRE[4]), statistics.median(calibrationYRE[4])]
    leftDownPointPixelTwoRE = [statistics.median(calibrationXRE[8]), statistics.median(calibrationYRE[8])]
    
    
    centerPointPixelLE = []
    centerPointPixelLE.append(statistics.mean([centerPointPixelOneLE[0], centerPointPixelTwoLE[0]]))
    centerPointPixelLE.append(statistics.mean([centerPointPixelOneLE[1], centerPointPixelTwoLE[1]]))
    centerPointPixelRE = []
    centerPointPixelRE.append(statistics.mean([centerPointPixelOneRE[0], centerPointPixelTwoRE[0]]))
    centerPointPixelRE.append(statistics.mean([centerPointPixelOneRE[1], centerPointPixelTwoRE[1]]))
    
    leftUpPixelLE = []
    leftUpPixelLE.append(statistics.mean([leftUpPointPixelOneLE[0], leftUpPointPixelTwoLE[0]]))
    leftUpPixelLE.append(statistics.mean([leftUpPointPixelOneLE[1], leftUpPointPixelTwoLE[1]]))
    leftUpPixelRE = []
    leftUpPixelRE.append(statistics.mean([leftUpPointPixelOneRE[0], leftUpPointPixelTwoRE[0]]))
    leftUpPixelRE.append(statistics.mean([leftUpPointPixelOneRE[1], leftUpPointPixelTwoRE[1]]))
    
    rightUpPixelLE = []
    rightUpPixelLE.append(statistics.mean([rightUpPointPixelOneLE[0], rightUpPointPixelTwoLE[0]]))
    rightUpPixelLE.append(statistics.mean([rightUpPointPixelOneLE[1], rightUpPointPixelTwoLE[1]]))
    rightUpPixelRE = []
    rightUpPixelRE.append(statistics.mean([rightUpPointPixelOneRE[0], rightUpPointPixelTwoRE[0]]))
    rightUpPixelRE.append(statistics.mean([rightUpPointPixelOneRE[1], rightUpPointPixelTwoRE[1]]))
    
    rightDownPixelLE = []
    rightDownPixelLE.append(statistics.mean([rightDownPointPixelOneLE[0], rightDownPointPixelTwoLE[0]]))
    rightDownPixelLE.append(statistics.mean([rightDownPointPixelOneLE[1], rightDownPointPixelTwoLE[1]]))
    rightDownPixelRE = []
    rightDownPixelRE.append(statistics.mean([rightDownPointPixelOneRE[0], rightDownPointPixelTwoRE[0]]))
    rightDownPixelRE.append(statistics.mean([rightDownPointPixelOneRE[1], rightDownPointPixelTwoRE[1]]))
    
    leftDownPixelLE = []
    leftDownPixelLE.append(statistics.mean([leftDownPointPixelOneLE[0], leftDownPointPixelTwoLE[0]]))
    leftDownPixelLE.append(statistics.mean([leftDownPointPixelOneLE[1], leftDownPointPixelTwoLE[1]]))
    leftDownPixelRE = []
    leftDownPixelRE.append(statistics.mean([leftDownPointPixelOneRE[0], leftDownPointPixelTwoRE[0]]))
    leftDownPixelRE.append(statistics.mean([leftDownPointPixelOneRE[1], leftDownPointPixelTwoRE[1]]))
    
    ###########################################################################
    positionsPixel = [leftUpPixelLE, rightUpPixelLE, rightDownPixelLE, leftDownPixelLE]
    
    monitorWidthCm = 62
    monitorHeightCm = 29
    
    convertFactorPixelCmLE_X = monitorWidthCm / (positionsPixel[1][0] - positionsPixel[0][0])
    convertFactorPixelCmLE_Y = monitorHeightCm / (positionsPixel[3][1] - positionsPixel[0][1])
    
    # pixel = [calibrationXLE[0][0], calibrationYLE[0][0]]
    pixel = [189.5, 108.0]
    pixelCM = [(pixel[0] - positionsPixel[0][0]) * convertFactorPixelCmLE_X, (pixel[1] - positionsPixel[0][1]) * convertFactorPixelCmLE_Y]

    ###########################################################################
    # Real positions of center and corners in pixels
    left_eye_center_pixels = centerPointPixelLE
    left_eye_top_left_corner_pixels = leftUpPixelLE
    left_eye_top_right_corner_pixels = rightUpPixelLE
    left_eye_bottom_left_corner_pixels = leftDownPixelLE
    left_eye_bottom_right_corner_pixels = rightDownPixelLE
    
    # Real positions of center and corners for right eye in pixels
    right_eye_center_pixels = centerPointPixelRE
    right_eye_top_left_corner_pixels = leftUpPixelRE
    right_eye_top_right_corner_pixels = rightUpPixelRE
    right_eye_bottom_left_corner_pixels = leftDownPixelRE
    right_eye_bottom_right_corner_pixels = rightDownPixelRE
    
    # Real positions of center and corners in centimeters
    center_position_cm = [0, 0]
    top_left_corner_cm = [-31, 14.5]
    top_right_corner_cm = [31, 14.5]
    bottom_left_corner_cm = [-31, -14.5]
    bottom_right_corner_cm = [31, -14.5]
    
    # Calculate the monitor dimensions in pixels
    # monitor_width_pixels = top_right_corner_pixels[0] - top_left_corner_pixels[0]
    # monitor_height_pixels = bottom_left_corner_pixels[1] - top_left_corner_pixels[1]
    
    left_eye_monitor_width_pixels = left_eye_top_right_corner_pixels[0] - left_eye_top_left_corner_pixels[0]
    left_eye_monitor_height_pixels = left_eye_bottom_left_corner_pixels[1] - left_eye_top_left_corner_pixels[1]
    right_eye_monitor_width_pixels = right_eye_top_right_corner_pixels[0] - right_eye_top_left_corner_pixels[0]
    right_eye_monitor_height_pixels = right_eye_bottom_left_corner_pixels[1] - right_eye_top_left_corner_pixels[1]

    
    # Calculate the monitor dimensions in centimeters
    monitorWidthCm = 62
    monitorHeightCm = 29
    
    # Calculate the pixel-to-centimeter conversion factors
    left_eye_pixel_to_cm_conversion_factor_width = monitorWidthCm / left_eye_monitor_width_pixels
    left_eye_pixel_to_cm_conversion_factor_height = monitorHeightCm / left_eye_monitor_height_pixels
    right_eye_pixel_to_cm_conversion_factor_width = monitorWidthCm / right_eye_monitor_width_pixels
    right_eye_pixel_to_cm_conversion_factor_height = monitorHeightCm / right_eye_monitor_height_pixels

    # Example pixel position
    def pixelToCmLE(xLE, yLE, xRE, yRE, left_eye_pixel_to_cm_conversion_factor_width, 
                    left_eye_pixel_to_cm_conversion_factor_height, right_eye_pixel_to_cm_conversion_factor_width, 
                    right_eye_pixel_to_cm_conversion_factor_height, left_eye_center_pixels, right_eye_center_pixels):
        # pixel_position = [217.5, 133.5]
        
        # Convert pixel position to cm
        # relative_position_pixels = (
        #     pixel_position[0] - center_position_pixels[0],
        #     pixel_position[1] - center_position_pixels[1]
        # )
        # relative_position_cm = (
        #     relative_position_pixels[0] * pixel_to_cm_conversion_factor_width,
        #     relative_position_pixels[1] * pixel_to_cm_conversion_factor_height
        # )
        # cm_position = (
        #     center_position_cm[0] + relative_position_cm[0],
        #     center_position_cm[1] + relative_position_cm[1]
        # )
        cmXLE = []
        cmYLE = []
        cmXRE = []
        cmYRE = []
        for i in range(len(xLE)):
            cmXLE.append(0 + (xLE[i] - left_eye_center_pixels[0]) * left_eye_pixel_to_cm_conversion_factor_width)
            cmYLE.append(0 + (yLE[i] - left_eye_center_pixels[1]) * left_eye_pixel_to_cm_conversion_factor_height)
            cmXRE.append(0 + (xRE[i] - right_eye_center_pixels[0]) * right_eye_pixel_to_cm_conversion_factor_width)
            cmYRE.append(0 + (yRE[i] - right_eye_center_pixels[1]) * right_eye_pixel_to_cm_conversion_factor_height)
        
        return cmXLE, cmYLE, cmXRE, cmYRE
    
    xLEcm, yLEcm, xREcm, yREcm = pixelToCmLE(xLE, yLE, xRE, yRE, left_eye_pixel_to_cm_conversion_factor_width, 
                    left_eye_pixel_to_cm_conversion_factor_height, right_eye_pixel_to_cm_conversion_factor_width, 
                    right_eye_pixel_to_cm_conversion_factor_height, left_eye_center_pixels, right_eye_center_pixels)
    # print("Pixel position:", pixel_position)
    # print("CM position:", cm_position)
    print("Left Eye CM X position:", xLEcm)
    print("Left Eye CM Y position:", yLEcm)
    print("Right Eye CM X position:", xREcm)
    print("Right Eye CM Y position:", yREcm)
    
    time = range(len(xLE))
    
    plt.plot(time, xLEcm)
    plt.xlabel('Time')
    plt.ylabel('X')
    plt.title('X coordinate of Left Pupil Center')
    plt.show()
    
    plt.plot(time, yLEcm)
    plt.xlabel('Time')
    plt.ylabel('X')
    plt.title('X coordinate of Left Pupil Center')
    plt.show()
    
    return xLEcm, yLEcm, xREcm, yREcm, calibrationXLE
    
    
    
