import cv2
import numpy as np
import dlib
import math
import time

cap = cv2.VideoCapture(0)

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

def send_features():
    print(client_status_sleep)

def euc_dist(x1, y1, x2, y2):
    return math.sqrt((abs(x1-x2))**2+(abs(y1-y2))**2)

def landmarks_dist(n1, n2):
    return euc_dist(landmarks.part(n1).x, landmarks.part(n1).y, landmarks.part(n2).x, landmarks.part(n2).y)

count = 0
sum = 0
data_frame = 10
eye_open = True

closing_time = 0
opening_time = 0
temp_time = 0
client_status_sleep = False

while True:
    _, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    faces = detector(gray)

    for face in faces:
        
        detection = True
        #print("Face detected: ", time.time())
        landmarks = predictor(gray, face)

        left_eye_width = landmarks_dist(42, 45)
        left_eye_height1 = landmarks_dist(43, 47)
        left_eye_height2 = landmarks_dist(44, 46)
        left_eye_ratio = (left_eye_height1 + left_eye_height2) / left_eye_width*2
        
        right_eye_width = landmarks_dist(36, 39)
        right_eye_height1 = landmarks_dist(37, 41)
        right_eye_height2 = landmarks_dist(38, 40)
        right_eye_ratio = (right_eye_height1 + right_eye_height2) / right_eye_width*2
        
        eye_ratio = right_eye_ratio + left_eye_ratio

        #circle landmark "42"
        x = landmarks.part(42).x
        y = landmarks.part(42).y
        cv2.circle(frame, (x, y), 4, (255, 0, 0), -1)

        
        #data_frame 만큼의 평균값을 통해 기준 값 설정
        if count < data_frame:
            count += 1
            sum += left_eye_ratio + right_eye_ratio
            mean_eye_ratio = sum / count
        
        #print(mean_eye_ratio, eye_ratio, count)
        
        prev_open = eye_open
        prev_time = temp_time

        #print(left_eye_ratio+right_eye_ratio, time.time())
        if count < data_frame:
            print("Collecting data, Please look at the front!")
        elif left_eye_ratio+right_eye_ratio < (mean_eye_ratio/1.4) and count == data_frame:
            #print("Eye closed", time.time())
            eye_open = False
            temp_time = time.time()
        else:
            #print("Eye opened", time.time())
            eye_open = True
            temp_time = time.time()

        #눈 감은 시간 계산, 1 초간 눈 뜨면 초기화
        if (prev_open == True) and (eye_open == False):
            closing_time += temp_time-prev_time
        elif prev_open == False and eye_open == True:
            opening_time += temp_time-prev_time        
        elif (prev_open == True) and (eye_open == True):
            opening_time += temp_time-prev_time
            #closing_time += temp_time-prev_open
        elif (prev_open == True ) and opening_time<1:
            closing_time += temp_time-prev_time
        elif eye_open == False:
            closing_time += temp_time-prev_time
            opening_time =0

        if eye_open == True and opening_time > 1:
            closing_time = 0

        #print(closing_time, opening_time)
        print(client_status_sleep)

        #3초 이상 누적되면 자는 걸로 판단
        if closing_time > 3:
            #print("잠")
            client_status_sleep = True
        else:
            client_status_sleep = False 
    
        cv2.imshow("Frame", frame)

    
    key = cv2.waitKey(1)
    if key == 27:
        break