import cv2
import mediapipe as mp
import websocket
import json
import threading
import time
import win32api
import win32con
import time


# Configuração do WebSocket
ws_url = "ws://localhost:8585"  # Substitua pelo endereço do seu servidor WebSocket
ws = None

# Inicializar MediaPipe para mãos
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(max_num_hands=2, min_detection_confidence=0.7)
mp_drawing = mp.solutions.drawing_utils

# Inicializar a captura de vídeo
cap = cv2.VideoCapture(0)

def sendMousePressed(mX,mY):  
    win32api.SetCursorPos((mX, mY))
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0)

def sendMouseRelease():  
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0)

def is_hand_open(landmarks):
    # Verifica se a mão está aberta: dedos estendidos têm as pontas mais distantes da palma
    fingers = [
        landmarks[8].y < landmarks[6].y,  # Dedo indicador
        landmarks[12].y < landmarks[10].y, # Dedo médio
        landmarks[16].y < landmarks[14].y, # Dedo anelar
        landmarks[20].y < landmarks[18].y  # Dedo mindinho
    ]
    return all(fingers)

def connect_ws():
    global ws
    while True:
        try:
            ws = websocket.WebSocket()
            ws.connect(ws_url)
            print("Conectado ao servidor WebSocket")
            break
        except Exception as e:
            print(f"Erro ao conectar ao WebSocket: {e}. Tentando reconectar em 5 segundos...")
            time.sleep(5)

def send_message(message):
    global ws
    try:
        if ws and ws.connected:
            ws.send(json.dumps(message))
            print("Mensagem enviada para o WebSocket:", message)
        else:
            raise ConnectionError("Conexão com WebSocket perdida")
    except Exception as e:
        print(f"Erro ao enviar mensagem: {e}")
        connect_ws()

# Conectar ao WebSocket em uma nova thread para não bloquear o programa
#ws_thread = threading.Thread(target=connect_ws)
#ws_thread.start()

while cap.isOpened():
    success, frame = cap.read()
    if not success:
        break

    # Inverter a imagem para espelhar a visão da câmera
    frame = cv2.flip(frame, 1)
    # Converter a imagem para RGB
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # Processar a imagem e detectar mãos
    results = hands.process(frame_rgb)
    leftHandOpen = False
    rightHandOpen = False

    if results.multi_hand_landmarks:
        for hand_landmarks, hand_type in zip(results.multi_hand_landmarks, results.multi_handedness):
            # Desenhar pontos de referência e conexões
            mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
            index_finger = hand_landmarks.landmark[8]
            x_px = int(index_finger.x * 1920)
            y_px = int(index_finger.y * 1080)
            #print(f"Dedo indicador: X={x_px}, Y={y_px}")

            sendMousePressed(x_px,y_px)
            

            # Verificar se a mão está aberta
            if is_hand_open(hand_landmarks.landmark):
                text = f"Hand {hand_type.classification[0].label} Open"
                
                if hand_type.classification[0].label == "Left":
                    leftHandOpen = True
                elif hand_type.classification[0].label == "Right":
                    rightHandOpen = True
            else:
                text = f"Hand {hand_type.classification[0].label} closed"

            # Adicionar texto na imagem
        if leftHandOpen and rightHandOpen:
            text = "All Open"           
        cv2.putText(frame, text, (200, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 1)
    else:
        sendMouseRelease()

         

        # Verifica se ambas as mãos estão abertas e envia a mensagem uma vez
        """
        if leftHandOpen and rightHandOpen:
            send_message({"action": "all_open"})
        elif not leftHandOpen and not rightHandOpen:
            send_message({"action": "all_closed"})
        else:
            if leftHandOpen:
                send_message({"action": "left_hand_open"})
            elif rightHandOpen:
                send_message({"action": "right_hand_open"})

                """
    
    # Exibir a imagem
    cv2.imshow("edgCamView", frame)

    # Sair do loop com a tecla 'q'
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Liberar os recursos
cap.release()
cv2.destroyAllWindows()
hands.close()
if ws:
    ws.close()
