`
+- **Purpose:** Main gameplay interface with task display
+- **Components:**
+ - `.task-container` - Task display and controls
+ - `.task-image-container` - Task image display
+ - `.task-text-container` - Task text display
+ - `.action-buttons` - Complete, Skip, Mercy Skip, Pause buttons
+ - `.game-stats` - Real-time session statistics
+- **Status:** โ **OBSOLETE** - Functionality moved to dedicated mode files
+
+### **2. PAUSED SCREEN (Lines 1678-1685)**
+- **Element:** `
`
+- **Purpose:** Game pause interface
+- **Components:**
+ - Resume button
+ - Quit button
+- **Status:** โ **OBSOLETE** - Handled in dedicated mode files
+
+### **3. GAME OVER SCREEN (Lines 1686-1700)**
+- **Element:** `
`
+- **Purpose:** End game statistics and replay option
+- **Components:**
+ - Final stats display (XP, time, tasks, streaks)
+ - Play again button
+- **Status:** โ **OBSOLETE** - Handled in dedicated mode files
+
+---
+
+## ๐ OBSOLETE SCRIPTS ANALYSIS
+
+### **4. GAME MODE DATA SCRIPTS (Lines 1705-1710)**
+- **Files:**
+ - `src/data/modes/mainGameData.js`
+ - `src/data/modes/humiliationGameData.js`
+ - `src/data/modes/trainingGameData.js`
+ - `src/data/modes/enduranceGameData.js`
+ - `src/data/modes/dressUpGameData.js`
+ - `src/data/gameDataManager.js`
+- **Status:** โ **MAY BE OBSOLETE** - Check if still used by dedicated HTML files
+
+### **5. GAME MODE MANAGER SCRIPT (Line 1843)**
+- **File:** `src/core/gameModeManager.js`
+- **Status:** โ **MAY BE OBSOLETE** - Check if still used by dedicated HTML files
+
+---
+
+## ๐ง OBSOLETE FUNCTIONALITY ANALYSIS
+
+### **6. SCREEN NAVIGATION SYSTEM**
+- **Functions:** `showScreen()` calls throughout JavaScript
+- **References:** Lines 1892, 1893, 3807, 3808, 3872, 3874, 3876, 3899, 3900
+- **Purpose:** Navigate between embedded game screens
+- **Status:** โ **PARTIALLY OBSOLETE** - Still needed for media management screens, but game mode navigation should be removed
+
+### **7. GAME STATE MANAGEMENT**
+- **Elements:** Session stats, final stats, game mode tracking
+- **Purpose:** Track progress within embedded game modes
+- **Status:** โ **OBSOLETE** - Now handled in dedicated HTML files
+
+### **8. TASK DISPLAY SYSTEM**
+- **Elements:** Task images, task text, action buttons
+- **Purpose:** Display and interact with game tasks
+- **Status:** โ **OBSOLETE** - Now handled in dedicated HTML files
+
+---
+
+## ๐ฏ KEEP vs REMOVE ANALYSIS
+
+### **โ
KEEP - Media Management Screens**
+These screens are still used for media library management:
+- `start-screen` - Home/landing page
+- `library-screen` - Media library management
+- `image-management-screen` - Image organization
+- `audio-management-screen` - Audio management
+- `video-management-screen` - Video management
+- `photo-gallery-screen` - Photo viewing
+- `annoyance-management-screen` - Settings management
+
+### **โ REMOVE - Game Mode Screens**
+These screens are obsolete after moving to dedicated HTML files:
+- `game-screen` - Main gameplay (moved to dedicated files)
+- `paused-screen` - Game pause (moved to dedicated files)
+- `game-over-screen` - End game stats (moved to dedicated files)
+
+---
+
+## ๐๏ธ CLEANUP PHASES
+
+### **PHASE 1: SCREEN REMOVAL**
+
+#### Step 1.1: Remove Game Screens
+- [ ] Delete `game-screen` element and all contents (Lines 1632-1677)
+- [ ] Delete `paused-screen` element and all contents (Lines 1678-1685)
+- [ ] Delete `game-over-screen` element and all contents (Lines 1686-1700)
+
+#### Step 1.2: Update Screen Navigation
+- [ ] Remove game screen references from `showScreen()` calls
+- [ ] Keep media management screen navigation intact
+- [ ] Remove obsolete screen transition JavaScript
+
+### **PHASE 2: SCRIPT CLEANUP**
+
+#### Step 2.1: Evaluate Game Mode Scripts
+- [ ] Check if `mainGameData.js` is used by dedicated HTML files
+- [ ] Check if `humiliationGameData.js` is used by dedicated files
+- [ ] Check if `trainingGameData.js` is used by dedicated files
+- [ ] Check if `enduranceGameData.js` is used by dedicated files
+- [ ] Check if `dressUpGameData.js` is used by dedicated files
+- [ ] Check if `gameDataManager.js` is used by dedicated files
+
+#### Step 2.2: Remove Unused Scripts
+- [ ] Remove script references from `index.html` if not used elsewhere
+- [ ] Keep script references if still used by dedicated HTML files
+
+#### Step 2.3: Evaluate Core Scripts
+- [ ] Check if `gameModeManager.js` is used by dedicated HTML files
+- [ ] Remove from `index.html` if not needed for media management
+
+### **PHASE 3: JAVASCRIPT CLEANUP**
+
+#### Step 3.1: Remove Game Mode Functions
+- [ ] Remove task display functions
+- [ ] Remove game state management functions
+- [ ] Remove game statistics functions
+- [ ] Remove game navigation functions (skip, complete, pause, etc.)
+
+#### Step 3.2: Clean Screen Navigation
+- [ ] Remove references to deleted screens in JavaScript
+- [ ] Update screen navigation to only handle media management screens
+- [ ] Clean up obsolete event listeners
+
+#### Step 3.3: Remove Game Mode Variables
+- [ ] Remove game state variables
+- [ ] Remove task management variables
+- [ ] Remove obsolete game mode tracking variables
+
+### **PHASE 4: CSS CLEANUP**
+
+#### Step 4.1: Remove Game Screen Styles
+- [ ] Remove `.task-container` and related styles
+- [ ] Remove `.task-image-container` styles
+- [ ] Remove `.task-text-container` styles
+- [ ] Remove `.action-buttons` styles
+- [ ] Remove `.game-stats` styles
+
+#### Step 4.2: Remove Game Mode Specific Styles
+- [ ] Remove paused screen styles
+- [ ] Remove game over screen styles
+- [ ] Remove game mode specific animations and transitions
+
+#### Step 4.3: Keep Media Management Styles
+- [ ] Keep all styles for media management screens
+- [ ] Keep start screen and library screen styles
+- [ ] Keep general screen navigation styles
+
+### **PHASE 5: HTML CLEANUP**
+
+#### Step 5.1: Remove Obsolete Elements
+- [ ] Remove task image containers
+- [ ] Remove action button containers
+- [ ] Remove game statistics displays
+- [ ] Remove final stats displays
+
+#### Step 5.2: Clean Comments and Documentation
+- [ ] Remove comments referring to removed screens
+- [ ] Update HTML structure comments
+- [ ] Clean up obsolete TODO comments
+
+---
+
+## ๐ ESTIMATED IMPACT
+
+### **Code Reduction:**
+- **HTML:** ~200 lines removed (obsolete game screens)
+- **CSS:** ~300 lines removed (game mode specific styles)
+- **JavaScript:** ~500 lines removed (game mode functions)
+- **Scripts:** 5-7 script references potentially removed
+- **Total:** ~1,000+ lines of obsolete code cleanup
+
+### **Performance Benefits:**
+- โ
Reduced index.html complexity and load time
+- โ
Cleaner separation of concerns (media management vs gameplay)
+- โ
Reduced JavaScript bundle size
+- โ
Faster startup time for index.html
+- โ
Simplified debugging and maintenance
+
+### **Architecture Benefits:**
+- โ
Clear separation between media management and gameplay
+- โ
index.html focused solely on media library management
+- โ
Dedicated HTML files handle all game mode functionality
+- โ
Reduced code duplication and conflicts
+- โ
Easier to maintain and extend individual game modes
+
+---
+
+## โ ๏ธ TESTING CHECKLIST
+
+After each phase, verify:
+- [ ] index.html loads and displays correctly
+- [ ] Start screen navigation works
+- [ ] Media library screens function properly
+- [ ] Image, audio, video management still works
+- [ ] Settings/annoyance management still works
+- [ ] No JavaScript console errors
+- [ ] Dedicated HTML files (quick-play.html, training-academy.html) still work
+- [ ] No broken links or missing resources
+- [ ] CSS styling remains consistent
+
+---
+
+## ๐ DEPENDENCIES CHECK
+
+Before cleanup, verify which dedicated HTML files use shared resources:
+- [ ] Check if quick-play.html uses game mode data files
+- [ ] Check if training-academy.html uses gameModeManager.js
+- [ ] Check if any dedicated files import from src/data/modes/
+- [ ] Check if any dedicated files use shared CSS from styles.css
+- [ ] Ensure cleanup doesn't break shared dependencies
+
+---
+
+## ๐ NOTES
+
+- **Primary Goal:** Remove obsolete game mode infrastructure from index.html
+- **Secondary Goal:** Maintain all media management functionality
+- **Tertiary Goal:** Ensure dedicated HTML files continue working
+- This cleanup addresses the architectural shift from embedded game modes to dedicated HTML files
+- All game mode functionality has been successfully moved to dedicated files
+- index.html should focus solely on being a media library management interface
+
+---
+
+*Document created after successful character image toggle implementation*
+*Next: Execute cleanup phases to remove obsolete game mode infrastructure*
\ No newline at end of file
diff --git a/training-academy.html b/training-academy.html
index deff5c1..18313d4 100644
--- a/training-academy.html
+++ b/training-academy.html
@@ -603,6 +603,215 @@
margin: 10px 0;
color: #e8f5e8;
}
+
+ /* Video Control Panel Styles */
+ .control-sidebar {
+ position: fixed;
+ top: 20px;
+ right: 20px;
+ width: 220px;
+ display: flex;
+ flex-direction: column;
+ background: rgba(0, 0, 0, 0.8);
+ border: 1px solid rgba(0, 212, 255, 0.3);
+ border-radius: 10px;
+ padding: 15px;
+ gap: 10px;
+ height: fit-content;
+ z-index: 1000;
+ }
+
+ .video-control-panel {
+ background: rgba(0, 0, 0, 0.9);
+ border: 1px solid rgba(139, 92, 246, 0.4);
+ border-radius: 8px;
+ margin-bottom: 15px;
+ overflow: hidden;
+ }
+
+ .video-control-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 10px 12px;
+ background: rgba(139, 92, 246, 0.2);
+ cursor: pointer;
+ transition: background 0.3s ease;
+ }
+
+ .video-control-header:hover {
+ background: rgba(139, 92, 246, 0.3);
+ }
+
+ .video-control-icon {
+ font-size: 1.2rem;
+ }
+
+ .video-control-title {
+ font-weight: 600;
+ color: #E5E7EB;
+ flex: 1;
+ text-align: center;
+ }
+
+ .video-control-toggle {
+ font-size: 0.9rem;
+ transition: transform 0.3s ease;
+ }
+
+ .video-control-toggle.collapsed {
+ transform: rotate(-90deg);
+ }
+
+ .video-control-content {
+ padding: 12px;
+ display: block;
+ transition: all 0.3s ease;
+ max-height: 400px;
+ overflow: hidden;
+ }
+
+ .video-control-content.collapsed {
+ display: none;
+ max-height: 0;
+ padding: 0 12px;
+ }
+
+ .control-group {
+ margin-bottom: 12px;
+ }
+
+ .control-group:last-child {
+ margin-bottom: 0;
+ }
+
+ .control-label {
+ display: block;
+ font-size: 0.8rem;
+ color: #9CA3AF;
+ margin-bottom: 5px;
+ font-weight: 500;
+ }
+
+ .control-row {
+ display: flex;
+ gap: 6px;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .control-btn {
+ background: rgba(139, 92, 246, 0.2);
+ color: #E5E7EB;
+ border: 1px solid rgba(139, 92, 246, 0.4);
+ border-radius: 6px;
+ padding: 6px 8px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ font-size: 0.8rem;
+ flex: 1;
+ min-width: 0;
+ text-align: center;
+ }
+
+ .control-btn:hover {
+ background: rgba(139, 92, 246, 0.4);
+ border-color: rgba(139, 92, 246, 0.6);
+ }
+
+ .volume-control {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .volume-slider {
+ flex: 1;
+ height: 4px;
+ background: rgba(255, 255, 255, 0.2);
+ border-radius: 2px;
+ outline: none;
+ -webkit-appearance: none;
+ appearance: none;
+ }
+
+ .volume-slider::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 14px;
+ height: 14px;
+ background: #8B5CF6;
+ border-radius: 50%;
+ cursor: pointer;
+ }
+
+ .volume-display {
+ font-size: 0.8rem;
+ color: #9CA3AF;
+ min-width: 35px;
+ text-align: right;
+ }
+
+ .playlist-select {
+ width: 100%;
+ background: rgba(0, 0, 0, 0.6);
+ color: #E5E7EB;
+ border: 1px solid rgba(139, 92, 246, 0.4);
+ border-radius: 6px;
+ padding: 6px 8px;
+ font-size: 0.8rem;
+ outline: none;
+ cursor: pointer;
+ }
+
+ .playlist-select:hover {
+ border-color: rgba(139, 92, 246, 0.6);
+ }
+
+ .playlist-select:focus {
+ border-color: #8B5CF6;
+ box-shadow: 0 0 0 2px rgba(139, 92, 246, 0.2);
+ }
+
+ .video-info {
+ background: rgba(0, 0, 0, 0.6);
+ border-radius: 6px;
+ padding: 8px;
+ }
+
+ .current-video-name {
+ font-size: 0.8rem;
+ color: #E5E7EB;
+ margin-bottom: 6px;
+ text-align: center;
+ font-weight: 500;
+ }
+
+ .video-progress {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ }
+
+ .progress-bar {
+ height: 4px;
+ background: rgba(255, 255, 255, 0.2);
+ border-radius: 2px;
+ overflow: hidden;
+ }
+
+ .progress-fill {
+ height: 100%;
+ background: linear-gradient(90deg, #8B5CF6, #EC4899);
+ width: 0%;
+ transition: width 0.1s ease;
+ }
+
+ .video-time {
+ font-size: 0.7rem;
+ color: #9CA3AF;
+ text-align: center;
+ }
@@ -611,11 +820,59 @@
-
-
- Next Video
- Opacity
- Play/Pause
+
+
@@ -1051,7 +1308,16 @@
video.onloadeddata = () => {
console.log('๐ฌ Video data loaded');
- document.getElementById('videoControlsOverlay').style.display = 'block';
+ setupVideoControlListeners(); // Initialize control functionality
+ };
+
+ video.onloadedmetadata = () => {
+ console.log('๐ฌ Video metadata loaded');
+ // Update video info once metadata is available
+ setTimeout(() => {
+ updateVideoInfo();
+ updateVideoProgress();
+ }, 100);
};
video.onerror = (e) => {
@@ -1077,6 +1343,12 @@
if (video) {
video.src = `file://${nextVideo.fullPath}`;
console.log(`๐ฌ Switched to: ${nextVideo.name}`);
+
+ // Update video info for the new video
+ video.addEventListener('loadedmetadata', function() {
+ updateVideoInfo();
+ updateVideoProgress();
+ }, { once: true });
}
}
@@ -1107,6 +1379,214 @@
}
}
+ // Toggle Video Controls Panel
+ function toggleVideoControls() {
+ const content = document.getElementById('video-control-content');
+ const toggle = document.getElementById('video-control-toggle');
+
+ if (content.classList.contains('collapsed')) {
+ content.classList.remove('collapsed');
+ toggle.classList.remove('collapsed');
+ toggle.textContent = 'โผ';
+ } else {
+ content.classList.add('collapsed');
+ toggle.classList.add('collapsed');
+ toggle.textContent = 'โถ';
+ }
+ }
+
+ // Setup Complete Video Control System (from Quick Play)
+ function setupVideoControlListeners() {
+ const video = document.getElementById('backgroundVideo');
+ if (!video) {
+ console.log('โ ๏ธ Background video element not found during control setup');
+ return;
+ }
+
+ console.log('๐ฎ Setting up video control listeners...');
+
+ // Play/Pause control
+ const playPauseBtn = document.getElementById('video-play-pause');
+ if (playPauseBtn) {
+ playPauseBtn.addEventListener('click', async () => {
+ const currentVideo = document.getElementById('backgroundVideo');
+ if (!currentVideo) {
+ console.log('No video element found');
+ return;
+ }
+
+ try {
+ if (currentVideo.paused) {
+ await currentVideo.play();
+ playPauseBtn.textContent = 'โธ๏ธ';
+ playPauseBtn.title = 'Pause';
+ console.log('โถ๏ธ Video resumed');
+ } else {
+ currentVideo.pause();
+ playPauseBtn.textContent = 'โถ๏ธ';
+ playPauseBtn.title = 'Play';
+ console.log('โธ๏ธ Video paused');
+ }
+ } catch (error) {
+ console.error('Video playback error:', error);
+ }
+ });
+ }
+
+ // Rewind 10 seconds
+ const rewindBtn = document.getElementById('video-rewind');
+ if (rewindBtn) {
+ rewindBtn.addEventListener('click', () => {
+ const currentVideo = document.getElementById('backgroundVideo');
+ if (currentVideo && currentVideo.duration && isFinite(currentVideo.duration)) {
+ currentVideo.currentTime = Math.max(0, currentVideo.currentTime - 10);
+ console.log('โช Rewound 10 seconds');
+ } else {
+ console.log('Cannot rewind: video not ready');
+ }
+ });
+ }
+
+ // Forward 10 seconds
+ const forwardBtn = document.getElementById('video-forward');
+ if (forwardBtn) {
+ forwardBtn.addEventListener('click', () => {
+ const currentVideo = document.getElementById('backgroundVideo');
+ if (currentVideo && currentVideo.duration && isFinite(currentVideo.duration)) {
+ currentVideo.currentTime = Math.min(currentVideo.duration, currentVideo.currentTime + 10);
+ console.log('โฉ Fast forwarded 10 seconds');
+ } else {
+ console.log('Cannot fast forward: video not ready');
+ }
+ });
+ }
+
+ // Skip video
+ const skipBtn = document.getElementById('video-skip');
+ if (skipBtn) {
+ skipBtn.addEventListener('click', () => {
+ skipToNextVideo();
+ });
+ }
+
+ // Volume control
+ const volumeSlider = document.getElementById('video-volume');
+ const volumeDisplay = document.getElementById('video-volume-display');
+ if (volumeSlider && volumeDisplay) {
+ volumeSlider.addEventListener('input', (e) => {
+ const currentVideo = document.getElementById('backgroundVideo');
+ if (currentVideo) {
+ const volume = e.target.value / 100;
+ currentVideo.volume = volume;
+ volumeDisplay.textContent = e.target.value + '%';
+ console.log(`๐ Volume set to ${e.target.value}% (${volume})`);
+
+ // Auto-mute when volume is 0
+ if (volume === 0) {
+ currentVideo.muted = true;
+ } else if (currentVideo.muted && volume > 0) {
+ currentVideo.muted = false;
+ }
+ } else {
+ console.warn('โ ๏ธ No background video element found for volume control');
+ }
+ });
+
+ // Set initial volume when video loads
+ const initializeVolume = () => {
+ const currentVideo = document.getElementById('backgroundVideo');
+ if (currentVideo) {
+ currentVideo.volume = volumeSlider.value / 100;
+ volumeDisplay.textContent = volumeSlider.value + '%';
+ console.log(`๐ Initial volume set to ${volumeSlider.value}%`);
+ }
+ };
+
+ // Try to set initial volume now and also when video loads
+ initializeVolume();
+
+ // Also set up a listener for when new videos are loaded
+ document.addEventListener('videoLoaded', initializeVolume);
+ }
+
+ // Playlist selection
+ const playlistSelect = document.getElementById('video-playlist-select');
+ if (playlistSelect) {
+ playlistSelect.addEventListener('change', (e) => {
+ const selectedPlaylist = e.target.value;
+ console.log('๐ต Playlist changed to:', selectedPlaylist);
+ // For now, just load a random video from current library
+ skipToNextVideo();
+ });
+ }
+
+ // Video progress and time updates
+ video.addEventListener('timeupdate', updateVideoProgress);
+ video.addEventListener('loadedmetadata', updateVideoInfo);
+ video.addEventListener('play', () => {
+ const playPauseBtn = document.getElementById('video-play-pause');
+ if (playPauseBtn) {
+ playPauseBtn.textContent = 'โธ๏ธ';
+ playPauseBtn.title = 'Pause';
+ }
+ });
+ video.addEventListener('pause', () => {
+ const playPauseBtn = document.getElementById('video-play-pause');
+ if (playPauseBtn) {
+ playPauseBtn.textContent = 'โถ๏ธ';
+ playPauseBtn.title = 'Play';
+ }
+ });
+
+ // Initial updates
+ setTimeout(() => {
+ updateVideoInfo();
+ updateVideoProgress();
+ }, 100);
+
+ console.log('โ
Video control listeners set up successfully');
+ }
+
+ function updateVideoProgress() {
+ const video = document.getElementById('backgroundVideo');
+ const progressFill = document.getElementById('progress-fill');
+ const videoTime = document.getElementById('video-time');
+
+ if (video && progressFill && videoTime && video.duration && isFinite(video.duration)) {
+ const progress = (video.currentTime / video.duration) * 100;
+ progressFill.style.width = isNaN(progress) ? '0%' : progress + '%';
+
+ const currentMinutes = Math.floor(video.currentTime / 60);
+ const currentSeconds = Math.floor(video.currentTime % 60);
+ const durationMinutes = Math.floor(video.duration / 60);
+ const durationSeconds = Math.floor(video.duration % 60);
+
+ videoTime.textContent = `${currentMinutes.toString().padStart(2, '0')}:${currentSeconds.toString().padStart(2, '0')} / ${durationMinutes.toString().padStart(2, '0')}:${durationSeconds.toString().padStart(2, '0')}`;
+ } else if (videoTime) {
+ videoTime.textContent = '00:00 / 00:00';
+ }
+ }
+
+ function updateVideoInfo() {
+ const video = document.getElementById('backgroundVideo');
+ const videoName = document.getElementById('current-video-name');
+
+ if (video && videoName) {
+ const videoPath = video.src || (video.querySelector('source') && video.querySelector('source').src);
+ if (videoPath) {
+ const fileName = videoPath.split('/').pop().split('\\').pop().split('.')[0];
+ const formattedName = fileName.replace(/[-_]/g, ' ');
+ // Capitalize each word
+ const displayName = formattedName.split(' ').map(word =>
+ word.charAt(0).toUpperCase() + word.slice(1)
+ ).join(' ');
+ videoName.textContent = displayName;
+ } else {
+ videoName.textContent = 'No video loaded';
+ }
+ }
+ }
+
// Training Mode Selection
function setupTrainingModeSelection() {
const container = document.getElementById('trainingModeSelection');