#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main(){
    // Load Haar cascades for face and eye detection
    CascadeClassifier face_cascade, eye_cascade;
    if (!face_cascade.load("haarcascade_frontalface_alt.xml") || !eye_cascade.load("haarcascade_eye.xml"))    {
        cout << "Failed to load Haar cascades" << endl;
        return -1;
    }

    // Open camera feed
    VideoCapture cap(0);
    if (!cap.isOpened()){
        cout << "Failed to open camera" << endl;
        return -1;
    }

    // Loop through frames
    while (true){
        Mat frame;
        cap >> frame;

        // Convert frame to grayscale for face and eye detection
        Mat gray_frame;
        cvtColor(frame, gray_frame, COLOR_BGR2GRAY);

        // Detect faces
        vector<Rect> faces;
        face_cascade.detectMultiScale(gray_frame, faces, 1.3, 5);

        // Loop through faces
        for (size_t i = 0; i < faces.size(); i++){
            Rect face_rect = faces[i];

            // Draw rectangle around face
            rectangle(frame, face_rect, Scalar(255, 0, 0), 2);

            // Extract ROI for face
            Mat face_roi = gray_frame(face_rect);

            // Detect eyes within face ROI (region of interest)
            vector<Rect> eyes;
            eye_cascade.detectMultiScale(face_roi, eyes, 1.3, 5);

            // Loop through eyes
            for (size_t j = 0; j < eyes.size(); j++){
                Rect eye_rect = eyes[j];

                // Draw rectangle around eye
                rectangle(frame, Point(face_rect.x + eye_rect.x, face_rect.y + eye_rect.y), 
                          Point(face_rect.x + eye_rect.x + eye_rect.width, face_rect.y + eye_rect.y + eye_rect.height), 
                          Scalar(0, 255, 0), 2);

                // Calculate center of eye
                Point eye_center(face_rect.x + eye_rect.x + eye_rect.width / 2, face_rect.y + eye_rect.y + eye_rect.height / 2);

                // Draw circle at center of eye
                circle(frame, eye_center, 2, Scalar(0, 0, 255), 2);
            }
        }

        // Show frame
        imshow("Gaze Detection", frame);

        // Exit on key press
        if (waitKey(1) == 27) break;
    }

    return 0;
}