# Plan de Implementación del Sistema de Traducción

## Objetivo
Crear un sistema de traducción dinámico que permita cargar idiomas desde archivos JSON externos **sin modificar los textos hardcodeados existentes**. Los textos en el código bleiben en inglés como fallback por defecto.

---

## 1. Funcionamiento Clave

### 1.1 Comportamiento
- **Sin carpeta de idiomas**: El juego funciona exactamente como ahora con los textos hardcodeados en inglés
- **Con carpeta de idiomas**: Cuando el usuario selecciona un idioma, se carga el JSON y se traducen los textos disponibles
- **Fallback**: Si una traducción no existe en el JSON, se usa el texto hardcodeado (inglés)

### 1.2 Carpeta de Idiomas (opcional)
```
/lenguajes/
  ├── Espanol.json
  ├── Portugues.json
  └── (otros idiomas).json
```

**Nota**: No se requiere English.json porque el inglés ya está hardcodeado en el código.

---

## 2. Archivos a Crear

| Archivo | Descripción |
|---------|-------------|
| `soh/soh/SohGui/LanguageManager.h` | Header del manager de idiomas |
| `soh/soh/SohGui/LanguageManager.cpp` | Implementación del manager |
| `lenguajes/Espanol.json` | Traducción español (ejemplo) |
| `lenguajes/Portugues.json` | Traducción portugués (ejemplo) |

---

## 3. Archivos a Modificar

| Archivo | Cambios |
|---------|---------|
| `soh/soh/SohGui/SohMenuSettings.cpp` | Agregar selector de idioma dinámico en configuración |

**Nota**: Los demás archivos del menú NO necesitan modificación. La función de traducción se aplica automáticamente a todos los textos existentes.

---

## 4. Formato de Archivos JSON

### 4.1 Estructura del JSON
```json
{
  "language": "Español",
  "strings": {
    "Settings": "Configuración",
    "Enhancements": "Mejoras",
    "Randomizer": "Randomizer",
    "Network": "Red",
    "Dev Tools": "Herramientas de Desarrollo",
    "Enabled": "Activado",
    "Disabled": "Desactivado",
    "Apply": "Aplicar",
    "Cancel": "Cancelar"
  }
}
```

### 4.2 Espanol.json (Ejemplo)
```json
{
  "language": "Español",
  "strings": {
    "Settings": "Configuración",
    "Enhancements": "Mejoras",
    "Randomizer": "Randomizer",
    "Network": "Red",
    "Dev Tools": "Herramientas de Desarrollo",
    "General Settings": "Configuración General",
    "Graphics": "Gráficos",
    "Audio": "Audio",
    "Controls": "Controles",
    "Enabled": "Activado",
    "Disabled": "Desactivado",
    "On": "Activado",
    "Off": "Desactivado",
    "Yes": "Sí",
    "No": "No",
    "Apply": "Aplicar",
    "Cancel": "Cancelar",
    "Resolution": "Resolución",
    "FPS Limit": "Límite de FPS",
    "VSync": "Sincronización Vertical",
    "Master Volume": "Volumen Principal",
    "Music Volume": "Volumen de Música",
    "SFX Volume": "Volumen de Efectos",
    "Anti-aliasing (MSAA)": "Antialiasing (MSAA)"
  }
}
```

---

## 5. Implementación del LanguageManager

### 5.1 LanguageManager.h
```cpp
class LanguageManager {
public:
    static LanguageManager& Instance();
    
    void Init();
    void LoadLanguage(const std::string& languageName);
    std::string GetString(const std::string& key);
    std::vector<std::string> GetAvailableLanguages();
    std::string GetCurrentLanguage();
    bool IsTranslationLoaded();
    
private:
    std::string currentLanguage;
    std::map<std::string, std::string> translations;
    bool translationLoaded;
    
    void ScanLanguageFiles();
    bool LoadJsonFile(const std::string& path);
};
```

### 5.2 Lógica de Funcionamiento

```cpp
std::string LanguageManager::GetString(const std::string& key) {
    // Si no hay traducción cargada, retorna el texto hardcodeado (ingles)
    if (!translationLoaded || translations.empty()) {
        return key;
    }
    
    // Busca la traducción
    auto it = translations.find(key);
    if (it != translations.end()) {
        return it->second;
    }
    
    // Si no encuentra la traducción, retorna el texto hardcodeado
    return key;
}
```

### 5.3 Funcionalidades Principales

1. **Escaneo de idiomas**: Al iniciar, escanea la carpeta `/lenguajes/` y detecta archivos `.json`
2. **Carga bajo demanda**: Solo carga el JSON cuando el usuario selecciona un idioma
3. **Fallback seguro**: Si no existe la traducción, retorna el texto hardcodeado
4. **Selector dinámico**: Genera opciones basadas en archivos encontrados (sin hardcodear nombres)

---

## 6. Ejemplo de Uso en el Código

### 6.1 Sin cambios en el código existente
Los textos hardcodeados permanecen exactamente igual:

```cpp
// El código queda igual, NO se cambia a L("key")
AddWidget(path, "Settings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Language", WIDGET_CVAR_COMBOBOX);
AddWidget(path, "Enabled", WIDGET_CVAR_CHECKBOX);
```

### 6.2 La traducción se aplica automáticamente
La función `GetString()` intercepta los textos y los traduce:

```cpp
// Internamente en AddWidget o donde se muestra el texto:
std::string displayText = LanguageManager::Instance().GetString("Settings");
// Si hay español cargado, retorna "Configuración"
// Si no hay traducción, retorna "Settings" (el texto original)
```

### 6.3 Cómo funciona
- Los textos en el código bleiben en inglés
- La función `GetString()` se llama al momento de mostrar el texto
- Si hay una traducción cargada y existe la clave, retorna la traducción
- Si no hay traducción o no existe la clave, retorna el texto original (hardcodeado)

---

## 7. Selector de Idioma

### 7.1 Ubicación
En `SohMenuSettings.cpp` dentro del menú de configuración

### 7.2 Comportamiento
- Muestra todos los archivos `.json` encontrados en `/lenguajes/`
- El nombre del archivo (sin extensión) se muestra en el selector
- Al seleccionar un idioma, carga el archivo JSON correspondiente
- Por defecto (sin acción del usuario), funciona con textos hardcodeados

### 7.3 Ejemplo de implementación del selector
```cpp
// El selector se genera dinámicamente
std::vector<std::string> languages = LanguageManager::Instance().GetAvailableLanguages();
// languages = {"Espanol", "Portugues", ...} (nombres de archivos JSON)

// Mostrar en el menú
AddWidget(path, "Language", WIDGET_CVAR_COMBOBOX)
    .Options(languages);
```

---

## 8. Proceso de Implementación (Orden Sugerido)

### Fase 1: Fundamentos
1. Crear `LanguageManager.h/cpp`
2. Crear estructura de carpetas `/lenguajes/`

### Fase 2: Integración
3. Modificar `SohMenuSettings.cpp` para agregar selector de idioma dinámico
4. Conectar el selector con `LanguageManager`

### Fase 3: Pruebas
5. Crear `Espanol.json` de prueba
6. Probar cambio de idioma

---

## 9. Notas Importantes

- ✅ **Textos hardcodeados permanecen**: El código no se modifica, los textos en inglés quedan como están
- ✅ **Sin carpeta de idiomas funciona igual**: Si no existe la carpeta, el juego funciona exactamente como antes
- ✅ **Fallback automático**: Si falta una traducción, se muestra el texto original
- ✅ **Selector dinámico**: Los nombres de idiomas vienen de los archivos JSON, no están hardcodeados
- ✅ **Fácil agregar idiomas**: Solo hay que crear un nuevo archivo `.json` en la carpeta

---

## 10. Archivos de Referencia con Textos Hardcodeados

### SohGui (ya analizados)
- `SohMenu_hardcoded.txt`
- `SohMenuSettings_hardcoded.txt`
- `SohMenuEnhancements_hardcoded.txt`
- `SohMenuRandomizer_hardcoded.txt`
- `SohMenuNetwork_hardcoded.txt`
- `SohMenuDevTools_hardcoded.txt`
- `SohMenuBar_hardcoded.txt`
- `ResolutionEditor_hardcoded.txt`

---

## 11. Diferencias con el Plan Anterior

| Aspecto | Plan Anterior | Plan Actual |
|---------|---------------|--------------|
| English.json | Obligatorio | No necesario (hardcodeado es fallback) |
| Reemplazo de textos | Sí, en todos los archivos | No, solo agregar función GetString |
| Archivos a modificar | 8+ archivos | Solo 1 archivo (SohMenuSettings.cpp) |
| Funcionamiento sin carpeta | Requiere English.json | Funciona igual que antes |
