import { WindowManager } from './window_manager.js'; import { Styles, createElement } from '../ui_styles.js'; export const ModelOverlay = { interval: null, open() { const { win, content } = WindowManager.create('window-model', '🧠 Model Visualization', { x: 260, y: 340, width: 300, height: 400 }); this.update(content); if (this.interval) clearInterval(this.interval); this.interval = setInterval(() => this.update(content), 1000); // 1s refresh // Cleanup on close (hacky but works for now if window maps to ID) const closeBtn = win.querySelector('button'); // THe X button if (closeBtn) { const oldClick = closeBtn.onclick; closeBtn.onclick = () => { if (this.interval) clearInterval(this.interval); if (oldClick) oldClick(); } } }, update(container) { if (!container) container = document.getElementById('window-model-content'); if (!container) { if (this.interval) clearInterval(this.interval); return; } const MB = window.MagicBot; if (!MB || !MB.state || !MB.state.garden || !MB.state.garden.tileObjects) { container.innerHTML = '
No Garden Data
'; return; } container.innerHTML = ''; const list = createElement('div', 'display: flex; flex-direction: column; gap: 4px; font-size: 10px;'); // Header Info const header = createElement('div', 'padding: 5px; background: rgba(0,0,0,0.2); margin-bottom: 5px; border-radius: 4px;'); const probs = MB.automation && MB.automation.weatherTracker ? MB.automation.weatherTracker.probabilities : null; const rainProb = probs ? (probs.P_Next_Rain_Thunderstorm * 100).toFixed(0) : '?'; const frostProb = probs ? (probs.P_Next_Frost * 100).toFixed(0) : '?'; const nextEventHrs = probs ? probs.Time_Until_Next_Event_Hrs.toFixed(2) : '?'; const tracker = MB.automation ? MB.automation.weatherTracker : null; const currentEvent = tracker ? tracker.currentEvent : 'None'; header.innerHTML = `
Weather: ${currentEvent || 'Clear'}
Next Event: ${nextEventHrs} hrs (Rain: ${rainProb}%, Frost: ${frostProb}%)
Smart Harvest: ${MB.automation && MB.automation.smartHarvest ? 'ON' : 'OFF'}
`; list.appendChild(header); const garden = MB.state.garden; const tiles = garden ? garden.tileObjects : {}; const activeCrops = []; if (tiles) { Object.keys(tiles).forEach(key => { const tile = tiles[key]; if (tile.slots) { tile.slots.forEach((slot, idx) => { activeCrops.push({ id: key, idx: idx, name: slot.species || tile.species || 'Unknown', endTime: slot.endTime, startTime: slot.startTime, mutations: slot.mutations || [] }); }); } }); } if (activeCrops.length === 0) { container.innerHTML += '
No Active Crops Found
'; container.appendChild(list); return; } // Limit to first 50 to prevent lag if huge farm activeCrops.slice(0, 50).forEach(crop => { const row = createElement('div', 'background: rgba(255,255,255,0.05); padding: 5px; border-radius: 4px; display: flex; flex-direction: column; gap: 2px;'); const now = Date.now(); const isReady = now >= crop.endTime; const timeLeft = Math.max(0, (crop.endTime - now) / 60000).toFixed(1); // Minutes let statusColor = '#aaa'; let statusText = `${timeLeft} min`; if (isReady) { const hasMutation = crop.mutations && crop.mutations.length > 0; if (hasMutation) { statusText = `Ready (${crop.mutations.join(', ')})`; statusColor = '#bada55'; } else { statusText = 'Ready'; statusColor = '#fff'; } } row.innerHTML = `
${crop.name} #${crop.id} ${statusText}
`; list.appendChild(row); }); container.appendChild(list); } };