import serial
import pyautogui
import time

# Configuration for ESP32 connection
ESP32_PORT = "COM14"  # Replace with your ESP32 COM port
BAUD_RATE = 115200

# Coordinates for each option (A, B, C, D)
OPTIONS_COORDS = [
    (482, 500),  # Option A
    (782, 489),  # Option B
    (1106, 483), # Option C
    (1409, 482)  # Option D
]

# Timing thresholds to prevent accidental keypresses
KEY_PRESS_DELAY = 1  # Seconds

# Initialize tracking variables
current_option_index = 0  # Start with Option A (index 0)
last_left_press_time = 0
last_right_press_time = 0
last_enter_press_time = 0

def connect_to_esp32(port, baud_rate):
    """Establish a serial connection to the ESP32."""
    try:
        ser = serial.Serial(port, baud_rate)
        print(f"Connected to ESP32 on {port} at {baud_rate} baud.")
        return ser
    except Exception as e:
        print(f"Error connecting to ESP32: {e}")
        exit()

def move_mouse_to_option(option_index):
    """Smoothly move the mouse to the specified option's coordinates."""
    x, y = OPTIONS_COORDS[option_index]
    pyautogui.moveTo(x, y, duration=0.2)

def handle_keypress(x, y, z):
    """
    Handle simulated keypress events based on x, y, z values.
    This controls mouse movement and option selection.
    """
    global current_option_index, last_left_press_time, last_right_press_time, last_enter_press_time

    current_time = time.time()

    # Handle left arrow key (select previous option)
    if z > 370 and x < 300 and (current_time - last_left_press_time > KEY_PRESS_DELAY):
        current_option_index = (current_option_index - 1) % len(OPTIONS_COORDS)  # Cycle backwards
        print(f"Selected Option: {chr(65 + current_option_index)}")  # A, B, C, D
        move_mouse_to_option(current_option_index)
        last_left_press_time = current_time

    # Handle right arrow key (select next option)
    if z < -200 and x < 300 and (current_time - last_right_press_time > KEY_PRESS_DELAY):
        current_option_index = (current_option_index + 1) % len(OPTIONS_COORDS)  # Cycle forwards
        print(f"Selected Option: {chr(65 + current_option_index)}")  # A, B, C, D
        move_mouse_to_option(current_option_index)
        last_right_press_time = current_time

    # Handle enter key (click on current option)
    if y > 350 and (current_time - last_enter_press_time > KEY_PRESS_DELAY):
        print(f"Clicked on Option: {chr(65 + current_option_index)}")
        pyautogui.click()  # Simulate mouse click
        last_enter_press_time = current_time

def main():
    """Main program loop to read data from ESP32 and handle input."""
    # Connect to ESP32
    ser = connect_to_esp32(ESP32_PORT, BAUD_RATE)

    try:
        # Move mouse to the initial option
        move_mouse_to_option(current_option_index)

        while True:
            # Check if data is available from the ESP32
            if ser.in_waiting > 0:
                # Read and decode a line of data
                data = ser.readline().decode('utf-8').strip()

                try:
                    # Parse x, y, z values from the received data
                    x, y, z = map(int, data.split(','))
                    # Process the keypress based on sensor data
                    handle_keypress(x, y, z)
                except ValueError:
                    print(f"Invalid data received: {data}")

    except KeyboardInterrupt:
        print("Program terminated by user.")
    finally:
        # Close the serial connection
        ser.close()
        print("Serial connection closed.")

# Run the program
if __name__ == "__main__":
    main()
