// Main application logic const API_BASE = '/api'; let currentMazeId = null; let currentMazeData = null; // DOM Elements const generateBtn = document.getElementById('generateBtn'); const visualizeBtn = document.getElementById('visualizeBtn'); const downloadBtn = document.getElementById('downloadBtn'); const saveBtn = document.getElementById('saveBtn'); const loadBtn = document.getElementById('loadBtn'); const solveDfsBtn = document.getElementById('solveDfsBtn'); const solveBfsBtn = document.getElementById('solveBfsBtn'); const analyzeBtn = document.getElementById('analyzeBtn'); const benchmarkBtn = document.getElementById('benchmarkBtn'); const algorithmSelect = document.getElementById('algorithm'); const rowsInput = document.getElementById('rows'); const colsInput = document.getElementById('cols'); const seedInput = document.getElementById('seed'); const solverSelect = document.getElementById('solver'); const resultsContent = document.getElementById('resultsContent'); const mazeInfo = document.getElementById('mazeInfo'); // Disable buttons initially function disableActionButtons() { visualizeBtn.disabled = true; downloadBtn.disabled = true; saveBtn.disabled = true; solveDfsBtn.disabled = true; solveBfsBtn.disabled = true; analyzeBtn.disabled = true; } function enableActionButtons() { visualizeBtn.disabled = false; downloadBtn.disabled = false; saveBtn.disabled = false; solveDfsBtn.disabled = false; solveBfsBtn.disabled = false; analyzeBtn.disabled = false; } disableActionButtons(); // Event Listeners generateBtn.addEventListener('click', generateMaze); visualizeBtn.addEventListener('click', visualizeMaze); downloadBtn.addEventListener('click', downloadMaze); saveBtn.addEventListener('click', saveMaze); loadBtn.addEventListener('click', showLoadModal); solveDfsBtn.addEventListener('click', () => solveMaze('dfs')); solveBfsBtn.addEventListener('click', () => solveMaze('bfs')); analyzeBtn.addEventListener('click', analyzeMaze); benchmarkBtn.addEventListener('click', runBenchmark); // Generate Maze async function generateMaze() { const algorithm = algorithmSelect.value; const rows = parseInt(rowsInput.value); const cols = parseInt(colsInput.value); const seed = seedInput.value ? parseInt(seedInput.value) : null; if (rows < 5 || rows > 50 || cols < 5 || cols > 50) { showError('Dimensions must be between 5 and 50'); return; } setLoading(generateBtn, true); try { const response = await fetch(`${API_BASE}/generate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ algorithm, rows, cols, seed }) }); const data = await response.json(); if (data.success) { currentMazeId = data.id; currentMazeData = data.maze; enableActionButtons(); showSuccess('Maze generated successfully!'); displayMazeInfo(data.maze); visualizeMaze(); } else { showError(data.error || 'Failed to generate maze'); } } catch (error) { showError('Network error: ' + error.message); } finally { setLoading(generateBtn, false); } } // Visualize Maze function visualizeMaze() { if (!currentMazeData) { showError('No maze to visualize'); return; } renderMaze(currentMazeData); showInfo('Maze visualized'); } // Download Maze async function downloadMaze() { if (currentMazeId === null) { showError('No maze to download'); return; } try { window.open(`${API_BASE}/download/${currentMazeId}?solution=false`, '_blank'); showSuccess('Downloading maze image...'); } catch (error) { showError('Failed to download: ' + error.message); } } // Save Maze async function saveMaze() { if (currentMazeId === null) { showError('No maze to save'); return; } const filename = prompt('Enter filename:', `maze_${currentMazeId}`); if (!filename) return; try { const response = await fetch(`${API_BASE}/save/${currentMazeId}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ filename }) }); const data = await response.json(); if (data.success) { showSuccess(`Maze saved to: ${data.filepath}`); } else { showError(data.error || 'Failed to save maze'); } } catch (error) { showError('Network error: ' + error.message); } } // Load Maze Modal async function showLoadModal() { const modal = document.getElementById('loadModal'); const fileList = document.getElementById('fileList'); const closeBtn = document.getElementById('closeModal'); try { const response = await fetch(`${API_BASE}/saved-mazes`); const data = await response.json(); if (data.files && data.files.length > 0) { fileList.innerHTML = data.files.map(file => `
${file}
` ).join(''); } else { fileList.innerHTML = '

No saved mazes found

'; } modal.classList.add('active'); closeBtn.onclick = () => modal.classList.remove('active'); modal.onclick = (e) => { if (e.target === modal) modal.classList.remove('active'); }; } catch (error) { showError('Failed to load file list: ' + error.message); } } async function loadMazeFile(filename) { const modal = document.getElementById('loadModal'); modal.classList.remove('active'); try { const response = await fetch(`${API_BASE}/load`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ filename }) }); const data = await response.json(); if (data.success) { currentMazeId = data.id; currentMazeData = data.maze; enableActionButtons(); showSuccess(`Loaded: ${filename}`); displayMazeInfo(data.maze); visualizeMaze(); } else { showError(data.error || 'Failed to load maze'); } } catch (error) { showError('Network error: ' + error.message); } } // Solve Maze async function solveMaze(algorithm) { if (currentMazeId === null) { showError('No maze to solve'); return; } const btn = algorithm === 'dfs' ? solveDfsBtn : solveBfsBtn; setLoading(btn, true); try { const response = await fetch(`${API_BASE}/solve`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ maze_id: currentMazeId, algorithm }) }); const data = await response.json(); if (data.success) { renderMaze(currentMazeData, data.visited, data.path); displaySolutionInfo(data); showSuccess(`Maze solved using ${data.algorithm}!`); } else { showError('Failed to solve maze'); } } catch (error) { showError('Network error: ' + error.message); } finally { setLoading(btn, false); } } // Analyze Maze async function analyzeMaze() { if (currentMazeId === null) { showError('No maze to analyze'); return; } setLoading(analyzeBtn, true); try { const response = await fetch(`${API_BASE}/analyze/${currentMazeId}`); const data = await response.json(); displayAnalysisResults(data); showSuccess('Analysis complete!'); } catch (error) { showError('Network error: ' + error.message); } finally { setLoading(analyzeBtn, false); } } // Run Benchmark async function runBenchmark() { setLoading(benchmarkBtn, true); showInfo('Running benchmarks... This may take a moment.'); try { const response = await fetch(`${API_BASE}/benchmark`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ type: 'quick' }) }); const data = await response.json(); displayBenchmarkResults(data); showSuccess('Benchmark complete!'); } catch (error) { showError('Network error: ' + error.message); } finally { setLoading(benchmarkBtn, false); } } // Display Functions function displayMazeInfo(maze) { mazeInfo.innerHTML = ` ALGORITHM: ${maze.algorithm}
SIZE: ${maze.rows} × ${maze.cols}
GENERATION TIME: ${maze.generationTime.toFixed(2)} ms `; } function displaySolutionInfo(solution) { const section = document.createElement('div'); section.className = 'result-section'; section.innerHTML = `

SOLUTION: ${solution.algorithm}

Path Length: ${solution.path_length} cells
Cells Visited: ${solution.visited.length}
Solve Time: ${solution.time_ms.toFixed(2)} ms
`; resultsContent.innerHTML = ''; resultsContent.appendChild(section); } function displayAnalysisResults(analysis) { const section = document.createElement('div'); section.className = 'result-section'; section.innerHTML = `

MAZE ANALYSIS

Dimensions: ${analysis.dimensions}
Total Cells: ${analysis.total_cells}
Algorithm: ${analysis.algorithm}
Dead Ends: ${analysis.dead_ends} (${analysis.dead_end_percentage.toFixed(1)}%)
Longest Path: ${analysis.longest_path_length} cells
Avg Branching: ${analysis.average_branching_factor.toFixed(2)}
`; resultsContent.innerHTML = ''; resultsContent.appendChild(section); } function displayBenchmarkResults(data) { let html = '

GENERATOR BENCHMARK

'; html += ''; data.generators.results.forEach(r => { html += ``; }); html += '
AlgorithmSizeAvg Time (ms)
${r.algorithm}${r.size}${r.avg_time_ms}
'; html += '

SOLVER BENCHMARK

'; html += ''; data.solvers.results.forEach(r => { html += ``; }); html += '
AlgorithmSizeAvg Time (ms)Path Length
${r.algorithm}${r.size}${r.avg_time_ms}${r.avg_path_length}
'; resultsContent.innerHTML = html; } // Utility Functions function showSuccess(message) { showStatus(message, 'success'); } function showError(message) { showStatus(message, 'error'); } function showInfo(message) { showStatus(message, 'info'); } function showStatus(message, type) { const existing = document.querySelector('.status-message'); if (existing) existing.remove(); const div = document.createElement('div'); div.className = `status-message status-${type}`; div.textContent = message; resultsContent.insertBefore(div, resultsContent.firstChild); setTimeout(() => div.remove(), 5000); } function setLoading(button, isLoading) { if (isLoading) { button.dataset.originalText = button.textContent; button.textContent = 'LOADING...'; button.disabled = true; } else { button.textContent = button.dataset.originalText || button.textContent; button.disabled = false; } }