Drawaria Interactive Tools Suit💻

A suite of interactive tools for Drawaria.online with a draggable floating menu.

// ==UserScript==
// @name         Drawaria Interactive Tools Suit💻
// @namespace    http://tampermonkey.net/
// @version      1.1.2
// @description  A suite of interactive tools for Drawaria.online with a draggable floating menu.
// @author       YouTubeDrawaria
// @match        https://drawaria.online/*
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-idle
// @license     MIT
// @icon        https://www.google.com/s2/favicons?sz=64&domain=drawaria.online
// ==/UserScript==

(function() {
    'use strict';

    // --- Core Variables and State ---
    let _drawariaCanvas = null;
    let _drawariaCtx = null;
    let _isReady = false;
    let _animationFrameId = null; // Usar requestAnimationFrame para un renderizado más suave
    let _drawariaSocket = null; // Para enviar comandos al servidor

    let _isPhoneActive = false;
    let _currentPhoneState = 'home';
    let _lastPhoneButtons = [];
    let _phoneCalcInput = "";

    let _isGameConsoleActive = false;
    let _lastGameConsoleButtons = [];

    let _isComputerActive = false;
    let _computerOutput = [];
    let _lastComputerButtons = [];

    let _isTabletActive = false;
    let _currentTabletState = 'home';
    let _lastTabletButtons = [];

    let _isShoppingMallActive = false;
    let _currentShoppingMallState = 'shop';
    let _lastShoppingMallButtons = [];
    const _shoppingMallProducts = [
        { id: "apple", name: "a p p l e", icon: "a", price: 5, color: "#df3535" },
        { id: "ball", name: "b a l l", icon: "b", price: 7, color: "#2277f3" },
        { id: "coin", name: "c o i n", icon: "3", price: 3, color: "#ddbe37" },
        { id: "lamp", name: "l a m p", icon: "l", price: 11, color: "#eedd66" }
    ];

    let _isHotelActive = false;
    let _currentHotelState = 'lobby';
    let _lastHotelButtons = [];

    let _isTechCenterActive = false;
    let _currentTechCenterState = 'main';
    let _lastTechCenterButtons = [];
    const _techCenterProducts = [
        { id: "chip", name: "c h i p", icon: "c", price: 10, color: "#92e8a1" },
        { id: "battery", name: "b a t t", icon: "b", price: 8, color: "#d9dd27" },
        { id: "robo_arm", name: "r o b o - b r a z o", icon: "r", price: 25, color: "#808080" },
        { id: "laser", name: "l a s e r", icon: "l", price: 18, color: "#ff0000" }
    ];

    let _userCoins = 20;
    let _userInventory = [];
    const _ui = {};

    // --- Patrones de Letras y Números (Ajustados para consistencia) ---
    const _letterPaths = {
        a: [[10, 40], [20, 0], [30, 40], [25, 20], [15, 20]],
        b: [[0, 0], [0, 40], [15, 40], [20, 35], [20, 25], [15, 20], [0, 20], [15, 20], [20, 15], [20, 5], [15, 0], [0, 0]],
        c: [[30, 10], [20, 0], [10, 0], [0, 10], [0, 30], [10, 40], [20, 40], [30, 30]],
        d: [[0, 0], [0, 40], [10, 40], [30, 20], [10, 0], [0, 0]],
        e: [[30, 0], [0, 0], [0, 20], [20, 20], [0, 20], [0, 40], [30, 40]],
        f: [[20, 0], [0, 0], [0, 20], [15, 20], [0, 20], [0, 40]],
        g: [[30, 10], [20, 0], [10, 0], [0, 10], [0, 30], [10, 40], [20, 40], [30, 30], [20, 20]],
        h: [[0, 0], [0, 40], [0, 20], [20, 20], [20, 0], [20, 40]],
        i: [[10, 0], [10, 40]],
        j: [[20, 0], [20, 40], [10, 40], [0, 30]],
        k: [[0, 0], [0, 40], [0, 20], [20, 0], [0, 20], [20, 40]],
        l: [[0, 0], [0, 40], [20, 40]],
        m: [[0, 40], [0, 0], [10, 20], [20, 0], [20, 40]],
        n: [[0, 40], [0, 0], [20, 40], [20, 0]],
        o: [[10, 0], [20, 0], [30, 10], [30, 30], [20, 40], [10, 40], [0, 30], [0, 10], [10, 0]],
        p: [[0, 40], [0, 0], [10, 0], [20, 10], [10, 20], [0, 20]],
        q: [[10, 0], [20, 0], [30, 10], [30, 30], [20, 40], [10, 40], [0, 30], [0, 10], [10, 0], [20, 20], [30, 40]],
        r: [[0, 40], [0, 0], [10, 0], [20, 10], [10, 20], [0, 20], [20, 40]],
        s: [[20, 0], [10, 0], [0, 10], [20, 20], [30, 30], [20, 40], [10, 40], [0, 30]],
        t: [[10, 0], [10, 40], null, [1, 0], [20, 0]],
        u: [[0, 0], [0, 30], [10, 40], [20, 40], [30, 30], [30, 0]],
        v: [[0, 0], [15, 40], [30, 0]],
        w: [[0, 0], [0, 40], [10, 20], [20, 40], [30, 0]],
        x: [[0, 0], [30, 40], [15, 20], [0, 40], [30, 0]],
        y: [[0, 0], [15, 20], [30, 0], [15, 20], [15, 40]],
        z: [[0, 0], [30, 0], [0, 40], [30, 40]],
        '.': [[7.5, 35], [9, 36]],
        '!': [[15, 0], [15, 30], null, [15, 35], [15, 40]],
        '@': [[20, 10], [10, 0], [0, 10], [0, 30], [10, 40], [20, 40], [30, 30], [30, 20], [15, 20]],
        '#': [[5, 0], [5, 40], null, [25, 0], [25, 40], null, [0, 10], [30, 10], null, [0, 30], [30, 30]],
        '$': [[20, 0], [10, 0], [0, 10], [10, 20], [20, 20], [30, 30], [20, 40], [10, 40], [15, 0], [15, 40]],
        '%': [[0, 30], [30, 0], null, [5, 10], [10, 5], null, [20, 35], [25, 30]],
        '^': [[0, 20], [15, 0], [30, 20]],
        '?': [[0, 10], [10, 0], [20, 0], [30, 10], [15, 20], [15, 30], null, [15, 35], [15, 40]],
        '+': [[15, 0], [15, 40], null, [0, 20], [30, 20]],
        '-': [[0, 20], [30, 20]],
        '*': [[15, 0], [15, 40], null, [0, 10], [30, 30], null, [0, 30], [30, 10]],
        '/': [[0, 40], [30, 0]],
        '(': [[15, 0], [0, 0], [0, 40], [15, 40]],
        ')': [[15, 0], [30, 0], [30, 40], [15, 40]],
        ':': [[15, 10], [16, 11], null, [15, 30], [16, 31]],
        '_': [[0, 40], [30, 40]],
        '=': [[0, 15], [30, 15], null, [0, 25], [30, 25]],
        '<': [[30, 10], [0, 20], [30, 30]],
        '>': [[0, 10], [30, 20], [0, 30]],
        ',': [[10, 30], [10, 35], [5, 40]],
        "'": [[15, 0], [20, 5], [15, 10]]
    };

    const _numberPaths = {
        0: [[10, 0], [20, 0], [30, 10], [30, 30], [20, 40], [10, 40], [0, 30], [0, 10], [10, 0]],
        1: [[15, 0], [15, 40], null, [15, 0], [10, 10], null, [10, 40], [20, 40]],
        2: [[0, 10], [10, 0], [20, 0], [30, 10], [0, 40], [30, 40]],
        3: [[0, 10], [10, 0], [20, 0], [30, 10], [20, 20], [30, 30], [20, 40], [10, 40], [0, 30]],
        4: [[20, 0], [20, 40], null, [0, 20], [25, 20], null, [0, 20], [20, 0]],
        5: [[30, 0], [0, 0], [0, 20], [20, 20], [30, 30], [20, 40], [10, 40], [0, 30]],
        6: [[30, 10], [20, 0], [10, 0], [0, 10], [0, 30], [10, 40], [20, 40], [30, 30], [20, 20], [10, 20], [0, 20], [0, 10]],
        7: [[0, 0], [30, 0], [15, 40]],
        8: [[15, 0], [25, 10], [15, 20], [5, 10], [15, 0], null, [15, 20], [25, 30], [15, 40], [5, 30], [15, 20]],
        9: [[5, 35], [15, 40], [25, 30], [30, 10], [20, 0], [10, 0], [0, 10], [5, 20], [15, 20], [25, 20], [27.5, 20]]
    };

    // --- Utility Functions (Adaptadas de la tienda) ---

    function getGameSocket() {
        if (_drawariaSocket) return _drawariaSocket;

        if (window.socket) {
            _drawariaSocket = window.socket;
        } else if (window.WebSocket && window.WebSocket.prototype) {
            const origSend = WebSocket.prototype.send;
            WebSocket.prototype.send = function(...args) {
                if (this.url && this.url.includes('drawaria') && !_drawariaSocket) {
                    _drawariaSocket = this;
                }
                return origSend.apply(this, args);
            };
        }
        return _drawariaSocket;
    }

    function saveState() {
        GM_setValue('userCoins', _userCoins);
        GM_setValue('userInventory', JSON.stringify(_userInventory));
    }

    function loadState() {
        _userCoins = GM_getValue('userCoins', 20);
        _userInventory = JSON.parse(GM_getValue('userInventory', '[]'));
    }

    function createDraggableMenu() {
        GM_addStyle(`
            #drawaria-tools-menu {
                position: fixed;
                top: 20px;
                left: 20px;
                width: 200px;
                background: #2b2b2b;
                border: 1px solid #555;
                border-radius: 8px;
                box-shadow: 0 4px 8px rgba(0,0,0,0.5);
                z-index: 9999;
                font-family: Arial, sans-serif;
                color: #f0f0f0;
                resize: both;
                overflow: auto;
            }
            #drawaria-tools-menu-header {
                cursor: move;
                background: #3c3c3c;
                padding: 10px;
                border-top-left-radius: 8px;
                border-top-right-radius: 8px;
                text-align: center;
                font-weight: bold;
                border-bottom: 1px solid #555;
            }
            #drawaria-tools-menu-content {
                padding: 10px;
            }
            .tool-button {
                width: 100%;
                padding: 8px;
                margin-bottom: 5px;
                background: #444;
                color: #fff;
                border: 1px solid #555;
                border-radius: 4px;
                cursor: pointer;
            }
            .tool-button:hover {
                background: #555;
            }
            .tool-button.active {
                background: #007bff;
                border-color: #0056b3;
            }
            .module-status-indicator {
                margin-top: 10px;
                padding: 5px;
                border-radius: 4px;
                text-align: center;
            }
            .module-status-connected { background: #28a745; }
            .module-status-disconnected { background: #dc3545; }
            .module-status-stopped { background: #ffc107; }
        `);

        const menu = document.createElement('div');
        menu.id = 'drawaria-tools-menu';
        document.body.appendChild(menu);

        const header = document.createElement('div');
        header.id = 'drawaria-tools-menu-header';
        header.textContent = 'Drawaria Interactive Tools Suit';
        menu.appendChild(header);

        const content = document.createElement('div');
        content.id = 'drawaria-tools-menu-content';
        menu.appendChild(content);

        let isDragging = false;
        let startX, startY;

        header.addEventListener('mousedown', (e) => {
            isDragging = true;
            startX = e.clientX - menu.offsetLeft;
            startY = e.clientY - menu.offsetTop;
            document.addEventListener('mousemove', onMouseMove);
            document.addEventListener('mouseup', onMouseUp);
        });

        const onMouseMove = (e) => {
            if (isDragging) {
                menu.style.left = `${e.clientX - startX}px`;
                menu.style.top = `${e.clientY - startY}px`;
            }
        };

        const onMouseUp = () => {
            isDragging = false;
            document.removeEventListener('mousemove', onMouseMove);
            document.removeEventListener('mouseup', onMouseUp);
        };

        _ui.togglePhoneButton = createButton('<i class="fas fa-mobile-alt"></i> Teléfono', () => _toggleModule('phone'));
        _ui.toggleGameConsoleButton = createButton('<i class="fas fa-gamepad"></i> Consola', () => _toggleModule('game_console'));
        _ui.toggleComputerButton = createButton('<i class="fas fa-laptop"></i> Computadora', () => _toggleModule('computer'));
        _ui.toggleTabletButton = createButton('<i class="fas fa-tablet-alt"></i> Tablet', () => _toggleModule('tablet'));
        _ui.toggleShoppingMallButton = createButton('<i class="fas fa-store"></i> Centro Comercial', () => _toggleModule('shopping_mall'));
        _ui.toggleHotelButton = createButton('<i class="fas fa-hotel"></i> Hotel', () => _toggleModule('hotel'));
        _ui.toggleTechCenterButton = createButton('<i class="fas fa-microchip"></i> Centro de Tecnología', () => _toggleModule('tech_center'));
        _ui.resetDataButton = createButton('<i class="fas fa-redo-alt"></i> Resetear Datos', () => _resetAllData());
        _ui.stopAllButton = createButton('<i class="fas fa-stop-circle"></i> Detener Todo', () => _stopAllModulesAndRendering());
        _ui.statusLabel = document.createElement('div');
        _ui.statusLabel.className = 'module-status-indicator';
        _ui.statusText = document.createElement('span');
        _ui.statusLabel.appendChild(_ui.statusText);

        content.appendChild(_ui.togglePhoneButton);
        content.appendChild(_ui.toggleGameConsoleButton);
        content.appendChild(_ui.toggleComputerButton);
        content.appendChild(_ui.toggleTabletButton);
        content.appendChild(_ui.toggleShoppingMallButton);
        content.appendChild(_ui.toggleHotelButton);
        content.appendChild(_ui.toggleTechCenterButton);
        content.appendChild(document.createElement('hr'));
        content.appendChild(_ui.resetDataButton);
        content.appendChild(_ui.stopAllButton);
        content.appendChild(_ui.statusLabel);
    }

    function createButton(html, onClick) {
        const btn = document.createElement('button');
        btn.className = 'tool-button';
        btn.innerHTML = html;
        btn.addEventListener('click', onClick);
        return btn;
    }

    function _waitUntilReady() {
        return new Promise(resolve => {
            const check = () => {
                _drawariaCanvas = document.getElementById('canvas');
                if (_drawariaCanvas) {
                    _drawariaCtx = _drawariaCanvas.getContext('2d');
                }
                getGameSocket(); // Asegura que _drawariaSocket se inicialice
                if (_drawariaCanvas && _drawariaCtx && _drawariaSocket) {
                    resolve();
                } else {
                    setTimeout(check, 250);
                }
            };
            check();
        });
    }

    function _getMouseCanvasCoords(e) {
        if (!_drawariaCanvas) return { x: 0, y: 0 };
        const rect = _drawariaCanvas.getBoundingClientRect();
        return {
            x: (e.clientX - rect.left) * (_drawariaCanvas.width / rect.width),
            y: (e.clientY - rect.top) * (_drawariaCanvas.height / rect.height)
        };
    }

    // --- Adaptado de la tienda: Funciones de Dibujo y Envío de Comandos ---
    function drawLineServerLocal(x1, y1, x2, y2, color = '#222', thickness = 3) {
        if (!_drawariaSocket || !_drawariaCanvas) return;
        const nx1 = (x1 / _drawariaCanvas.width).toFixed(4), ny1 = (y1 / _drawariaCanvas.height).toFixed(4),
              nx2 = (x2 / _drawariaCanvas.width).toFixed(4), ny2 = (y2 / _drawariaCanvas.height).toFixed(4);
        const cmd = `42["drawcmd",0,[${nx1},${ny1},${nx2},${ny2},false,${-Math.abs(thickness)},"${color}",0,0,{}]]`;
        try {
            _drawariaSocket.send(cmd);
        } catch (e) {
            console.error("Error sending draw command:", e);
        }

        _drawariaCtx.save();
        _drawariaCtx.strokeStyle = color;
        _drawariaCtx.lineWidth = thickness;
        _drawariaCtx.lineCap = 'round';
        _drawariaCtx.beginPath();
        _drawariaCtx.moveTo(x1, y1);
        _drawariaCtx.lineTo(x2, y2);
        _drawariaCtx.stroke();
        _drawariaCtx.restore();
    }

    function drawFilledRect(x, y, w, h, color = '#eee') {
        if (!_drawariaCtx) return;
        _drawariaCtx.save();
        _drawariaCtx.fillStyle = color;
        _drawariaCtx.fillRect(x, y, w, h);
        _drawariaCtx.restore();
    }

    function drawRectServerLocal(x, y, w, h, color = '#222', thickness = 3) {
        if (!_drawariaCtx) return;
        _drawariaCtx.save();
        _drawariaCtx.strokeStyle = color;
        _drawariaCtx.lineWidth = thickness;
        _drawariaCtx.strokeRect(x, y, w, h);
        _drawariaCtx.restore();
    }

     function drawLine(x1, y1, x2, y2, color, thickness) {
         drawLineServerLocal(x1, y1, x2, y2, color, thickness);
     }

    function drawLetterPathLocal(path, startX, startY, fontSize, color, thickness) {
        if (!_drawariaCtx) return;
        const scale = fontSize / 40;

        _drawariaCtx.save();
        _drawariaCtx.strokeStyle = color;
        _drawariaCtx.lineWidth = thickness;
        _drawariaCtx.lineCap = 'round';
        _drawariaCtx.lineJoin = 'round';
        _drawariaCtx.beginPath();

        let penLifted = true;
        for (let i = 0; i < path.length; i++) {
            const segment = path[i];
            if (segment === null) {
                penLifted = true;
                continue;
            }
            const [px, py] = segment;
            const currentX = startX + px * scale;
            const currentY = startY + py * scale;
            if (penLifted) {
                _drawariaCtx.moveTo(currentX, currentY);
                penLifted = false;
            } else {
                _drawariaCtx.lineTo(currentX, currentY);
            }
        }
        _drawariaCtx.stroke();
        _drawariaCtx.restore();
    }

    function _drawLocalText(str, x, y, color, thickness = 2, fontSize = 18) {
        let cx = x;
        for (const char of str) {
            const path = _letterPaths[char.toLowerCase()] || _numberPaths[char] || _letterPaths[' '];
            if (path) {
                drawLetterPathLocal(path, cx, y, fontSize, color, thickness);
            }
            cx += fontSize * 0.6;
        }
    }

    // --- Main Logic (Converted from Class Methods) ---

    function _onStartup() {
        createDraggableMenu();
        loadState();
        _waitUntilReady().then(() => {
            _isReady = true;
            _startRenderLoop();
            document.getElementById('canvas').addEventListener('click', _handleCanvasClick);
        });
    }

    // Función de bucle de renderizado usando requestAnimationFrame
    function _renderLoop() {
        if (!_isReady || !_drawariaCtx) {
            const socketStatus = getGameSocket() ? 'connected' : 'disconnected';
            _ui.statusLabel.className = `module-status-indicator module-status-${socketStatus}`;
            _ui.statusText.textContent = socketStatus.charAt(0).toUpperCase() + socketStatus.slice(1);
            _animationFrameId = requestAnimationFrame(_renderLoop); // Continuar solicitando fotogramas incluso si no se renderizan módulos
            return;
        }

        const anyModuleActive = _isPhoneActive || _isGameConsoleActive || _isComputerActive ||
            _isTabletActive || _isShoppingMallActive || _isHotelActive ||
            _isTechCenterActive;

        if (anyModuleActive) {
            // Limpiar solo si un módulo está activo para dibujar la interfaz del módulo
            _drawariaCtx.clearRect(0, 0, _drawariaCanvas.width, _drawariaCanvas.height);

            if (_isPhoneActive) _renderPhone();
            else if (_isGameConsoleActive) _renderGameConsole();
            else if (_isComputerActive) _renderComputer();
            else if (_isTabletActive) _renderTablet();
            else if (_isShoppingMallActive) _renderShoppingMall();
            else if (_isHotelActive) _renderHotel();
            else if (_isTechCenterActive) _renderTechCenter();
        } else {
            // Si ningún módulo está activo, NO limpiar el canvas.
            // Esto permite que el juego principal se dibuje sobre el canvas.
            // Nuestro script solo interviene cuando un módulo está activo.
        }

        const socketStatus = getGameSocket() ? 'connected' : 'disconnected';
        _ui.statusLabel.className = `module-status-indicator module-status-${socketStatus}`;
        _ui.statusText.textContent = socketStatus.charAt(0).toUpperCase() + socketStatus.slice(1);

        _animationFrameId = requestAnimationFrame(_renderLoop); // Programar el siguiente fotograma
    }

    function _startRenderLoop() {
        if (_animationFrameId) {
            cancelAnimationFrame(_animationFrameId); // Cancelar el anterior si existe
        }
        _animationFrameId = requestAnimationFrame(_renderLoop); // Iniciar el bucle
    }

    function _handleCanvasClick(e) {
        if (!_isReady || !_drawariaCtx) return;
        const { x: cx, y: cy } = _getMouseCanvasCoords(e);

        // Delegar el manejo del clic al módulo activo
        if (_isPhoneActive) _handlePhoneClick(cx, cy);
        else if (_isGameConsoleActive) _handleGameConsoleClick(cx, cy);
        else if (_isComputerActive) _handleComputerClick(cx, cy);
        else if (_isTabletActive) _handleTabletClick(cx, cy);
        else if (_isShoppingMallActive) _handleShoppingMallClick(cx, cy);
        else if (_isHotelActive) _handleHotelClick(cx, cy);
        else if (_isTechCenterActive) _handleTechCenterClick(cx, cy);
    }

    function _toggleModule(moduleName) {
        // Desactivar todos los módulos primero
        _isPhoneActive = false;
        _isGameConsoleActive = false;
        _isComputerActive = false;
        _isTabletActive = false;
        _isShoppingMallActive = false;
        _isHotelActive = false;
        _isTechCenterActive = false;

        // Remover la clase 'active' de todos los botones del menú
        document.querySelectorAll('.tool-button').forEach(btn => btn.classList.remove('active'));

        let message = `Módulo '${moduleName.replace('_', ' ')}' desactivado.`;

        switch (moduleName) {
            case 'phone':
                _isPhoneActive = true;
                _ui.togglePhoneButton.classList.add('active');
                _currentPhoneState = 'home';
                message = "Módulo 'Teléfono' activado.";
                break;
            case 'game_console':
                _isGameConsoleActive = true;
                _ui.toggleGameConsoleButton.classList.add('active');
                message = "Módulo 'Consola' activado.";
                break;
            case 'computer':
                _isComputerActive = true;
                _ui.toggleComputerButton.classList.add('active');
                message = "Módulo 'Computadora' activado.";
                break;
            case 'tablet':
                _isTabletActive = true;
                _ui.toggleTabletButton.classList.add('active');
                _currentTabletState = 'home';
                message = "Módulo 'Tablet' activado.";
                break;
            case 'shopping_mall':
                _isShoppingMallActive = true;
                _ui.toggleShoppingMallButton.classList.add('active');
                _currentShoppingMallState = 'shop';
                message = "Módulo 'Centro Comercial' activado.";
                break;
            case 'hotel':
                _isHotelActive = true;
                _ui.toggleHotelButton.classList.add('active');
                _currentHotelState = 'lobby';
                message = "Módulo 'Hotel' activado.";
                break;
            case 'tech_center':
                _isTechCenterActive = true;
                _ui.toggleTechCenterButton.classList.add('active');
                _currentTechCenterState = 'main';
                message = "Módulo 'Centro de Tecnología' activado.";
                break;
        }

        // Si el canvas está disponible, lo limpiamos solo si activamos un módulo,
        // para asegurar que el estado anterior no interfiera.
        if (_drawariaCtx && _drawariaCanvas && anyModuleActive) {
            _drawariaCtx.clearRect(0, 0, _drawariaCanvas.width, _drawariaCanvas.height);
        }
        _startRenderLoop(); // Reiniciar bucle para aplicar cambios
    }

    function _resetAllData() {
        _userCoins = 20;
        _userInventory = [];
        _phoneCalcInput = "";
        _currentPhoneState = 'home';
        _currentTabletState = 'home';
        _currentShoppingMallState = 'shop';
        _currentHotelState = 'lobby';
        _currentTechCenterState = 'main';
        _computerOutput = [];
        saveState();
        _startRenderLoop(); // Re-renderizar para mostrar el estado reseteado
        alert("Todos los datos han sido reseteados.");
    }

    function _stopAllModulesAndRendering() {
        _isPhoneActive = false;
        _isGameConsoleActive = false;
        _isComputerActive = false;
        _isTabletActive = false;
        _isShoppingMallActive = false;
        _isHotelActive = false;
        _isTechCenterActive = false;

        document.querySelectorAll('.tool-button').forEach(btn => btn.classList.remove('active'));

        if (_animationFrameId) {
            cancelAnimationFrame(_animationFrameId);
            _animationFrameId = null;
        }

        // Al detener todo, debemos asegurarnos de que el canvas se limpie para mostrar el juego de nuevo.
        if (_drawariaCtx && _drawariaCanvas) {
            _drawariaCtx.clearRect(0, 0, _drawariaCanvas.width, _drawariaCanvas.height);
        }

        const socketStatus = getGameSocket() ? 'connected' : 'disconnected';
        _ui.statusLabel.className = `module-status-indicator module-status-stopped`;
        _ui.statusText.textContent = `Detenido (${socketStatus.charAt(0).toUpperCase() + socketStatus.slice(1)})`;
    }

    // --- Helper Drawing Functions ---

    function _drawLocalLine(x1, y1, x2, y2, color = '#222', thickness = 3) {
        if (!_drawariaCtx) return;
        _drawariaCtx.save();
        _drawariaCtx.strokeStyle = color;
        _drawariaCtx.lineWidth = thickness;
        _drawariaCtx.lineCap = 'round';
        _drawariaCtx.beginPath();
        _drawariaCtx.moveTo(x1, y1);
        _drawariaCtx.lineTo(x2, y2);
        _drawariaCtx.stroke();
        _drawariaCtx.restore();
    }

     // Función genérica para dibujar texto usando los patrones definidos
     function _drawTextGeneric(str, x, y, color, thickness = 2, fontSize = 18, paths) {
         let cx = x;
         for (const char of str) {
             const path = paths[char.toLowerCase()] || paths[' '];
             if (path) {
                 drawLetterPathLocal(path, cx, y, fontSize, color, thickness);
             }
             cx += fontSize * 0.6;
         }
     }

     // Sobrescribir _drawLocalText para usar la función genérica
     function _drawLocalText(str, x, y, color, thickness = 2, fontSize = 18) {
         _drawTextGeneric(str, x, y, color, thickness, fontSize, _letterPaths);
     }

    function _drawLocalFilledRect(x, y, w, h, color = '#eee') {
        if (!_drawariaCtx) return;
        _drawariaCtx.save();
        _drawariaCtx.fillStyle = color;
        _drawariaCtx.fillRect(x, y, w, h);
        _drawariaCtx.restore();
    }

    function _drawLocalRectOutline(x, y, w, h, color = '#222', thickness = 3) {
        if (!_drawariaCtx) return;
        _drawariaCtx.save();
        _drawariaCtx.strokeStyle = color;
        _drawariaCtx.lineWidth = thickness;
        _drawariaCtx.strokeRect(x, y, w, h);
        _drawariaCtx.restore();
    }

    function _drawActionButton(x, y, w, h, text, action, buttonArray, bgColor = '#DDD', textColor = '#222', fontSize = 17, textThickness = 2, borderColor = '#222', borderWidth = 2, extraData = {}) {
        _drawLocalFilledRect(x, y, w, h, bgColor);
        _drawLocalRectOutline(x, y, w, h, borderColor, borderWidth);
        const textWidthApprox = text.length * fontSize * 0.6;
        _drawLocalText(text, x + (w - textWidthApprox) / 2, y + (h - fontSize) / 2 + 3, textColor, textThickness, fontSize);
        buttonArray.push({ x, y, w, h, action, ...extraData });
    }

     function _drawAppButton(x, y, size, action, bgColor, borderColor, iconChar, iconColor, labelText, labelColor, buttonArray) {
         _drawLocalFilledRect(x, y, size, size, bgColor);
         _drawLocalRectOutline(x, y, size, size, borderColor, 2);
         _drawLocalText(iconChar, x + size / 2 - 10, y + 8, iconColor, 2, 20);
         const labelTextWidthApprox = labelText.length * 12 * 0.6;
         _drawLocalText(labelText, x + size / 2 - (labelTextWidthApprox / 2), y + size + 5, labelColor, 1.5, 12);
         buttonArray.push({ x: x, y: y, w: size, h: size, action: action });
     }


    // --- Module Rendering and Click Handlers ---

    function _handlePhoneClick(cx, cy) {
        for (const btn of _lastPhoneButtons) {
            if (cx >= btn.x && cx <= btn.x + btn.w && cy >= btn.y && cy <= btn.y + btn.h) {
                switch (btn.action) {
                    case 'home': _currentPhoneState = 'home'; break;
                    case 'open_football': _currentPhoneState = 'football'; break;
                    case 'open_notes': _currentPhoneState = 'notes'; break;
                    case 'open_calc': _currentPhoneState = 'calc'; break;
                    case 'open_clock': _currentPhoneState = 'clock'; break;
                    case 'open_gallery': _currentPhoneState = 'gallery'; break;
                    case 'calcpress':
                        _phoneCalcInput += btn.val;
                        break;
                    case 'equals':
                        try {
                            let safeInput = _phoneCalcInput.replace(/[^0-9+\-*/.()]/g, '');
                            _phoneCalcInput = String(eval(safeInput));
                        } catch {
                            _phoneCalcInput = "ERR";
                        }
                        break;
                    case 'ce':
                        _phoneCalcInput = "";
                        break;
                }
                _renderPhone();
                return;
            }
        }
    }

    function _renderPhone() {
        if (!_drawariaCanvas) return;
        const phoneW = 220, phoneH = 420;
        const { x, y, w, h } = { x: _drawariaCanvas.width - phoneW - 32, y: _drawariaCanvas.height - phoneH - 32, w: phoneW, h: phoneH };
        _lastPhoneButtons = [];

        _drawLocalFilledRect(x, y, w, h, '#222');
        _drawLocalRectOutline(x, y, w, h, '#999', 4);
        _drawLocalFilledRect(x + 10, y + 10, w - 20, h - 20, '#000');
        _drawLocalFilledRect(x + w / 2 - 30, y + 20, 60, 10, '#444');
        _drawLocalFilledRect(x + w / 2 - 15, y + h - 30, 30, 15, '#444');

        switch (_currentPhoneState) {
            case 'home': _renderPhoneHome(x + 15, y + 45, w - 30, h - 80); break;
            case 'football': _renderPhoneFootballApp(x + 15, y + 45, w - 30, h - 80); break;
            case 'notes': _renderPhoneNotesApp(x + 15, y + 45, w - 30, h - 80); break;
            case 'calc': _renderPhoneCalcApp(x + 15, y + 45, w - 30, h - 80); break;
            case 'clock': _renderPhoneClockApp(x + 15, y + 45, w - 30, h - 80); break;
            case 'gallery': _renderPhoneGalleryApp(x + 15, y + 45, w - 30, h - 80); break;
        }

        if (_currentPhoneState !== 'home') {
            const btnX = x + 15 + (w - 30) / 2 - 40, btnY = y + 45 + (h - 80) - 40, btnW = 80, btnH = 30;
            _drawActionButton(btnX, btnY, btnW, btnH, "v o l v e r", 'home', _lastPhoneButtons, '#DDD', '#555', 14);
        }
    }

    function _renderPhoneHome(x, y, w, h) {
        _drawLocalText("a n d r o i d", x + 10, y + 10, '#17A', 3, 17);
        _drawAppButton(x + 10, y + 40, 45, 'open_football', '#FAFAFF', '#222', 'f', '#173', 'f u t b o l', '#222', _lastPhoneButtons);
        _drawAppButton(x + 70, y + 40, 45, 'open_notes', '#FFFDE9', '#222', 'n', '#962', 'n o t e s', '#222', _lastPhoneButtons);
        _drawAppButton(x + 130, y + 40, 45, 'open_calc', '#EAEEFF', '#222', 'c', '#246', 'c a l c', '#222', _lastPhoneButtons);
        _drawAppButton(x + 10, y + 120, 45, 'open_clock', '#F6FFEA', '#222', 'r', '#184', 'r e l o j', '#222', _lastPhoneButtons);
        _drawAppButton(x + 70, y + 120, 45, 'open_gallery', '#FAEEFF', '#222', 'g', '#71a', 'g a l e r', '#222', _lastPhoneButtons);
    }

    function _renderPhoneFootballApp(x, y, w, h) {
        _drawLocalText("f u t b o l", x + 20, y + 10, '#173', 3, 18);
        _drawLocalFilledRect(x + 20, y + 50, w - 40, h - 100, '#8BC34A');
        _drawLocalRectOutline(x + 20, y + 50, w - 40, h - 100, '#222', 2);
        _drawLocalLine(x + w / 2, y + 50, x + w / 2, y + h - 50, '#FFF', 1);
        _drawLocalText("b o l a", x + w / 2 - 25, y + h / 2 + 10, '#FFF', 2, 18);
    }

    function _renderPhoneNotesApp(x, y, w, h) {
        _drawLocalText("n o t a s", x + 20, y + 10, '#962', 3, 18);
        _drawLocalFilledRect(x + 10, y + 40, w - 20, h - 80, '#fffbe0');
        _drawLocalRectOutline(x + 10, y + 40, w - 20, h - 80, '#555', 2);
        for (let i = 0; i < 5; i++) {
            _drawLocalLine(x + 15, y + 50 + i * 20, x + w - 15, y + 50 + i * 20, '#99F', 1);
        }
        _drawLocalText("t o m a  n o t a !", x + 20, y + 60, "#333", 2, 15);
    }

    function _renderPhoneCalcApp(x, y, w, h) {
        _drawLocalText("c a l c", x + 20, y + 10, '#246', 3, 18);
        _drawLocalFilledRect(x + 10, y + 40, w - 20, 40, '#f4f7fd');
        _drawLocalRectOutline(x + 10, y + 40, w - 20, 40, '#222', 2);
        _drawLocalText(_phoneCalcInput || "0", x + 15, y + 50, '#246', 2, 18);
        const bw = 40, bh = 30, pad = 5;
        const layout = [
            ['7', '8', '9', '+'],
            ['4', '5', '6', '-'],
            ['1', '2', '3', '*'],
            ['ce', '0', '=', '/']
        ];
        let startY = y + 90;
        for (let row = 0; row < layout.length; row++) {
            let startX = x + 15;
            for (let col = 0; col < layout[row].length; col++) {
                const char = layout[row][col];
                const btnAction = (char === 'ce' || char === '=') ? char : 'calcpress';
                const extra = (btnAction === 'calcpress') ? { val: char } : {};
                _drawActionButton(startX + col * (bw + pad), startY + row * (bh + pad), bw, bh, char, btnAction, _lastPhoneButtons, '#EEE', '#222', 15, 2, '#999', 1, extra);
            }
        }
    }

    function _renderPhoneClockApp(x, y, w, h) {
        _drawLocalText("r e l o j", x + 20, y + 10, '#184', 3, 18);
        const now = new Date();
        const timeStr = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;
        const dateStr = `${String(now.getDate()).padStart(2, '0')}/${String(now.getMonth() + 1).padStart(2, '0')}/${now.getFullYear()}`;
        _drawLocalText(timeStr, x + 20, y + 70, '#222', 3, 25);
        _drawLocalText(dateStr, x + 20, y + 110, '#555', 2, 15);
    }

    function _renderPhoneGalleryApp(x, y, w, h) {
        _drawLocalText("g a l e r", x + 20, y + 10, '#71a', 3, 18);
        _drawLocalFilledRect(x + 10, y + 40, w - 20, h - 80, '#DDD');
        _drawLocalRectOutline(x + 10, y + 40, w - 20, h - 80, '#555', 2);
        _drawLocalText("n o   f o t o s", x + 20, y + 50, '#555', 2, 15);
    }

    function _handleGameConsoleClick(cx, cy) {
        for (const btn of _lastGameConsoleButtons) {
            if (cx >= btn.x && cx <= btn.x + btn.w && cy >= btn.y && cy <= btn.y + btn.h) {
                switch (btn.action) {
                    case 'dpad_up': _drawLocalText("A R R I B A", cx, cy - 20, '#0F0', 2, 12); break;
                    case 'dpad_down': _drawLocalText("A B A J O", cx, cy + 20, '#0F0', 2, 12); break;
                    case 'dpad_left': _drawLocalText("I Z Q", cx - 20, cy + 5, '#0F0', 2, 12); break;
                    case 'dpad_right': _drawLocalText("D E R", cx + 20, cy + 5, '#0F0', 2, 12); break;
                    case 'btn_a': _drawLocalText("A C T I O N", cx, cy, '#0F0', 2, 12); break;
                    case 'btn_b': _drawLocalText("C A N C E L", cx, cy, '#0F0', 2, 12); break;
                }
                _renderGameConsole();
                return;
            }
        }
    }

    function _renderGameConsole() {
        if (!_drawariaCanvas) return;
        const consoleW = 400, consoleH = 200;
        const { x, y, w, h } = { x: _drawariaCanvas.width / 2 - consoleW / 2, y: _drawariaCanvas.height / 2 - consoleH / 2, w: consoleW, h: consoleH };
        _lastGameConsoleButtons = [];

        _drawLocalFilledRect(x, y, w, h, '#444');
        _drawLocalRectOutline(x, y, w, h, '#999', 4);
        _drawLocalFilledRect(x + 20, y + 20, w - 40, 100, '#000');
        _drawLocalRectOutline(x + 20, y + 20, w - 40, 100, '#0F0', 2);

        _drawLocalText("P O N G", x + w / 2 - 50, y + 50, '#0F0', 3, 20);
        _drawLocalText("j u g a r", x + w / 2 - 60, y + 80, '#0F0', 2, 15);
        _drawLocalText("c o n s o l a", x + w / 2 - 80, y + 140, '#CCC', 2, 18);

        const btnSize = 30, btnPad = 10;
        _drawActionButton(x + 30, y + 140, btnSize, btnSize, '▲', 'dpad_up', _lastGameConsoleButtons);
        _drawActionButton(x + 30, y + 140 + btnSize + btnPad, btnSize, btnSize, '▼', 'dpad_down', _lastGameConsoleButtons);
        _drawActionButton(x + 30 - btnSize - btnPad, y + 140 + btnSize + btnPad / 2, btnSize, btnSize, '◀', 'dpad_left', _lastGameConsoleButtons);
        _drawActionButton(x + 30 + btnSize + btnPad, y + 140 + btnSize + btnPad / 2, btnSize, btnSize, '▶', 'dpad_right', _lastGameConsoleButtons);
        _drawActionButton(x + w - 30 - btnSize, y + 140 + btnSize / 2, btnSize, btnSize, 'A', 'btn_a', _lastGameConsoleButtons);
        _drawActionButton(x + w - 30 - btnSize - 20, y + 140 + btnSize / 2 + 10, btnSize, btnSize, 'B', 'btn_b', _lastGameConsoleButtons);
    }

    function _handleComputerClick(cx, cy) {
        for (const btn of _lastComputerButtons) {
            if (cx >= btn.x && cx <= btn.x + btn.w && cy >= btn.y && cy <= btn.y + btn.h) {
                switch (btn.action) {
                    case 'power':
                        _computerOutput.push("P O W E R   O N");
                        break;
                    case 'code':
                        _computerOutput.push("P R O G R A M M I N G");
                        _computerOutput.push("C O D E   L I N E");
                        break;
                    case 'internet':
                        _computerOutput.push("I N T E R N E T");
                        _computerOutput.push("S E A R C H I N G...");
                        break;
                    case 'clear':
                        _computerOutput = [];
                        break;
                }
                if (_computerOutput.length > 5) {
                    _computerOutput.shift();
                }
                _renderComputer();
                return;
            }
        }
    }

    function _renderComputer() {
        if (!_drawariaCanvas) return;
        const compW = 450, compH = 300;
        const { x, y, w, h } = { x: 10, y: 10, w: compW, h: compH };
        _lastComputerButtons = [];

        _drawLocalFilledRect(x, y, w, h, '#333');
        _drawLocalRectOutline(x, y, w, h, '#777', 4);
        _drawLocalFilledRect(x + 20, y + 20, w - 40, h - 60, '#000');
        _drawLocalRectOutline(x + 20, y + 20, w - 40, h - 60, '#0F0', 2);

        _drawLocalText("C O M P U T A D O R A", x + w / 2 - 100, y + 10, '#EEE', 3, 18);
        let outputY = y + 30;
        _computerOutput.forEach(line => {
            _drawLocalText(line, x + 30, outputY, '#0F0', 2, 14);
            outputY += 20;
        });

        _drawActionButton(x + 20, y + h - 30, 80, 20, 'O N', 'power', _lastComputerButtons, '#28A745', '#FFF', 14);
        _drawActionButton(x + 110, y + h - 30, 80, 20, 'C O D E', 'code', _lastComputerButtons, '#007BFF', '#FFF', 14);
        _drawActionButton(x + 200, y + h - 30, 80, 20, 'I N T E R N E T', 'internet', _lastComputerButtons, '#FFC107', '#FFF', 14);
        _drawActionButton(x + w - 100, y + h - 30, 80, 20, 'C L E A R', 'clear', _lastComputerButtons, '#DC3545', '#FFF', 14);
    }

    function _handleTabletClick(cx, cy) {
        for (const btn of _lastTabletButtons) {
            if (cx >= btn.x && cx <= btn.x + btn.w && cy >= btn.y && cy <= btn.y + btn.h) {
                switch (btn.action) {
                    case 'home': _currentTabletState = 'home'; break;
                    case 'open_youtube': _currentTabletState = 'youtube'; break;
                    case 'open_maps': _currentTabletState = 'maps'; break;
                    case 'open_paint': _currentTabletState = 'paint'; break;
                }
                _renderTablet();
                return;
            }
        }
    }

    function _renderTablet() {
        if (!_drawariaCanvas) return;
        const tabletW = 500, tabletH = 350;
        const { x, y, w, h } = { x: _drawariaCanvas.width / 2 - tabletW / 2, y: _drawariaCanvas.height / 2 - tabletH / 2, w: tabletW, h: tabletH };
        _lastTabletButtons = [];

        _drawLocalFilledRect(x, y, w, h, '#222');
        _drawLocalRectOutline(x, y, w, h, '#999', 4);
        _drawLocalFilledRect(x + 10, y + 10, w - 20, h - 20, '#fff');
        _drawLocalFilledRect(x + w / 2 - 20, y + h - 25, 40, 10, '#444');

        switch (_currentTabletState) {
            case 'home': _renderTabletHome(x + 10, y + 10, w - 20, h - 20); break;
            case 'youtube': _renderTabletYouTubeApp(x + 10, y + 10, w - 20, h - 20); break;
            case 'maps': _renderTabletMapsApp(x + 10, y + 10, w - 20, h - 20); break;
            case 'paint': _renderTabletPaintApp(x + 10, y + 10, w - 20, h - 20); break;
        }

        if (_currentTabletState !== 'home') {
            const btnX = x + 10 + (w - 20) / 2 - 40, btnY = y + 10 + (h - 20) - 40, btnW = 80, btnH = 30;
            _drawActionButton(btnX, btnY, btnW, btnH, "v o l v e r", 'home', _lastTabletButtons, '#DDD', '#555', 14);
        }
    }

    function _renderTabletHome(x, y, w, h) {
        _drawLocalText("T A B L E T", x + 10, y + 10, '#369', 3, 18);
        _drawAppButton(x + 20, y + 50, 60, 'open_youtube', '#F00', '#222', 'p', '#FFF', 'y o u t u b e', '#222', _lastTabletButtons);
        _drawAppButton(x + 100, y + 50, 60, 'open_maps', '#28A745', '#222', 'm', '#FFF', 'm a p s', '#222', _lastTabletButtons);
        _drawAppButton(x + 180, y + 50, 60, 'open_paint', '#81D4FA', '#222', 'p', '#FFF', 'p i n t a r', '#222', _lastTabletButtons);
    }

    function _renderTabletYouTubeApp(x, y, w, h) {
        _drawLocalText("y o u t u b e", x + 10, y + 10, '#F00', 3, 18);
        _drawLocalFilledRect(x + 20, y + 50, w - 40, h - 100, '#000');
        _drawLocalRectOutline(x + 20, y + 50, w - 40, h - 100, '#F00', 2);
        _drawLocalText("v i d e o", x + w / 2 - 50, y + h / 2 - 10, '#FFF', 2, 20);
        _drawLocalText("►", x + w / 2 - 10, y + h / 2 - 20, '#FFF', 3, 25);
    }

    function _renderTabletMapsApp(x, y, w, h) {
        _drawLocalText("m a p s", x + 10, y + 10, '#28A745', 3, 18);
        _drawLocalFilledRect(x + 20, y + 50, w - 40, h - 100, '#8BC34A');
        _drawLocalRectOutline(x + 20, y + 50, w - 40, h - 100, '#222', 2);
        _drawLocalText("m a p a", x + w / 2 - 40, y + h / 2 - 10, '#222', 2, 20);
        _drawLocalText("📍", x + w / 2 - 10, y + h / 2 - 20, '#F00', 3, 25);
    }

    function _renderTabletPaintApp(x, y, w, h) {
        _drawLocalText("p i n t a r", x + 10, y + 10, '#81D4FA', 3, 18);
        _drawLocalFilledRect(x + 20, y + 50, w - 40, h - 100, '#FFF');
        _drawLocalRectOutline(x + 20, y + 50, w - 40, h - 100, '#222', 2);
        _drawLocalText("l a p i z", x + 20, y + 60, '#222', 2, 15);
        _drawLocalText("🎨", x + 20, y + 75, '#222', 3, 25);
    }

    function _handleShoppingMallClick(cx, cy) {
        for (const btn of _lastShoppingMallButtons) {
            if (cx >= btn.x && cx <= btn.x + btn.w && cy >= btn.y && cy <= btn.y + btn.h) {
                switch (btn.action) {
                    case 'shop':
                        _currentShoppingMallState = 'shop';
                        break;
                    case 'inventory':
                        _currentShoppingMallState = 'inventory';
                        break;
                    case 'buy':
                        const prod = _shoppingMallProducts.find(p => p.id === btn.id);
                        if (prod && _userCoins >= prod.price) {
                            _userCoins -= prod.price;
                            _userInventory.push(prod.id);
                            saveState();
                        } else if (prod) {
                            alert("¡No tienes suficientes coins!");
                        }
                        break;
                }
                _renderShoppingMall();
                return;
            }
        }
    }

    function _renderShoppingMall() {
        if (!_drawariaCanvas) return;
        const shopW = 500, shopH = 300;
        const { x, y, w, h } = { x: _drawariaCanvas.width / 2 - shopW / 2, y: _drawariaCanvas.height - shopH - 32, w: shopW, h: shopH };
        _lastShoppingMallButtons = [];

        _drawLocalFilledRect(x, y, w, h, '#f4f4f4');
        _drawLocalRectOutline(x, y, w, h, '#222', 4);
        _drawLocalText("c e n t r o   c o m e r c i a l", x + 10, y + 10, '#222', 3, 18);
        _drawLocalText(`c o i n s: ${_userCoins}`, x + 10, y + 30, '#555', 2, 15);
        _drawActionButton(x + 10, y + 45, 100, 30, 't i e n d a', 'shop', _lastShoppingMallButtons);
        _drawActionButton(x + 120, y + 45, 100, 30, 'i n v e n t', 'inventory', _lastShoppingMallButtons);

        switch (_currentShoppingMallState) {
            case 'shop': _renderShopItems(x, y, w, h); break;
            case 'inventory': _renderInventory(x, y, w, h); break;
        }
    }

    function _renderShopItems(x, y, w, h) {
        const itemX = x + 20, itemY = y + 80, itemW = 100, itemH = 60, pad = 10;
        let currentY = itemY;
        _shoppingMallProducts.forEach(item => {
            _drawLocalFilledRect(itemX, currentY, itemW, itemH, '#EEE');
            _drawLocalRectOutline(itemX, currentY, itemW, itemH, '#555', 2);
            _drawLocalText(item.name, itemX + 5, currentY + 5, '#222', 2, 14);
            _drawLocalText(`$${item.price}`, itemX + 5, currentY + 25, '#444', 2, 12);
            const canAfford = _userCoins >= item.price;
            _drawActionButton(itemX + 60, currentY + 30, 35, 20, 'c o m p', 'buy', _lastShoppingMallButtons, canAfford ? '#4a90e2' : '#999', '#FFF', 12, 1, '#222', 1, { id: item.id });
            currentY += itemH + pad;
        });
    }

    function _renderInventory(x, y, w, h) {
        _drawLocalText("i n v e n t a r i o", x + 20, y + 80, '#222', 3, 16);
        let invY = y + 100;
        if (_userInventory.length === 0) {
            _drawLocalText("v a c i o", x + 30, invY, '#555', 2, 14);
        } else {
            const counts = _userInventory.reduce((acc, curr) => {
                acc[curr] = (acc[curr] || 0) + 1;
                return acc;
            }, {});
            for (const itemId in counts) {
                 const product = _shoppingMallProducts.find(p => p.id === itemId);
                 if (product) {
                    _drawLocalText(`${product.name} x ${counts[itemId]}`, x + 30, invY, '#222', 2, 14);
                    invY += 20;
                 }
            }
        }
    }

    function _handleHotelClick(cx, cy) {
        for (const btn of _lastHotelButtons) {
            if (cx >= btn.x && cx <= btn.x + btn.w && cy >= btn.y && cy <= btn.y + btn.h) {
                switch (btn.action) {
                    case 'lobby':
                        _currentHotelState = 'lobby';
                        break;
                    case 'rent':
                        if (_userCoins >= 10) {
                            _userCoins -= 10;
                            _currentHotelState = 'room';
                            saveState();
                        } else {
                            alert("¡No tienes suficientes coins para alquilar!");
                        }
                        break;
                    case 'check_out':
                        _currentHotelState = 'lobby';
                        break;
                }
                _renderHotel();
                return;
            }
        }
    }

    function _renderHotel() {
        if (!_drawariaCanvas) return;
        const hotelW = 400, hotelH = 250;
        const { x, y, w, h } = { x: 30, y: 30, w: hotelW, h: hotelH };
        _lastHotelButtons = [];

        _drawLocalFilledRect(x, y, w, h, '#E0F7FA');
        _drawLocalRectOutline(x, y, w, h, '#222', 4);
        _drawLocalText("h o t e l", x + 10, y + 10, '#369', 3, 18);
        _drawLocalText(`c o i n s: ${_userCoins}`, x + 10, y + 30, '#555', 2, 15);

        switch (_currentHotelState) {
            case 'lobby': _renderHotelLobby(x, y, w, h); break;
            case 'room': _renderHotelRoom(x, y, w, h); break;
        }
    }

    function _renderHotelLobby(x, y, w, h) {
        _drawLocalText("b i e n v e n i d o", x + w / 2 - 60, y + 60, '#369', 3, 18);
        _drawLocalText("r e n t a   u n a   h a b i t", x + 20, y + 100, '#555', 2, 14);
        _drawLocalText("c o s t o: 10 c", x + 20, y + 120, '#555', 2, 14);
        const canRent = _userCoins >= 10;
        _drawActionButton(x + 20, y + h - 50, 150, 30, "a l q u i l a r", 'rent', _lastHotelButtons, canRent ? '#4a90e2' : '#999', '#FFF', 14, 1, '#222', 1);
    }

    function _renderHotelRoom(x, y, w, h) {
        _drawLocalText("t u   h a b i t a c i o n", x + w / 2 - 80, y + 60, '#369', 3, 18);
        _drawLocalText("h o r a   d e   r e l a j", x + 20, y + 100, '#555', 2, 14);
        _drawActionButton(x + 20, y + h - 50, 150, 30, "d e s a l o j a r", 'check_out', _lastHotelButtons, '#DC3545', '#FFF', 14, 1, '#222', 1);
    }

    function _handleTechCenterClick(cx, cy) {
        for (const btn of _lastTechCenterButtons) {
            if (cx >= btn.x && cx <= btn.x + btn.w && cy >= btn.y && cy <= btn.y + btn.h) {
                switch (btn.action) {
                    case 'main':
                        _currentTechCenterState = 'main';
                        break;
                    case 'buy_tech':
                        const prod = _techCenterProducts.find(p => p.id === btn.id);
                        if (prod && _userCoins >= prod.price) {
                            _userCoins -= prod.price;
                            _userInventory.push(prod.id);
                            saveState();
                        } else if (prod) {
                             alert("¡No tienes suficientes coins!");
                        }
                        break;
                }
                _renderTechCenter();
                return;
            }
        }
    }

    function _renderTechCenter() {
        if (!_drawariaCanvas) return;
        const techW = 500, techH = 300;
        const { x, y, w, h } = { x: _drawariaCanvas.width / 2 - techW / 2, y: _drawariaCanvas.height / 2 - techH / 2, w: techW, h: techH };
        _lastTechCenterButtons = [];

        _drawLocalFilledRect(x, y, w, h, '#212121');
        _drawLocalRectOutline(x, y, w, h, '#9E9E9E', 4);
        _drawLocalText("t e c n o l o g i a", x + 10, y + 10, '#E0F7FA', 3, 18);
        _drawLocalText(`c o i n s: ${_userCoins}`, x + 10, y + 30, '#BDBDBD', 2, 15);
        _drawActionButton(x + 10, y + 45, 100, 30, 'm e n u', 'main', _lastTechCenterButtons);

        switch (_currentTechCenterState) {
            case 'main': _renderTechItems(x, y, w, h); break;
        }
    }

    function _renderTechItems(x, y, w, h) {
        const itemX = x + 20, itemY = y + 80, itemW = 100, itemH = 60, pad = 10;
        let currentY = itemY;
        _techCenterProducts.forEach(item => {
            _drawLocalFilledRect(itemX, currentY, itemW, itemH, '#424242');
            _drawLocalRectOutline(itemX, currentY, itemW, itemH, '#757575', 2);
            _drawLocalText(item.name, itemX + 5, currentY + 5, '#E0F7FA', 2, 14);
            _drawLocalText(`$${item.price}`, itemX + 5, currentY + 25, '#BDBDBD', 2, 12);
            const canAfford = _userCoins >= item.price;
            _drawActionButton(itemX + 60, currentY + 30, 35, 20, 'c o m p', 'buy_tech', _lastTechCenterButtons, canAfford ? '#4a90e2' : '#999', '#FFF', 12, 1, '#222', 1, { id: item.id });
            currentY += itemH + pad;
        });
    }

    // --- Inicialización ---
    _onStartup();

})();