import cv2
from include.FeaturesExtractor import FeaturesExtractor
from include.PoseExtractor import PoseExtractor
from include.KNNClassifier import KNNClassifier, GestureClassifier
from include.DataGruber import DataGruber

stream = cv2.VideoCapture(0)
RUN = True

features_extractor = FeaturesExtractor()
pose_extractor = PoseExtractor()
classifier = KNNClassifier()
data_gruber = DataGruber()
gesture_classifier = GestureClassifier()


while RUN:
    ret, img = stream.read()
    if not ret:
        RUN = False
    else:
        pose_extractor.update_op_datum(img)
        drawed_pose = pose_extractor.draw_pose()
        poses = pose_extractor.get_poses()
        if len(poses):
            actual_pose = poses[0]
            k_points = pose_extractor.pose_to_k_points(actual_pose)

            k_points_features, scale_factor_points = features_extractor.extract_pose_k_points(k_points)
            scale_factor = features_extractor.get_scale_factor(scale_factor_points)

            x_f = features_extractor.get_x_features(k_points_features, scale_factor)
            y_f = features_extractor.get_y_features(k_points_features, scale_factor)

            if x_f is not None and y_f is not None:
                classifier_input_data = classifier.dx_dy_to_input(x_f, y_f)
                try:
                    gesture = classifier.predict(classifier_input_data)

                    data_gruber.update_gestures_list(gesture)
                    gesture_seq = data_gruber.get_actual_gestures_sequence()

                    gest = gesture_classifier.classify_gesture_sequence(gesture_seq)
                    if gest:
                        data_gruber.gestures_list = []
                        data_gruber.time_list = []


                    print(gest)


                    cv2.putText(drawed_pose, gesture, (35, 35), cv2.FONT_HERSHEY_COMPLEX, 1.2, (0, 0, 180), 2)
                except:
                    pass

        cv2.imshow("img", drawed_pose)
        if cv2.waitKey(10) & 0xFF == 27:
            RUN = False
            cv2.destroyAllWindows()
            stream.release()