Drawaria - Custom Palettes Mod

Gestiona y guarda paletas de colores personalizadas en Drawaria.online con una interfaz siempre visible.

// ==UserScript==
// @name         Drawaria - Custom Palettes Mod
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Gestiona y guarda paletas de colores personalizadas en Drawaria.online con una interfaz siempre visible.
// @author       YouTubeDrawaria
// @match        https://drawaria.online/*
// @grant        none
// @license      MIT
// @icon         https://www.google.com/s2/favicons?sz=64&domain=drawaria.online
// ==/UserScript==

// EN ESTA LÍNEA SE HACE EL CAMBIO
(function($) { // <--- Aquí se define $ como un parámetro de la función
    'use strict';

    // --- Helper Functions from Drawaria's main.js (enhanced for better integration) ---
    // This function attempts to use Drawaria's internal localization function (fa)
    // and falls back to a default value if it's not available.
    function getLocalizedText(key, defaultVal) {
        if (window.fa && typeof window.fa === 'function') {
            const localized = window.fa(key);
            // Drawaria's fa returns the key if no translation is found, so we check.
            if (localized !== key) {
                return localized;
            }
        }
        return defaultVal;
    }

    // This function attempts to use Drawaria's internal system message function (ea)
    // and falls back to a simple chat message if it's not available.
    function showDrawariaMessage(msg, type = 'info') {
        if (window.ea && typeof window.ea === 'function') {
            // Use Drawaria's internal function for system messages
            window.ea(msg);
        } else {
            // Fallback: append directly to chatbox for basic visibility
            const systemChatMessageDiv = `<div class="chatmessage systemchatmessage">${msg}</div>`;
            $('#chatbox_messages').append(systemChatMessageDiv);
            const chatbox = $('#chatbox_messages')[0];
            if (chatbox) { // Ensure chatbox exists before trying to scroll
                chatbox.scrollTop = chatbox.scrollHeight; // Scroll to bottom
            }
            console.log(`Drawaria Palette Assistant: ${msg}`); // Also log to console
        }
    }

    // Function to convert RGB to Hex (standard utility)
    function rgbToHex(rgb) {
        if (rgb.startsWith('rgb')) {
            const parts = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)$/);
            if (!parts) return rgb;
            delete parts[0];
            for (let i = 1; i <= 3; ++i) {
                parts[i] = parseInt(parts[i]).toString(16);
                if (parts[i].length === 1) parts[i] = '0' + parts[i];
            }
            return '#' + parts.slice(1, 4).join('');
        }
        return rgb; // Assume it's already hex or rgba, return as is (Drawaria might give rgba)
    }

    // --- Core Script Logic ---
    let customPalettes = [];
    const STORAGE_KEY = 'drawaria_custom_color_palettes';

    // Load palettes from localStorage
    function loadPalettes() {
        try {
            const stored = localStorage.getItem(STORAGE_KEY);
            customPalettes = stored ? JSON.parse(stored) : [];
        } catch (e) {
            console.error('Error loading custom palettes:', e);
            customPalettes = [];
            showDrawariaMessage(getLocalizedText('Error loading palettes. Please check console.', 'Error loading palettes. Please check console.'));
        }
    }

    // Save palettes to localStorage
    function savePalettes() {
        try {
            localStorage.setItem(STORAGE_KEY, JSON.stringify(customPalettes));
        } catch (e) {
            console.error('Error saving custom palettes:', e);
            showDrawariaMessage(getLocalizedText('Error saving palettes. Browser storage might be full.', 'Error saving palettes. Browser storage might be full.'), 'error');
        }
    }

    // Get current colors from Drawaria's palette buttons
    function getCurrentPaletteColors() {
        const colors = [];
        // Select all color buttons, but exclude the "color picker" button which is the last one
        // and doesn't represent a direct color.
        $('.drawcontrols-button.drawcontrols-color[data-ctrlgroup="color"]').each(function(index) {
            // Drawaria has 12 basic color buttons (0-11) + 1 color picker button (12th in array, but 13th button overall)
            // The 13th button is the color picker, which doesn't have a fixed color to capture.
            if (index < 12) {
                colors.push(rgbToHex($(this).css('background-color')));
            }
        });
        return colors;
    }

    // Render / update the list of custom palettes in the panel
    function renderPaletteList() {
        const $paletteList = $('#paletteAssistantList');
        $paletteList.empty();

        if (customPalettes.length === 0) {
            $paletteList.append($('<p>').text(getLocalizedText('No palettes saved yet.', 'No palettes saved yet.')));
            return;
        }

        customPalettes.forEach((palette, index) => {
            const $item = $('<div>').addClass('palette-item');
            const $paletteColors = $('<div>').addClass('palette-item-colors');
            palette.colors.forEach(color => {
                $('<span>').css('background-color', color).appendTo($paletteColors);
            });

            const $name = $('<span>').text(palette.name).addClass('palette-item-name');
            const $loadBtn = $('<button>').text(getLocalizedText('Load', 'Load')).addClass('palette-item-btn load-btn');
            const $deleteBtn = $('<button>').text(getLocalizedText('Delete', 'Delete')).addClass('palette-item-btn delete-btn');

            $loadBtn.on('click', () => applyPalette(palette.colors));
            $deleteBtn.on('click', (e) => {
                e.stopPropagation(); // Prevent item click if we implement it later
                deletePalette(index);
            });

            $item.append($name, $paletteColors, $loadBtn, $deleteBtn);
            $paletteList.append($item);
        });
    }

    // Apply a saved palette to Drawaria's color buttons
    function applyPalette(colors) {
        const $colorButtons = $('.drawcontrols-button.drawcontrols-color[data-ctrlgroup="color"]');
        colors.forEach((color, i) => {
            if (i < 12) { // Apply only to the basic 12 color buttons
                $colorButtons.eq(i).css('background-color', color);
            }
        });
        showDrawariaMessage(getLocalizedText('Palette applied!', 'Palette applied!'), 'info');
    }

    // Save current palette
    function saveCurrentPalette() {
        const paletteName = prompt(getLocalizedText('Enter a name for this palette:', 'Enter a name for this palette:'));
        if (paletteName) {
            const currentColors = getCurrentPaletteColors();
            if (currentColors.length === 0) {
                showDrawariaMessage(getLocalizedText('Could not capture current palette colors. Are you in a drawing round?', 'Could not capture current palette colors. Are you in a drawing round?'), 'warning');
                return;
            }
            customPalettes.push({ name: paletteName, colors: currentColors });
            savePalettes();
            renderPaletteList();
            showDrawariaMessage(getLocalizedText('Palette saved successfully!', 'Palette saved successfully!'), 'info');
        } else if (paletteName === '') {
            showDrawariaMessage(getLocalizedText('Palette name cannot be empty.', 'Palette name cannot be empty.'), 'warning');
        }
    }

    // Delete a palette
    function deletePalette(index) {
        if (confirm(getLocalizedText('Are you sure you want to delete this palette?', 'Are you sure you want to delete this palette?'))) {
            customPalettes.splice(index, 1);
            savePalettes();
            renderPaletteList();
            showDrawariaMessage(getLocalizedText('Palette deleted.', 'Palette deleted.'), 'info');
        }
    }

    // Initialize UI and load data
    function initPaletteAssistant() {
        loadPalettes();

        // Create the main toggle button
        const $toggleButton = $('<button>')
            .attr('id', 'paletteAssistantToggleButton')
            .text(getLocalizedText('🎨 Palettes', '🎨 Palettes')) // Use localized text
            .addClass('btn btn-outline-secondary btn-sm'); // Reuse Drawaria's button classes for styling

        // Create the palette panel
        const $palettePanel = $('<div>')
            .attr('id', 'paletteAssistantPanel')
            .addClass('palette-assistant-panel')
            .hide();

        const $panelHeader = $('<div>').addClass('panel-header');
        $('<span>').text(getLocalizedText('Custom Palettes', 'Custom Palettes')).appendTo($panelHeader);
        $('<button>').text('X').addClass('close-btn').on('click', () => $palettePanel.hide()).appendTo($panelHeader);

        const $paletteList = $('<div>').attr('id', 'paletteAssistantList').addClass('palette-list');
        const $saveButton = $('<button>').text(getLocalizedText('Save Current Palette', 'Save Current Palette')).addClass('save-btn');

        $saveButton.on('click', saveCurrentPalette);

        $palettePanel.append($panelHeader, $paletteList, $saveButton);

        // Append to a consistent location, e.g., body with fixed positioning
        // This ensures it's always visible regardless of Drawaria's dynamic UI.
        $('body').append($toggleButton, $palettePanel);

        // Toggle panel visibility
        $toggleButton.on('click', () => $palettePanel.toggle());

        // Initial render of palettes
        renderPaletteList();

        // --- Inject CSS for the panel ---
        // Using `position: fixed` for robustness and always-on-top visibility
        $('head').append(`
            <style>
                #paletteAssistantToggleButton {
                    position: fixed;
                    top: 10px; /* Adjust vertical position */
                    right: 180px; /* Adjust horizontal position, leaving space from right edge */
                    z-index: 10000; /* Ensure it's on top of almost everything */
                    width: auto;
                    padding: 0.5em 1em;
                    height: auto;
                    line-height: 1;
                    font-size: 1em;
                    background-color: #f1f9f5; /* Light background to match Drawaria UI */
                    color: #333;
                    border: 1px solid #b0b5b9;
                    border-radius: .5em;
                    cursor: pointer;
                    box-shadow: 0 2px 5px rgba(0,0,0,0.2);
                    transition: all 0.2s ease;
                    white-space: nowrap; /* Prevent text wrapping */
                }
                #paletteAssistantToggleButton:hover {
                    background-color: #e0e0e0;
                    box-shadow: 0 4px 8px rgba(0,0,0,0.3);
                }
                .palette-assistant-panel {
                    position: fixed;
                    top: 50px; /* Position slightly below the button */
                    right: 180px; /* Align with the button */
                    width: 280px; /* Slightly wider panel for content */
                    background-color: #f1f9f5;
                    border: 1px solid #b0b5b9;
                    border-radius: .5em;
                    box-shadow: 0 5px 15px rgba(0,0,0,0.3);
                    z-index: 9999; /* Slightly lower than button, but still high */
                    display: flex;
                    flex-direction: column;
                    padding: 0.8em;
                }
                .panel-header {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    font-weight: bold;
                    margin-bottom: 0.8em;
                    color: #333;
                    font-size: 1.1em;
                }
                .panel-header .close-btn {
                    background: none;
                    border: none;
                    font-size: 1.2em;
                    cursor: pointer;
                    color: #555;
                }
                .panel-header .close-btn:hover {
                    color: #000;
                }
                .palette-list {
                    max-height: 200px;
                    overflow-y: auto;
                    margin-bottom: 1em;
                    border-top: 1px solid #eee;
                    padding-top: 0.5em;
                }
                .palette-list p {
                    text-align: center;
                    color: #777;
                    font-style: italic;
                }
                .palette-item {
                    display: flex;
                    align-items: center;
                    padding: 0.5em;
                    border: 1px solid #ddd;
                    border-radius: 4px;
                    margin-bottom: 0.5em;
                    background-color: #fff;
                    font-size: 0.9em;
                }
                .palette-item:hover {
                    background-color: #f8f8f8;
                }
                .palette-item-name {
                    flex-grow: 1;
                    margin-right: 0.5em;
                    font-weight: bold;
                    color: #333;
                    white-space: nowrap;
                    overflow: hidden;
                    text-overflow: ellipsis;
                }
                .palette-item-colors {
                    display: flex;
                    margin-right: 0.5em;
                }
                .palette-item-colors span {
                    width: 15px;
                    height: 15px;
                    border: 1px solid #ccc;
                    display: inline-block;
                    margin-right: -1px; /* Overlap borders */
                }
                .palette-item-btn {
                    padding: 0.3em 0.6em;
                    font-size: 0.8em;
                    border-radius: 4px;
                    cursor: pointer;
                    margin-left: 0.3em;
                    white-space: nowrap;
                    min-width: 50px; /* Ensure buttons have consistent width */
                    text-align: center;
                }
                .load-btn {
                    background-color: #5cb85c;
                    color: white;
                    border: 1px solid #4cae4c;
                }
                .load-btn:hover {
                    background-color: #4cae4c;
                }
                .delete-btn {
                    background-color: #d9534f;
                    color: white;
                    border: 1px solid #d43f3a;
                }
                .delete-btn:hover {
                    background-color: #d43f3a;
                }
                .save-btn {
                    width: 100%;
                    padding: 0.6em;
                    background-color: #007bff;
                    color: white;
                    border: 1px solid #007bff;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 1em;
                }
                .save-btn:hover {
                    background-color: #0056b3;
                }
            </style>
        `);
    }

    // Wait for jQuery and Drawaria's core elements to be available
    function waitForDrawariaElements() {
        // Check for jQuery and at least the color buttons in the draw controls
        // This ensures the game UI is loaded and ready before injecting our script.
        if (typeof window.jQuery !== 'undefined' && window.jQuery('.drawcontrols-button.drawcontrols-color').length >= 12) {
            // Check for the Drawaria's main drawing area too, to be sure
            if (window.jQuery('#canvas').length && window.jQuery('#drawcontrols').length) {
                initPaletteAssistant();
            } else {
                // If not in a drawing round yet, but Drawaria is loaded, retry after a delay
                setTimeout(waitForDrawariaElements, 500);
            }
        } else {
            // If jQuery or core elements aren't loaded yet, keep waiting
            setTimeout(waitForDrawariaElements, 100);
        }
    }

    waitForDrawariaElements();

// Y AQUÍ SE PASA window.jQuery a la función principal
})(window.jQuery); // <--- Aquí se pasa window.jQuery para que sea el $ dentro del script