File size: 11,514 Bytes
8ad412d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// document.addEventListener('DOMContentLoaded', () => {
//     const socket = io();

//     const videoPlayer = document.getElementById('videoPlayer');
//     const yoloTextLabel = document.getElementById('yoloTextLabel');
//     const yoloImageFrame = document.getElementById('yoloImageFrame');
//     const statusLabel = document.getElementById('statusLabel');
//     const resetButton = document.getElementById('resetButton');
//     const videoUploadInput = document.getElementById('videoUpload');
//     const uploadButton = document.getElementById('uploadButton');
    
//     // CHANGED: Get the new dropdown selector
//     const anomalySelector = document.getElementById('anomalySelector');

//     let chart;

//     function initializeChart() {
//         const ctx = document.getElementById('anomalyChart').getContext('2d');
//         if (chart) { chart.destroy(); }
//         chart = new Chart(ctx, {
//             type: 'line', data: { labels: [], datasets: [{ label: 'Anomaly Score', data: [], borderColor: 'rgba(255, 99, 132, 1)', backgroundColor: 'rgba(255, 99, 132, 0.2)', borderWidth: 2, tension: 0.4, pointRadius: 0 }] }, options: { scales: { y: { beginAtZero: true, max: 1.0, ticks: { color: '#e0e0e0' }}, x: { ticks: { color: '#e0e0e0' }}}, plugins: { legend: { labels: { color: '#e0e0e0' }}}}
//         });
//     }

//     function resetUI() {
//         videoPlayer.pause();
//         videoPlayer.removeAttribute('src');
//         videoPlayer.load();
//         initializeChart();
//         yoloTextLabel.textContent = 'Waiting for anomaly...';
//         yoloImageFrame.src = '';
//         statusLabel.textContent = 'System reset. Select a video to begin.';
//         videoUploadInput.value = '';
//         anomalySelector.selectedIndex = 0; // Reset dropdown to the default option
//     }

//     // --- WebSocket Event Listeners (unchanged) ---
//     socket.on('connect', () => { statusLabel.textContent = 'Connected. Please select a video to start processing.'; });
//     socket.on('update_graph', (data) => {
//         const { score } = data;
//         if (!chart) return;
//         const newLabel = chart.data.labels.length + 1;
//         chart.data.labels.push(newLabel);
//         chart.data.datasets[0].data.push(score);
//         if (chart.data.labels.length > 100) { chart.data.labels.shift(); chart.data.datasets[0].data.shift(); }
//         chart.update();
//     });
//     socket.on('update_yolo_text', (data) => { yoloTextLabel.textContent = data.text; });
//     socket.on('update_yolo_image', (data) => { yoloImageFrame.src = `data:image/jpeg;base64,${data.image_data}`; });
//     socket.on('update_status', (data) => { statusLabel.textContent = data.status; });
//     socket.on('processing_error', (data) => { statusLabel.textContent = `Error: ${data.error}`; });
//     socket.on('processing_finished', (data) => { statusLabel.textContent = data.message; });
//     socket.on('system_reset_confirm', () => { resetUI(); });

//     // --- User Interaction ---

//     // CHANGED: Replaced the old event listener for links with one for the dropdown
//     anomalySelector.addEventListener('change', (event) => {
//         const anomalyName = event.target.value;
//         if (!anomalyName) return; // Do nothing if the default option is selected

//         resetUI();
//         statusLabel.textContent = `Requesting to process ${anomalyName}...`;
        
//         videoPlayer.src = `/video_stream/demo/${anomalyName}`;
//         videoPlayer.play();
        
//         socket.emit('start_processing', { 'source': 'demo', 'filename': anomalyName });
//     });

//     resetButton.addEventListener('click', () => { socket.emit('reset_system'); });

//     // Upload button logic (unchanged)
//     uploadButton.addEventListener('click', () => {
//         const file = videoUploadInput.files[0];
//         if (!file) {
//             alert('Please select a video file first!');
//             return;
//         }
        
//         resetUI();
//         statusLabel.textContent = 'Uploading video...';
        
//         const formData = new FormData();
//         formData.append('video', file);

//         fetch('/upload', { method: 'POST', body: formData })
//         .then(response => response.json())
//         .then(data => {
//             if (data.success) {
//                 const uploadedFilename = data.filename;
//                 statusLabel.textContent = `Upload successful. Starting analysis...`;
//                 videoPlayer.src = `/video_stream/upload/${uploadedFilename}`;
//                 videoPlayer.play();
//                 socket.emit('start_processing', { 'source': 'upload', 'filename': uploadedFilename });
//             } else {
//                 statusLabel.textContent = `Error: ${data.error}`;
//                 alert(`Upload failed: ${data.error}`);
//             }
//         })
//         .catch(error => {
//             statusLabel.textContent = 'An error occurred during upload.';
//             console.error('Upload error:', error);
//         });
//     });

//     initializeChart();
// });

document.addEventListener('DOMContentLoaded', () => {
    const socket = io();

    // Get all UI elements
    const videoPlayer = document.getElementById('videoPlayer');
    const yoloTextLabel = document.getElementById('yoloTextLabel');
    const yoloImageFrame = document.getElementById('yoloImageFrame');
    const statusLabel = document.getElementById('statusLabel');
    const resetButton = document.getElementById('resetButton');
    const anomalySelector = document.getElementById('anomalySelector');
    const videoUploadInput = document.getElementById('videoUpload');
    const uploadButton = document.getElementById('uploadButton');
    
    // Get the new summary elements
    const summaryTextLabel = document.getElementById('summaryTextLabel');
    const summaryLoaderContainer = document.getElementById('summaryLoaderContainer');

    let chart;

    function initializeChart() {
        const ctx = document.getElementById('anomalyChart').getContext('2d');
        if (chart) { chart.destroy(); }
        chart = new Chart(ctx, {
            type: 'line', data: { labels: [], datasets: [{ label: 'Anomaly Score', data: [], borderColor: 'rgba(255, 99, 132, 1)', backgroundColor: 'rgba(255, 99, 132, 0.2)', borderWidth: 2, tension: 0.4, pointRadius: 0 }] }, options: { scales: { y: { beginAtZero: true, max: 1.0, ticks: { color: '#e0e0e0' }}, x: { ticks: { color: '#e0e0e0' }}}, plugins: { legend: { labels: { color: '#e0e0e0' }}}}
        });
    }

    // This function resets the whole UI
    function resetUI() {
        videoPlayer.pause();
        videoPlayer.removeAttribute('src');
        videoPlayer.load();
        initializeChart();
        yoloTextLabel.textContent = 'Waiting for anomaly...';
        yoloImageFrame.src = '';
        statusLabel.textContent = 'System reset. Select a video to begin.';
        videoUploadInput.value = '';
        anomalySelector.selectedIndex = 0;
        
        // Reset the summary box
        summaryLoaderContainer.style.display = 'none'; // Hide loader
        summaryTextLabel.style.display = 'block'; // Show text
        summaryTextLabel.textContent = 'Summary will appear here after analysis...';
    }

    // --- WebSocket Event Listeners ---
    socket.on('connect', () => { statusLabel.textContent = 'Connected. Please select a video to start processing.'; });
    socket.on('update_graph', (data) => {
        const { score } = data;
        if (!chart) return;
        const newLabel = chart.data.labels.length + 1;
        chart.data.labels.push(newLabel);
        chart.data.datasets[0].data.push(score);
        if (chart.data.labels.length > 100) { chart.data.labels.shift(); chart.data.datasets[0].data.shift(); }
        chart.update();
    });
    socket.on('update_yolo_text', (data) => { yoloTextLabel.textContent = data.text; });
    socket.on('update_yolo_image', (data) => { yoloImageFrame.src = `data:image/jpeg;base64,${data.image_data}`; });
    socket.on('update_status', (data) => { statusLabel.textContent = data.status; });
    socket.on('processing_error', (data) => { statusLabel.textContent = `Error: ${data.error}`; });
    socket.on('processing_finished', (data) => { statusLabel.textContent = data.message; });
    socket.on('system_reset_confirm', () => { resetUI(); });

    // NEW: Listener for the recording light
    socket.on('recording_signal', (data) => {
        if (data.recording) {
            statusLabel.textContent = "Anomaly detected! Recording 30s clip...";
        } 
        // The 'false' signal is handled by the summary logic
    });

    // --- NEW: Logic for the summary box ---
    socket.on('update_summary', (data) => {
        const summary = data.summary;
        
        if (summary === 'loading') {
            // Show the loader
            summaryTextLabel.style.display = 'none';
            summaryLoaderContainer.style.display = 'flex';
        } else {
            // Hide the loader and show the final summary
            summaryLoaderContainer.style.display = 'none';
            summaryTextLabel.style.display = 'block';
            summaryTextLabel.textContent = summary; // Set the final text
            statusLabel.textContent = 'Analysis complete.'; // Update status
        }
    });

    // --- User Interaction (No changes) ---
    anomalySelector.addEventListener('change', (event) => {
        const anomalyName = event.target.value;
        if (!anomalyName) return; 
        resetUI();
        statusLabel.textContent = `Requesting to process ${anomalyName}...`;
        videoPlayer.src = `/video_stream/demo/${anomalyName}`;
        videoPlayer.play();
        socket.emit('start_processing', { 'source': 'demo', 'filename': anomalyName });
    });

    resetButton.addEventListener('click', () => { socket.emit('reset_system'); });

    uploadButton.addEventListener('click', () => {
        const file = videoUploadInput.files[0];
        if (!file) {
            alert('Please select a video file first!');
            return;
        }
        resetUI();
        statusLabel.textContent = 'Uploading video...';
        const formData = new FormData();
        formData.append('video', file);

        fetch('/upload', { method: 'POST', body: formData })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                const uploadedFilename = data.filename;
                statusLabel.textContent = `Upload successful. Starting analysis...`;
                videoPlayer.src = `/video_stream/upload/${uploadedFilename}`;
                videoPlayer.play();
                socket.emit('start_processing', { 'source': 'upload', 'filename': uploadedFilename });
            } else {
                statusLabel.textContent = `Error: ${data.error}`;
                alert(`Upload failed: ${data.error}`);
            }
        })
        .catch(error => {
            statusLabel.textContent = 'An error occurred during upload.';
            console.error('Upload error:', error);
        });
    });

    // Initialize the chart and UI on page load
    initializeChart();
    resetUI(); // Call reset to ensure correct initial state
});