import os
import time
from datetime import datetime
from playsound import playsound
import pyttsx3
import cv2 as cv

# Określa ścieżki dostępu do plików dźwiękowych.
root_dir = os.path.abspath('.')
gunfire_path = os.path.join(root_dir, 'gunfire.wav')
tone_path = os.path.join(root_dir, 'tone.wav')

# Ustawia ścieżki do kaskadowych klasyfikatorów Haara do wykrywania twarzy.
path = "C:/Python39/Lib/site-packages/cv2/data/"
face_cascade = cv.CascadeClassifier(path + 'haarcascade_frontalface_alt.xml')
face2_cascade = cv.CascadeClassifier(path + 'haarcascade_frontalface_alt2.xml')
eye_cascade = cv.CascadeClassifier(path + 'haarcascade_eye.xml')

# Uzyskuje dostęp do obrazów z korytarza.
os.chdir('corridor_5')
contents = sorted(os.listdir())

# Wykrywa twarze i otwiera ogień lub dezaktywuje broń.
for image in contents:
    print(f"\nWykryto ruch... {datetime.now()}")
    discharge_weapon = True
    os.system("say 'Znajdujesz się w strefie pod kontrolą ogniową. \
               Natychmiast zatrzymaj się i zwróć twarz w kierunku wieżyczki. \
               Masz 5 sekund na przejście od momentu usłyszenia sygnału.' &")
    time.sleep(6)
    
    img_gray = cv.imread(image, cv.IMREAD_GRAYSCALE)
    height, width = img_gray.shape
    cv.imshow(f'Wykryto ruch na obrazie {image}', img_gray)
    cv.waitKey(2000)
    cv.destroyWindow(f'Wykryto ruch na obrazie {image}')

    # Znajduje prostokąty z twarzami.
    face_rect_list = []  
    face_rect_list.append(face_cascade.detectMultiScale(image=img_gray,
                                                        scaleFactor=1.2,
                                                        minNeighbors=5))
    face_rect_list.append(face2_cascade.detectMultiScale(image=img_gray,
                                                         scaleFactor=1.2,
                                                         minNeighbors=5))

    print(f"Wyszukiwanie oczu na obrazie {image}.")
    for rect in face_rect_list:
        for (x, y, w, h) in rect:
            rect_4_eyes = img_gray[y:y+h, x:x+w]
            eyes = eye_cascade.detectMultiScale(image=rect_4_eyes,
                                                scaleFactor=1.05,
                                                minNeighbors=2)
            for (xe, ye, we, he) in eyes:
                print("Wykryto oko.")
                center = (int(xe + 0.5 * we), int(ye + 0.5 * he))
                radius = int(0.3 * (we + he))
                cv.circle(rect_4_eyes, center, radius, 255, 2)
                cv.rectangle(img_gray, (x, y), (x+w, y+h), (255, 255, 255), 2)
                discharge_weapon = False
                break
            
    if discharge_weapon == False:
        time.sleep(2)
        playsound(tone_path, block=False)
        cv.imshow('Wykryto twarze', img_gray)
        cv.waitKey(2000)
        cv.destroyWindow('Wykryto twarze')
        time.sleep(5)

    else:
        time.sleep(2)
        print(f"Brak twarzy na obrazie {image}. Ognia!")
        cv.putText(img_gray, 'OGNIA!', (int(width / 2) - 20, int(height / 2)),
                                       cv.FONT_HERSHEY_PLAIN, 3, 255, 3)
        playsound(gunfire_path, block=False)
        cv.imshow('Mutant', img_gray)
        cv.waitKey(2000)
        cv.destroyWindow('Mutant')
        time.sleep(5)  # Opóźnia wyświetlenie kolejnego obrazu.
