import cv2, requests, threading
import mediapipe as mp
import numpy as np

# Initialize MediaPipe Hands
mp_hands = mp.solutions.hands
hands = mp_hands.Hands()
mp_drawing = mp.solutions.drawing_utils

# Initialize variables for hand tracking
tracking = False
hand_y = 0
hand_x = 0
prev_dir = ""

URL = "http://projectalmanac.local/"

def send(link):
    try:
        response = requests.get(link)
        print("Response ->", response)
    except Exception as e:
        print(f"Error sending HTTP request: {e}")

# Function to find the direction based on the hand's xy-coordinate
def find_direction(frame, hand_y, hand_x, frame_center):
    width, height, _ = frame.shape[:3]

    if hand_y < frame_center[1] - height * 0.1:
        return "forward"
    elif hand_y > frame_center[1] + height * 0.1:
        return "backward"
    elif hand_x < frame_center[0] - width * 0.2:
        return "left"
    elif hand_x > frame_center[0] + width * 0.2:
        return "right"
    else:
        return "stop"


# Capture video from the default camera (usually 0)
cap = cv2.VideoCapture(0)

with hands:
    hand_landmarks = None  # Initialize hand_landmarks outside the loop
    while True:
        ret, frame = cap.read()
        frame = cv2.flip(frame,1)

        if not ret:
            break

        # Get the frame dimensions
        height, width, _ = frame.shape

        # Create a black background image
        black_background = np.zeros_like(frame)

        # Process the frame with MediaPipe Hands
        rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        # rgb_frame = cv2.flip(rgb_frame, 1)
        results = hands.process(rgb_frame)

        if results.multi_hand_landmarks:
            # Assuming only one hand is in the frame
            hand_landmarks = results.multi_hand_landmarks[0]

            # Extract the y-coordinate of the index finger tip
            index_finger_tip = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP]
            hand_y = int(index_finger_tip.y * height)
            hand_x = int(index_finger_tip.x * width)

            tracking = True

        # Update the direction based on the finger position
        frame_center = (width // 2, height // 2)
        if tracking:
            direction = find_direction(frame, hand_y, hand_x, frame_center)

            if(direction != prev_dir):
                try:
                    link = URL+direction
                    http_thread = threading.Thread(target=send, args=(link,))
                    http_thread.start()
                except Exception as e:
                    print(e)
                prev_dir = direction
                print(direction)
    
            cv2.putText(black_background, direction, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

        # Draw a filled circle for the index finger on the black background
        if tracking:
            circle_radius = 20
            circle_color = (0, 0, 255)  # Red circle color
            cv2.circle(black_background, (hand_x, hand_y), circle_radius, circle_color, -1)

        # Add a colored border to the center area on the black background
        # border_color = (0, 255, 0)  # Green border color
        # border_thickness = 5
        # center_x, center_y = frame_center
        # center_width, center_height = int(width * 0.2), int(height * 0.2)
        # cv2.rectangle(black_background, (center_x - center_width, center_y - center_height), 
        #               (center_x + center_width, center_y + center_height), border_color, border_thickness)

        text_x = 10
        text_y = 60
        cv2.putText(black_background, "Forward", (width*2 // 5, text_y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
        cv2.putText(black_background, "Backward", (width*2 // 5, height - text_y - text_x), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
        cv2.putText(black_background, "Left", (text_x, height // 2), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
        cv2.putText(black_background, "Right", (width - text_x - 90, height // 2), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
        cv2.putText(black_background, "Stop", (width // 2 - 20, height // 2), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)


        # Decrease the opacity of the black background
        opacity = 0.8  # Adjust this value for the desired opacity (0.0 to 1.0)
        cv2.addWeighted(black_background, opacity, frame, 1 - opacity, 0, frame)

        # Show the frame with all the elements
        cv2.imshow("Hand Tracking", frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

cap.release()
cv2.destroyAllWindows()
