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

# Przygotowuje plik dźwiękowy z ostrzeżeniem.
engine = pyttsx3.init()
engine.setProperty('rate', 145)  # Szybko, ale wyraźnie
engine.setProperty('volume', 1.0)  # Maksymalna wartość to 1.0.

# 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_default.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
    engine.say("Zajdujesz 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.")
    engine.runAndWait()
    time.sleep(3)
    
    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.1,
                                                        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((we + he) / 3)
                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 not discharge_weapon:
        playsound(tone_path, block=False)
        cv.imshow('Wykryto twarze', img_gray)
        cv.waitKey(2000)
        cv.destroyWindow('Wykryto twarze')
        time.sleep(5)

    else:
        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(3)  # Opóźnia wyświetlanie kolejnego obrazu.

engine.stop()  # Opcjonalnie
