ailed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture.
exam_details.php:1 Uncaught (in promise) TypeError: Permissions check failed
exam_details.php?exam_code=671777f76698f:552 Remaining time updated successfully.
exam_details.php?exam_code=671777f76698f:316 Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture.
enterFullscreen @ exam_details.php?exam_code=671777f76698f:316
handleFullscreenExit @ exam_details.php?exam_code=671777f76698f:346
exam_details.php?exam_code=671777f76698f:316 Uncaught (in promise) TypeError: Permissions check failed
    at enterFullscreen (exam_details.php?exam_code=671777f76698f:316:25)
    at HTMLDocument.handleFullscreenExit (exam_details.php?exam_code=671777f76698f:346:17)


<?php
// exam_details.php
session_start();

// Enable error reporting for debugging (disable in production)
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Redirect to login if not logged in
if (!isset($_SESSION['user_id'])) {
    header("Location: index.php");
    exit();
}

// Fetch exam_code from GET if provided, else check session
if (isset($_GET['exam_code'])) {
    $_SESSION['exam_code'] = $_GET['exam_code'];
} elseif (!isset($_SESSION['exam_code'])) {
    // If exam_code is not in GET and not in session, redirect
    header("Location: index.php");
    exit();
}

$exam_code = $_SESSION['exam_code'];
$user_id = $_SESSION['user_id'];

// CSRF Token Generation
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$csrf_token = $_SESSION['csrf_token'];

// Retrieve saved answers from session
$saved_answers = isset($_SESSION['saved_answers']) ? $_SESSION['saved_answers'] : [];

// Database connection parameters
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "capstone2";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// Define language mapping based on topics
$languageMapping = [
    'python' => 'python',
    'java' => 'java',
    'c' => 'c',
    'c++' => 'cpp',
    'javascript' => 'javascript',
    'html' => 'html',
    'css' => 'css',
    'ruby' => 'ruby',
    'php' => 'php',
    'swift' => 'swift',
    'go' => 'go',
    // Add more mappings as necessary
];

// Define starter code for each language
$codePlaceholders = [
    'python' => "# Write your Python code here\n\n",
    'java' => "// Write your Java code here\npublic class Main {\n    public static void main(String[] args) {\n        \n    }\n}\n",
    'c' => "// Write your C code here\n#include <stdio.h>\nint main() {\n    \n    return 0;\n}\n",
    'cpp' => "// Write your C++ code here\n#include <iostream>\nusing namespace std;\nint main() {\n    \n    return 0;\n}\n",
    'javascript' => "// Write your JavaScript code here\nfunction main() {\n    \n}\nmain();\n",
    'html' => "<!-- Write your HTML code here -->\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Document</title>\n</head>\n<body>\n    \n</body>\n</html>",
    'css' => "/* Write your CSS code here */\nbody {\n    background-color: #f0f0f0;\n    font-family: Arial, sans-serif;\n}\nh1 {\n    color: #333;\n}",
    'ruby' => "# Write your Ruby code here\ndef main\n    \nend\n\nmain\n",
    'php' => "<?php\n// Write your PHP code here\n\n?>",
    'swift' => "// Write your Swift code here\nimport Foundation\n\nfunc main() {\n    \n}\n\nmain()\n",
    'go' => "// Write your Go code here\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n    \n}\n",
    // Add more starter codes as necessary
];

// Initialize variables for exam details
$exam_title = "";
$subject = "";
$status = "";
$duration = "";
$start_exam_datetime = "";
$remaining_time = "";

// Prepare and execute query for enrolled subjects view
$query = "SELECT exam_title, subject, status, duration, start_exam_datetime, remaining_time 
          FROM enrolled_subjects_view 
          WHERE exam_code = ? AND user_id = ?";
$stmt = $conn->prepare($query);

// Check if prepare was successful
if (!$stmt) {
    die("Preparation failed: " . $conn->error);
}

// Assuming user_id is integer
$stmt->bind_param("si", $exam_code, $user_id);
$stmt->execute();
$result = $stmt->get_result();

// Check if exam exists
if ($result->num_rows > 0) {
    $exam = $result->fetch_assoc();
    $exam_title = htmlspecialchars($exam['exam_title'] ?? '', ENT_QUOTES, 'UTF-8');
    $subject = htmlspecialchars($exam['subject'] ?? '', ENT_QUOTES, 'UTF-8');
    $status = strtolower(trim($exam['status'] ?? '')); // Normalize status to lowercase
    $duration = $exam['duration'] ?? '00:00:00';
    $start_exam_datetime = $exam['start_exam_datetime'] ?? '';
    $remaining_time = $exam['remaining_time'] ?? '00:00:00';
} else {
    echo "Exam not found for this user.";
    exit(); // Exit if exam not found
}

$stmt->close();

// Record start_exam_datetime if not already set
if (empty($start_exam_datetime)) {
    // Set the start_exam_datetime to current datetime and initialize remaining_time
    $update_start_time_query = "UPDATE enrolled_exams SET start_exam_datetime = NOW(), remaining_time = ? 
                                WHERE exam_code = ? AND user_id = ?";
    $update_stmt = $conn->prepare($update_start_time_query);
    if ($update_stmt) {
        // Assuming duration is in HH:MM:SS format
        $update_stmt->bind_param("ssi", $duration, $exam_code, $user_id);
        if ($update_stmt->execute()) {
            $update_stmt->close();
            // Update the $exam array with the new start time and remaining_time
            $start_exam_datetime = date("Y-m-d H:i:s");
            $remaining_time = $duration;
        } else {
            die("Failed to set start time: " . $update_stmt->error);
        }
    } else {
        die("Failed to prepare start time update: " . $conn->error);
    }
}

// Check if exam status allows access
if ($status === 'done') { // Assuming status is normalized to lowercase
    // We'll handle the notification and redirection in JavaScript
    // So we set a flag
    $exam_done = true;
} else {
    $exam_done = false;
}

// Prepare and execute query for exam questions
$query = "SELECT eq.question_id, eq.question, eq.question_type, eq.points, ed.topic 
          FROM exam_questions eq 
          JOIN exam_data ed ON eq.question_id = ed.question_id 
          WHERE eq.exam_code = ?";
$stmt = $conn->prepare($query);

// Check if prepare was successful
if (!$stmt) {
    die("Preparation failed: " . $conn->error);
}

$stmt->bind_param("s", $exam_code);
$stmt->execute();
$questions_result = $stmt->get_result();

// Fetch questions and their types
$questions_with_types = [];
$total_points = 0;

// Check if shuffled_questions is already set in session
if (!isset($_SESSION['shuffled_questions'])) {
    while ($row = $questions_result->fetch_assoc()) {
        $questions_with_types[] = $row;
        $total_points += intval($row['points']); // Sum up the points for each question
    }

    // Shuffle the questions array to randomize the order of questions
    shuffle($questions_with_types);

    // Store the shuffled questions in session
    $_SESSION['shuffled_questions'] = $questions_with_types;
} else {
    // Retrieve shuffled questions from session
    $questions_with_types = $_SESSION['shuffled_questions'];
    
    // Calculate total points
    foreach ($questions_with_types as $q) {
        $total_points += intval($q['points']);
    }
}

// Set the total points to session variable
$_SESSION['total_points_questions'] = $total_points;

// Close the statement (keep the connection open for fetching options)
$stmt->close();
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Exam Details</title>
    <!-- Font Awesome for icons -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
    <!-- External CSS -->
    <link rel="stylesheet" href="exam_styles.css">
    <style>
        /* Additional styles for points display */
        .points {
            font-weight: bold;
            color: #333;
            margin-top: 5px;
        }
        /* Style for the total points section */
        .total-points {
            font-size: 1.2em;
            margin-bottom: 20px;
        }
        /* Styling the submit button */
        .submit-btn {
            background-color: #4CAF50; /* Green */
            color: white;
            padding: 10px 20px;
            border: none;
            cursor: pointer;
            border-radius: 5px;
            font-size: 16px;
            margin: 20px 0;
        }
        .submit-btn:hover {
            background-color: #45a049;
        }
        /* Timer styles */
        #timer {
            font-size: 1.5em;
            font-weight: bold;
            margin-left: 10px;
        }
        /* Exam header styling */
        .exam-header {
            display: flex;
            align-items: center;
            margin-bottom: 20px;
        }
        /* Exam information styling */
        .exam-info p {
            margin: 5px 0;
        }
        /* Question styling */
        .question {
            margin-bottom: 20px;
        }
        /* Notification container styling */
        #notificationContainer {
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 1000;
            width: 300px;
            font-family: Arial, sans-serif;
        }
        /* Notification Styles */
        .notification {
            border: 1px solid;
            padding: 10px;
            margin-bottom: 10px;
            border-radius: 5px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            opacity: 0;
            transition: opacity 0.5s;
        }
        .notification.warning {
            background-color: #fff3cd;
            color: #856404;
            border-color: #ffeeba;
        }
        .notification.error {
            background-color: #f8d7da;
            color: #721c24;
            border-color: #f5c6cb;
        }
        .notification.info {
            background-color: #d1ecf1;
            color: #0c5460;
            border-color: #bee5eb;
        }

        /* Custom Modal Styles */
        /* Modal Overlay */
        .modal {
            display: none; /* Hidden by default */
            position: fixed; /* Stay in place */
            z-index: 2000; /* Sit on top of other elements */
            left: 0;
            top: 0;
            width: 100%; /* Full width */
            height: 100%; /* Full height */
            overflow: auto; /* Enable scroll if needed */
            background-color: rgba(0, 0, 0, 0.5); /* Black w/ opacity */
        }

        /* Modal Content Box */
        .modal-content {
            background-color: #fefefe;
            margin: 15% auto; /* 15% from top and centered */
            padding: 20px;
            border: 1px solid #888;
            width: 300px; /* Could be more or less, depending on screen size */
            border-radius: 5px;
            text-align: center;
        }

        /* Close Button (X) */
        .close-button {
            color: #aaa;
            float: right;
            font-size: 28px;
            font-weight: bold;
            cursor: pointer;
        }

        .close-button:hover,
        .close-button:focus {
            color: black;
            text-decoration: none;
        }

        /* Modal Buttons */
        .modal-buttons {
            margin-top: 20px;
        }

        .modal-buttons button {
            padding: 10px 20px;
            margin: 0 10px;
            border: none;
            border-radius: 3px;
            cursor: pointer;
        }

        #yesButton {
            background-color: #4CAF50; /* Green */
            color: white;
        }

        #noButton {
            background-color: #f44336; /* Red */
            color: white;
        }

        /* Fullscreen Exit Modal Specific Styles */
        #fullscreenExitModal .modal-content {
            width: 400px;
        }

        /* Code Editor Styling */
        .code-editor {
            height: 300px;
            border: 1px solid #ccc;
        }

        /* Instructions Styling */
        .instructions {
            background-color: #e9ecef;
            padding: 15px;
            border-radius: 5px;
            margin-bottom: 20px;
        }
    </style>
    <!-- Monaco Editor Loader -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/loader.min.js"></script>
    <script>
        // Function to open the submission confirmation modal
        function submitExam() {
            const modal = document.getElementById('confirmationModal');
            modal.style.display = 'block';
        }

        // Function to close the submission confirmation modal
        function closeModal() {
            const modal = document.getElementById('confirmationModal');
            modal.style.display = 'none';
        }

        // Function to handle the "Yes" button click in submission confirmation modal
        function confirmSubmit() {
            closeModal(); // Close the modal
            document.getElementById('examForm').submit(); // Submit the form
        }

        // Function to open the fullscreen exit notification modal
        function showFullscreenExitModal() {
            const modal = document.getElementById('fullscreenExitModal');
            modal.style.display = 'block';
        }

        // Function to close the fullscreen exit notification modal
        function closeFullscreenExitModal() {
            const modal = document.getElementById('fullscreenExitModal');
            modal.style.display = 'none';
        }

        // Function to open the instructions modal (optional)
        function showInstructionsModal() {
            const modal = document.getElementById('instructionsModal');
            modal.style.display = 'block';
        }

        // Function to close the instructions modal (optional)
        function closeInstructionsModal() {
            const modal = document.getElementById('instructionsModal');
            modal.style.display = 'none';
        }

        // Event listeners for the "Yes" and "No" buttons in submission confirmation modal
        document.addEventListener('DOMContentLoaded', function() {
            const yesButton = document.getElementById('yesButton');
            const noButton = document.getElementById('noButton');
            if (yesButton && noButton) {
                yesButton.addEventListener('click', confirmSubmit);
                noButton.addEventListener('click', closeModal);
            }

            // Event listeners for the "OK" button in fullscreen exit modal
            const fullscreenOkButton = document.getElementById('fullscreenOkButton');
            if (fullscreenOkButton) {
                fullscreenOkButton.addEventListener('click', closeFullscreenExitModal);
                enterFullscreen();
            }

            // Event listener for the "Take Exam" button
            const takeExamBtn = document.getElementById('takeExamBtn');
            if (takeExamBtn) {
                takeExamBtn.addEventListener('click', function() {
                    // Hide the "Take Exam" button
                    takeExamBtn.style.display = 'none';
                    
                    // Show the exam form
                    const examForm = document.getElementById('examForm');
                    if (examForm) {
                        examForm.style.display = 'block';
                    }

                    // Disable specific keys
                    disableExitKeys();

                    // Enter fullscreen mode
                    enterFullscreen();

                    // Start the timer and monitoring
                    startTimer('<?php echo $remaining_time; ?>');
                    setupExamMonitoring();
                    setupAnswerSaving();
                    
                    // Setup window focus handling
                    setupWindowFocusHandling();
                });
            }
        });

        // Disable copy, cut, and paste
        function disableCopyPaste() {
            document.addEventListener('copy', function(e) {
                e.preventDefault();
            });
            document.addEventListener('cut', function(e) {
                e.preventDefault();
            });  
            document.addEventListener('paste', function(e) {
                e.preventDefault();
            });
        }  
        disableCopyPaste();

        // Function to show non-blocking notifications
        function showNotification(message, type = 'warning') {
            // Create a notification container if it doesn't exist
            let notificationContainer = document.getElementById('notificationContainer');
            if (!notificationContainer) {
                notificationContainer = document.createElement('div');
                notificationContainer.id = 'notificationContainer';
                document.body.appendChild(notificationContainer);
            }

            // Create a notification div
            const notification = document.createElement('div');
            notification.className = `notification ${type}`;
            notification.textContent = message;
            notificationContainer.appendChild(notification);

            // Force reflow to enable transition
            void notification.offsetWidth;

            // Fade in the notification
            notification.style.opacity = '1';

            // Remove the notification after 5 seconds
            setTimeout(() => {
                notification.style.opacity = '0';
                // Remove from DOM after transition
                setTimeout(() => {
                    if (notificationContainer.contains(notification)) {
                        notificationContainer.removeChild(notification);
                    }
                }, 500);
            }, 5000);
        }

        // Function to enter fullscreen mode
        function enterFullscreen() {
            const element = document.documentElement;
            if (element.requestFullscreen) {
                element.requestFullscreen();
            } else if (element.mozRequestFullScreen) { /* Firefox */
                element.mozRequestFullScreen();
            } else if (element.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
                element.webkitRequestFullscreen();
            } else if (element.msRequestFullscreen) { /* IE/Edge */
                element.msRequestFullscreen();
            }
        }

        // Function to set up fullscreen exit handling
        function setupFullscreenExitHandling() {
            document.addEventListener('fullscreenchange', handleFullscreenExit);
            document.addEventListener('mozfullscreenchange', handleFullscreenExit);
            document.addEventListener('webkitfullscreenchange', handleFullscreenExit);
            document.addEventListener('msfullscreenchange', handleFullscreenExit);
        }

        // Function to handle fullscreen exit
        function handleFullscreenExit() {
            const isFullscreen = document.fullscreenElement || 
                                 document.mozFullScreenElement || 
                                 document.webkitFullscreenElement || 
                                 document.msFullscreenElement;
            if (!isFullscreen) {
                // Show the fullscreen exit notification modal
                showFullscreenExitModal();
                
                
                // Attempt to re-enter fullscreen mode
                enterFullscreen();
            }
        }

        // Function to set up exam monitoring
        function setupExamMonitoring() {
            // Handle visibility change
            document.addEventListener('visibilitychange', handleVisibilityChange);

            // Handle window blur
            window.addEventListener('blur', handleWindowBlur);

            // Setup fullscreen exit handling
            setupFullscreenExitHandling();
        }

        // Function to handle visibility change
        function handleVisibilityChange() {
            if (document.hidden) {
                showNotification("You switched tabs or minimized the window.", 'warning');
            }
        }

        // Function to handle window blur
        function handleWindowBlur() {
            showNotification("You switched windows.", 'warning');
        }

        // Function to disable specific keys
        function disableExitKeys() {
            document.addEventListener('keydown', function(e) {
                // List of keys to disable
                const keysToDisable = ['Escape', 'F11', 'F4'];

                if (keysToDisable.includes(e.key)) {
                    e.preventDefault();
                    e.stopPropagation();
                    showNotification("Exiting fullscreen is disabled during the exam.", 'warning');
                }

                // Disable Alt+F4 (common exit shortcut on Windows)
                if (e.key === 'F4' && e.altKey) {
                    e.preventDefault();
                    e.stopPropagation();
                    showNotification("Exiting fullscreen is disabled during the exam.", 'warning');
                }

                // Attempt to disable Ctrl+W (Close tab) and Ctrl+T (New tab)
                if ((e.ctrlKey && (e.key === 'w' || e.key === 'W' || e.key === 't' || e.key === 'T'))) {
                    e.preventDefault();
                    e.stopPropagation();
                    showNotification("This action is disabled during the exam.", 'warning');
                }
            });
        }

        // Function to setup window focus handling
        function setupWindowFocusHandling() {
            window.addEventListener('blur', function() {
                
                // Optionally, forcefully bring the window back into focus
                window.focus();
            });
        }

        // Function to submit the exam with a message
        function submitExamWithMessage(message) {
            showNotification(message, 'error');
            // Optionally, you can delay the submission to allow the user to read the message
            setTimeout(() => {
                document.getElementById('examForm').submit();
            }, 3000); // 3 seconds delay
        }

        // Function to save answers via AJAX when inputs change
        function setupAnswerSaving() {
            // Select all input fields (radio buttons and textareas)
            const radioInputs = document.querySelectorAll('input[type="radio"]');
            const textareas = document.querySelectorAll('textarea');

            // For radio buttons
            radioInputs.forEach(input => {
                input.addEventListener('change', function() {
                    const questionId = this.getAttribute('data-question-id');
                    let answer = '';

                    // Get the selected value for radio buttons
                    const selectedOption = document.querySelector(`input[name="answer_${questionId}"]:checked`);
                    if (selectedOption) {
                        answer = selectedOption.value;
                    }

                    // Send the answer to the server via AJAX
                    saveAnswer(questionId, answer);
                });
            });

            // For textareas (identification and essay questions)
            textareas.forEach(textarea => {
                // Skip hidden textareas used for code editors
                if (textarea.style.display === 'none') return;

                textarea.addEventListener('input', function() {
                    const questionId = this.getAttribute('data-question-id');
                    const answer = this.value;

                    // Send the answer to the server via AJAX
                    saveAnswer(questionId, answer);
                });
            });

            // For code editors (code-type questions)
            // This will be handled by Monaco Editor's onDidChangeModelContent event
        }

        function saveAnswer(questionId, answer) {
            const xhr = new XMLHttpRequest();
            xhr.open('POST', 'save_answer.php', true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

            // Prepare CSRF token
            const csrf_token = '<?php echo $csrf_token; ?>';

            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        try {
                            const response = JSON.parse(xhr.responseText);
                            if (response.success) {
                                console.log(`Answer for question ${questionId} saved successfully.`);
                            } else {
                                console.error('Error saving answer:', response.error);
                            }
                        } catch (e) {
                            console.error('Invalid JSON response from server.');
                        }
                    } else {
                        console.error('Error saving answer. Status:', xhr.status);
                    }
                }
            };

            // Send data
            const params = `csrf_token=${encodeURIComponent(csrf_token)}&question_id=${encodeURIComponent(questionId)}&answer=${encodeURIComponent(answer)}`;
            xhr.send(params);
        }

        // Function to start the exam timer and setup remaining_time updater
        function startTimer(initialDuration) {
            // Convert duration (HH:MM:SS) to total seconds
            const timerParts = initialDuration.split(':');
            let hours = parseInt(timerParts[0], 10);
            let minutes = parseInt(timerParts[1], 10);
            let seconds = parseInt(timerParts[2], 10);
            let totalSeconds = hours * 3600 + minutes * 60 + seconds;

            // Display the initial timer
            updateTimerDisplay(totalSeconds);

            // Update the timer every second
            const countdownInterval = setInterval(function() {
                totalSeconds--;

                if (totalSeconds <= 0) {
                    clearInterval(countdownInterval);
                    clearInterval(updateInterval);
                    // Display notification when time is up
                    submitExamWithMessage("Time is up! Your exam will now be submitted.");
                    return;
                }

                updateTimerDisplay(totalSeconds);
            }, 1000); // Update every second

            // Update remaining_time in the database every second (1000 ms)
            const updateInterval = setInterval(function() {
                if (totalSeconds > 0) {
                    const remaining_time = formatTime(totalSeconds);
                    updateRemainingTime(remaining_time);
                }
            }, 1000); // Every second

            // Function to format seconds into HH:MM:SS
            function formatTime(seconds) {
                const h = Math.floor(seconds / 3600);
                const m = Math.floor((seconds % 3600) / 60);
                const s = seconds % 60;

                return `${h < 10 ? "0" : ""}${h}:${m < 10 ? "0" : ""}${m}:${s < 10 ? "0" : ""}${s}`;
            }

            // Function to send remaining_time to the server
            function updateRemainingTime(remaining_time) {
                const xhr = new XMLHttpRequest();
                xhr.open('POST', 'update_time.php', true);
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

                // Prepare CSRF token
                const csrf_token = '<?php echo $csrf_token; ?>';

                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4) {
                        if (xhr.status === 200) {
                            try {
                                const response = JSON.parse(xhr.responseText);
                                if (response.success) {
                                    console.log('Remaining time updated successfully.');
                                } else {
                                    console.error('Error updating remaining time:', response.error);
                                }
                            } catch (e) {
                                console.error('Invalid JSON response from server.');
                            }
                        } else {
                            console.error('Error updating remaining time. Status:', xhr.status);
                        }
                    }
                };

                // Send data
                xhr.send(`csrf_token=${encodeURIComponent(csrf_token)}&remaining_time=${encodeURIComponent(remaining_time)}`);
            }

            // Function to update the timer display
            function updateTimerDisplay(totalSeconds) {
                const h = Math.floor(totalSeconds / 3600);
                const m = Math.floor((totalSeconds % 3600) / 60);
                const s = totalSeconds % 60;

                // Change color based on remaining time thresholds
                const timerElement = document.getElementById('timer');
                if (totalSeconds <= 60) {
                    timerElement.style.color = 'red';
                } else if (totalSeconds <= 300) { // 5 minutes
                    timerElement.style.color = 'orange';
                } else {
                    timerElement.style.color = 'green';
                }

                timerElement.textContent = 
                    `${h < 10 ? "0" : ""}${h}:${m < 10 ? "0" : ""}${m}:${s < 10 ? "0" : ""}${s}`;
            }
        }

        // Initialize the exam on window load
        window.onload = function() {
            <?php if ($exam_done): ?>
                showNotification("You have already responded to the exam.", 'info');
                setTimeout(() => {
                    window.location.href = 'index.php'; // Redirect after showing notification
                }, 3000); // 3 seconds delay
            <?php endif; ?>
            // Note: Fullscreen and monitoring will be initiated after clicking "Take Exam"
        };
    </script>
</head>
<body>
    <div class="detailsko">
        <div class="exam-header">
            <i class="fas fa-clock"></i>
            <div id="timer">00:00:00</div>
        </div>
        <div class="exam-info">
            <p><strong>Title:</strong> <?php echo $exam_title; ?></p>
            <p><strong>Subject:</strong> <?php echo $subject; ?></p>
            <!-- Optional: Display Total Points -->
            <p class="total-points"><strong><?php echo $total_points; ?> points</strong></p>
        </div>
    </div>

    <div id="examDetails">
        <?php if (!$exam_done): ?>
            <?php if (!empty($questions_with_types)): ?>
                <!-- Instructions (Optional) -->
                <div class="instructions">
                    <p>Please ensure you are in fullscreen mode before starting the exam. Exiting fullscreen mode or switching windows may result in your exam being submitted automatically.</p>
                </div>

                <!-- Take Exam Button -->
                <button id="takeExamBtn" class="submit-btn">Take Exam</button>

                <!-- Exam Form, hidden initially -->
                <form id="examForm" method="post" action="submit_exam.php" style="display: none;">
                    <!-- CSRF Token -->
                    <input type="hidden" name="csrf_token" value="<?php echo $csrf_token; ?>">
                    
                    <?php foreach ($questions_with_types as $index => $question): ?>
                        <div class="question">
                            
                            <?php
                            $question_id = $question['question_id'];
                            $question_type = $question['question_type'];
                            $points = htmlspecialchars($question['points'] ?? '0', ENT_QUOTES, 'UTF-8'); // Sanitize points
                            $topic = htmlspecialchars($question['topic'] ?? '', ENT_QUOTES, 'UTF-8'); // Sanitize topic

                            // Display directions based on question type
                            switch ($question_type) {
                                case 'single_choice':
                                    echo '<p><b><em>Multiple Choice</em></b></p>';
                                    break;
                                case 'true_false':
                                    echo '<p><b><em>True or False</em></b></p>';
                                    break;
                                case 'identification':
                                    echo '<p><b><em>Identification</em></b></p>';
                                    break;
                                case 'essay':
                                    echo '<p><b><em>Essay</em></b></p>';
                                    break;
                                case 'code':
                                    echo '<p><b><em>Code</em></b></p>';
                                    break;
                                default:
                                    // Other types
                                    break;
                            }
                            ?>
                            <p class="points" style="color: green;"><?php echo $points; ?> points</p>
                            <br>
                            <!-- Display Question Number, Points, and Question Text -->
                            <p>
                                <strong>Question <?php echo $index + 1; ?>:</strong> 
                                <?php echo htmlspecialchars($question['question'] ?? '', ENT_QUOTES, 'UTF-8'); ?>
                            </p>
                            <br>

                            <?php
                            // Get the saved answer for this question if available
                            $saved_answer = isset($saved_answers[$question_id]) ? $saved_answers[$question_id] : '';

                            if ($question_type === 'single_choice'):

                                // Check if shuffled_options for this question is already set in session
                                if (!isset($_SESSION['shuffled_options'][$question_id])) {
                                    // Fetch options for single choice questions
                                    $options_stmt = $conn->prepare("SELECT option_text FROM `option` WHERE question_id = ?");
                                    if ($options_stmt) {
                                        $options_stmt->bind_param("i", $question_id);
                                        $options_stmt->execute();
                                        $options_result = $options_stmt->get_result();

                                        $options = array();
                                        if ($options_result->num_rows > 0):
                                            while ($option_row = $options_result->fetch_assoc()):
                                                $options[] = $option_row['option_text'];
                                            endwhile;
                                        endif;

                                        $options_stmt->close();

                                        // Shuffle the options to randomize their order
                                        shuffle($options);

                                        // Store the shuffled options in session
                                        $_SESSION['shuffled_options'][$question_id] = $options;
                                    } else {
                                        echo "Failed to fetch options.";
                                    }
                                } else {
                                    // Retrieve shuffled options from session
                                    $options = $_SESSION['shuffled_options'][$question_id];
                                }

                                // Display the shuffled options
                                foreach ($options as $option_text):
                                    // Ensure option_text is a string
                                    $option_text_safe = is_string($option_text) ? $option_text : '';
                                    // Check if this option is the saved answer
                                    $isChecked = ($option_text_safe === $saved_answer) ? 'checked' : '';
                                    ?>
                                    <label>
                                        <input type="radio" name="answer_<?php echo $question_id; ?>" id="answer_<?php echo $question_id; ?>_<?php echo htmlspecialchars($option_text_safe, ENT_QUOTES, 'UTF-8'); ?>" data-question-id="<?php echo $question_id; ?>" value="<?php echo htmlspecialchars($option_text_safe, ENT_QUOTES, 'UTF-8'); ?>" <?php echo $isChecked; ?> required>
                                        <?php echo htmlspecialchars($option_text_safe, ENT_QUOTES, 'UTF-8'); ?>
                                    </label>
                                    <br>
                                    <?php
                                endforeach;

                            elseif ($question_type === 'true_false'):
                                // Check if shuffled_options for this question is already set in session
                                if (!isset($_SESSION['shuffled_options'][$question_id])) {
                                    // Define True and False options
                                    $tf_options = ['True', 'False'];

                                    // Shuffle the options to randomize their order
                                    shuffle($tf_options);

                                    // Store the shuffled options in session
                                    $_SESSION['shuffled_options'][$question_id] = $tf_options;
                                } else {
                                    // Retrieve shuffled options from session
                                    $tf_options = $_SESSION['shuffled_options'][$question_id];
                                }

                                // Display the shuffled options
                                foreach ($tf_options as $option_text):
                                    // Ensure option_text is a string
                                    $option_text_safe = is_string($option_text) ? $option_text : '';
                                    // Check if this option is the saved answer
                                    $isChecked = ($option_text_safe === $saved_answer) ? 'checked' : '';
                                    ?>
                                    <label>
                                        <input type="radio" name="answer_<?php echo $question_id; ?>" id="answer_<?php echo $question_id; ?>_<?php echo htmlspecialchars($option_text_safe, ENT_QUOTES, 'UTF-8'); ?>" data-question-id="<?php echo $question_id; ?>" value="<?php echo htmlspecialchars($option_text_safe, ENT_QUOTES, 'UTF-8'); ?>" <?php echo $isChecked; ?> required>
                                        <?php echo htmlspecialchars($option_text_safe, ENT_QUOTES, 'UTF-8'); ?>
                                    </label>
                                    <br>
                                    <?php
                                endforeach;
                            elseif ($question_type === 'identification' || $question_type === 'essay'):
                                // Ensure $saved_answer is a string
                                $saved_answer_safe = is_string($saved_answer) ? $saved_answer : '';
                                ?>
                                <p>
                                    <label for="answer_<?php echo $question_id; ?>">Answer:</label>
                                    <textarea id="answer_<?php echo $question_id; ?>" name="answer_<?php echo $question_id; ?>" data-question-id="<?php echo $question_id; ?>" rows="4" cols="50" required><?php echo htmlspecialchars($saved_answer_safe, ENT_QUOTES, 'UTF-8'); ?></textarea>
                                </p>
                            <?php elseif ($question_type === 'code'): ?>
                                <?php
                                // Determine the programming language for syntax highlighting
                                $language = isset($languageMapping[$topic]) ? $languageMapping[$topic] : 'javascript';
                                
                                // Ensure the language is supported by Monaco Editor
                                $supportedLanguages = ['javascript', 'python', 'java', 'c', 'cpp', 'html', 'css', 'ruby', 'php', 'swift', 'go'];
                                if (!in_array($language, $supportedLanguages)) {
                                    $language = 'javascript'; // Default to JavaScript if unsupported
                                }

                                // Retrieve starter code or use empty string if not defined
                                $starter_code = isset($codePlaceholders[$language]) ? $codePlaceholders[$language] : '';
                                
                                // If there's a saved answer, use it; otherwise, use the starter code
                                $initial_code = !empty($saved_answers[$question_id]) ? $saved_answers[$question_id] : $starter_code;
                                
                                // Ensure $initial_code is a string
                                $initial_code_safe = is_string($initial_code) ? $initial_code : '';
                                ?>
                                <p>
                                    <label for="editor_<?php echo $question_id; ?>">Your Code:</label>
                                    <!-- Container for Monaco Editor -->
                                    <div id="editor_<?php echo $question_id; ?>" class="code-editor"></div>
                                    <!-- Hidden textarea to capture Monaco Editor content -->
                                    <textarea id="answer_<?php echo $question_id; ?>" name="answer_<?php echo $question_id; ?>" data-question-id="<?php echo $question_id; ?>" style="display: none;" required><?php echo htmlspecialchars($initial_code_safe, ENT_QUOTES, 'UTF-8'); ?></textarea>
                                </p>
                            <?php else: ?>
                                <!-- Handle other types if any -->
                            <?php endif; ?>
                        </div>
                        <hr> <!-- Separator between questions -->
                    <?php endforeach; ?>
                    
                    <!-- Submit Button -->
                    <button type="button" class="submit-btn" onclick="submitExam()">Submit Exam</button>
                </form>
            <?php else: ?>
                <script type="text/javascript">
                    // Function to display the notification and redirect
                    function showNotificationAndRedirect() {
                        showNotification('No questions found for this exam.', 'error');
                        setTimeout(() => {
                            window.location.href = 'index.php'; // Redirect to index.php
                        }, 3000); // 3 seconds delay
                    }
                    showNotificationAndRedirect();
                </script>
            <?php endif; ?>
        <?php endif; ?>
    </div>

    <!-- Submission Confirmation Modal -->
    <div id="confirmationModal" class="modal">
        <div class="modal-content">
            <span class="close-button" onclick="closeModal()">&times;</span>
            <p>Are you sure you want to submit the exam?</p>
            <div class="modal-buttons">
                <button id="yesButton">Yes</button>
                <button id="noButton">No</button>
            </div>
        </div>
    </div>

    <!-- Fullscreen Exit Notification Modal -->
    <div id="fullscreenExitModal" class="modal">
        <div class="modal-content">
            <span class="close-button" onclick="closeFullscreenExitModal()">&times;</span>
            <p>You have exited fullscreen mode. Please return to fullscreen to continue your exam.</p>
            <div class="modal-buttons">
                <button id="fullscreenOkButton">OK</button>
            </div>
        </div>
    </div>

    <!-- Instructions Modal (Optional) -->
    <!-- You can uncomment and use this if you want to display instructions in a modal instead of a div -->
    <!--
    <div id="instructionsModal" class="modal">
        <div class="modal-content">
            <span class="close-button" onclick="closeInstructionsModal()">&times;</span>
            <p>Please ensure you are in fullscreen mode before starting the exam. Exiting fullscreen mode or switching windows may result in your exam being submitted automatically.</p>
            <div class="modal-buttons">
                <button onclick="closeInstructionsModal()">OK</button>
            </div>
        </div>
    </div>
    -->

    <!-- Monaco Editor Initialization Script -->
    <script>
        require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs' }});
        require(['vs/editor/editor.main'], function() {
            // Ensure 'code_questions' is only declared once
            const code_questions = <?php
                // Prepare a PHP array of code-type questions
                $code_questions = [];
                foreach ($questions_with_types as $question) {
                    if ($question['question_type'] === 'code') {
                        $q_id = $question['question_id'];
                        $topic = strtolower(trim($question['topic']));
                        // Map topic to language, default to javascript
                        $language = isset($languageMapping[$topic]) ? $languageMapping[$topic] : 'javascript';
                        // Placeholder code based on language (optional)
                        $starter_code = isset($codePlaceholders[$language]) ? $codePlaceholders[$language] : '';
                        $initialCode = !empty($saved_answers[$q_id]) ? $saved_answers[$q_id] : $starter_code;

                        $code_questions[] = [
                            'question_id' => $q_id,
                            'language' => $language,
                            'initial_code' => $initialCode
                        ];
                    }
                }
                // Convert PHP array to JSON
                echo json_encode($code_questions);
            ?>;

            code_questions.forEach(question => {
                const editorId = `editor_${question.question_id}`;
                const textareaId = `answer_${question.question_id}`;
                const language = question.language || 'javascript';
                const initialCode = question.initial_code || '';

                const editorContainer = document.getElementById(editorId);
                const hiddenTextarea = document.getElementById(textareaId);

                if (!editorContainer || !hiddenTextarea) {
                    console.error(`Missing editor or textarea for question ID: ${question.question_id}`);
                    return;
                }

                // Initialize Monaco Editor
                const editor = monaco.editor.create(editorContainer, {
                    value: initialCode,
                    language: language,
                    theme: 'vs-dark',
                    automaticLayout: true
                });

                // Disable copy, cut, and paste within the editor
                editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_C, () => {});
                editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_V, () => {});
                editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_X, () => {});

                // Update the hidden textarea whenever the editor content changes
                editor.onDidChangeModelContent(() => {
                    hiddenTextarea.value = editor.getValue();
                });

                // Initialize the hidden textarea with the initial editor content
                hiddenTextarea.value = editor.getValue();
            });
        });
    </script>
</body>
</html>




make it in full code with no missing components, please?