import cv2
import mediapipe as mp
import tkinter as tk
from threading import Thread
import serial
import time

class BasketballScoreboard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Finger Score")

        # Score initialization
        self.score = 0

        # Creating labels to display the score
        self.label_team = tk.Label(self, text="Score", font=("Arial", 100))
        self.label_team.grid(row=0, column=0, padx=20, pady=10)
        
        self.label_score = tk.Label(self, text=self.score, font=("Arial", 300))
        self.label_score.grid(row=1, column=0, padx=20, pady=10)

        # Serial port initialization
        self.serial_port = 'COM3'  # Change this to the correct port
        self.baud_rate = 115200
        self.ser = serial.Serial(self.serial_port, self.baud_rate)
        
        # Start the hand detection and serial listening thread
        self.hand_detection_thread = Thread(target=self.detect_hands)
        self.hand_detection_thread.daemon = True
        self.hand_detection_thread.start()

        self.serial_thread = Thread(target=self.listen_serial)
        self.serial_thread.daemon = True
        self.serial_thread.start()

        self.update_score = False

    def increment_score(self, points):
        for _ in range(points):
            self.score += 1
            self.label_score.config(text=self.score)
            time.sleep(0.1)  # Increase slowly

    def listen_serial(self):
        while True:
            if self.ser.in_waiting > 0:
                signal = self.ser.readline().decode().strip()
                if signal == 'h':
                    self.update_score = True
                    time.sleep(0.1)  # Short pause to avoid multiple readings

    def detect_hands(self):
        mp_hands = mp.solutions.hands
        mp_drawing = mp.solutions.drawing_utils
        hands = mp_hands.Hands()
        cap = cv2.VideoCapture(0)

        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break

            frame = cv2.cvtColor(cv2.flip(frame, 1), cv2.COLOR_BGR2RGB)
            results = hands.process(frame)

            if results.multi_hand_landmarks:
                hand_landmarks = results.multi_hand_landmarks[0]
                # Draw reference points and connections
                mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
                
                # Count raised fingers and update score if 'h' signal is received
                if self.update_score:
                    fingers = self.count_fingers(hand_landmarks)
                    if fingers > 0:
                        self.increment_score(fingers)
                    self.update_score = False

            cv2.imshow('Hand Detection', cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
            if cv2.waitKey(5) & 0xFF == 27:
                break

        cap.release()
        cv2.destroyAllWindows()

    def count_fingers(self, hand_landmarks):
        # Count raised fingers
        finger_tips = [4, 8, 12, 16, 20]
        count = 0
        if hand_landmarks.landmark[finger_tips[0]].x < hand_landmarks.landmark[finger_tips[0] - 1].x:
            count += 1  # count thumb
        for tip in finger_tips[1:]:
            if hand_landmarks.landmark[tip].y < hand_landmarks.landmark[tip - 2].y:
                count += 1
        return min(count, 3)  # Maximum 3 points

if __name__ == "__main__":
    app = BasketballScoreboard()
    app.mainloop()
