---
plan: "AI-Generated Dynamic UI – Runtime XML Generation"
description: "AI generuje Kodi XML dialogy za běhu podle kontextu obsahu. Každý film/seriál dostane unikátní vizuální stránku."
status: "in-progress"
priority: "high"
complexity: "epic"
created: "2026-04-06"
updated: "2026-04-06"
completed: null
depends_on: null
related_features:
  - "docs/features/002-ai-system.md"
  - "docs/features/004-mytv.md"
  - "docs/features/006-metadata.md"
  - "docs/features/012-ui-system.md"
related_research:
  - "docs/research/2026-04-06-kodi-cache-system.md"
estimated_files: 8
---

# AI-Generated Dynamic UI – Runtime XML Generation

## Motivace

Kodi XML dialogy jsou statické – každý film vypadá stejně. Máme ale:
1. **AI engine** (5 providerů) schopný generovat kód
2. **TMDb metadata** (žánry, hodnocení, barvy posterů, počet sezón, nálada)
3. **Runtime XML Injection** – ověřená technika přepisování XML před otevřením dialogu

Spojením těchto tří komponent vytvoříme systém, kde AI generuje unikátní vizuální stránku pro každý film/seriál. Horor bude vypadat jako horor, romantika jako romantika. Žádný jiný Kodi addon tohle neumí.

## Cíl

**Po implementaci prototypu**: Když uživatel otevře detail filmu/seriálu, AI vygeneruje přizpůsobenou XML stránku na základě metadat (žánr, nálada, hodnocení). Stránka se zobrazí jako `WindowXMLDialog` s unikátními barvami, animacemi a rozložením.

**Měřitelný výstup**: Detail hororu bude vizuálně odlišný od detailu romantické komedie – jiné barvy, animace, pozadí.

## Současný stav

### Existující komponenty

- **AIHandler** (`wcs/ai/AIHandler.py`, 94 KB): Orchestrace AI požadavků, multi-provider podpora (viz [002-ai-system.md](../features/002-ai-system.md))
- **DialogWcsDetails** (`wcs/ui/dialogs/DialogWcsDetails.py`, 19 KB): Statický detail dialog s XML šablonou (viz [012-ui-system.md](../features/012-ui-system.md))
- **TMDbClient** (`wcs/metadata/TMDbClient.py`): Kompletní metadata – žánry, rating, overview, images (viz [006-metadata.md](../features/006-metadata.md))
- **Runtime XML Injection**: Ověřená technika – Python přepisuje XML před `WindowXMLDialog()` (MyTV Ken Burns animace)
- **TMDbCache** (`wcs/metadata/TMDbCache.py`): Disk cache s TTL pro API odpovědi

### Co chybí

- Žádné propojení mezi AI a XML generováním
- Žádný template systém pro dynamické XML
- Žádný systém pro cachování vygenerovaných XML
- Žádný prompt engineering pro XML generování

## Navrhované řešení

### Přehled

Systém se skládá z 3 vrstev: (1) **XML Template Engine** – Python třída která z parametrů generuje validní Kodi XML, (2) **AI Style Generator** – AI analyzuje metadata a vrátí styl (barvy, animace, layout), (3) **Dynamic Dialog Loader** – nahrazuje statický XML za dynamicky generovaný. Prototyp implementuje jednu stránku – detail filmu.

### Architektura

```
Uživatel klikne "Detail filmu"
         ↓
TMDb metadata (žánr, rating, overview, images)
         ↓
AI Style Generator → prompt: "Pro horor z 1987 s ratingem 8.5 vrať JSON se stylem"
         ↓
AI odpovídá: { barvy, animace, layout_variant, nálada }
         ↓
XML Template Engine → generuje kompletní XML dialog z šablony + stylu
         ↓
Zápis do temp XML souboru
         ↓
WindowXMLDialog(temp_xml) → unikátní vizuální stránka
```

### Fáze implementace

#### FÁZE 1: Proof of Concept (tento plán)

Cíl: **Jeden dialog** (detail filmu) s **AI-generovanými barvami a animacemi**. Ne celý layout – jen vizuální styl aplikovaný na existující šablonu.

#### FÁZE 2: Pokročilé šablony (budoucí plán)

Cíl: AI volí z několika layout variant + generuje celé sekce.

#### FÁZE 3: Plně generované dialogy (budoucí plán)

Cíl: AI generuje kompletní XML dialogy od nuly.

---

### Dotčené soubory (FÁZE 1)

| Soubor | Akce | Popis změny |
|--------|------|-------------|
| `wcs/ui/DynamicXMLEngine.py` | NEW | XML Template Engine – generace XML z parametrů |
| `wcs/ui/AIStyleGenerator.py` | NEW | AI style generator – prompt + parsing odpovědi |
| `wcs/ui/dialogs/DialogWcsDetails.py` | MODIFY | Napojení na Dynamic XML místo statického XML |
| `resources/skins/Default/1080i/ui/DialogWcsDetails.xml` | MODIFY | Přidání markerů pro injection |
| `resources/settings.xml` | MODIFY | Setting pro zapnutí/vypnutí AI UI |
| `docs/features/012-ui-system.md` | MODIFY | Aktualizace dokumentace |

### Implementační kroky (FÁZE 1)

#### Krok 1: AIStyleGenerator – AI vrací vizuální styl

**Soubor**: `wcs/ui/AIStyleGenerator.py` (NEW, ~100 řádků)

```python
class AIStyleGenerator:
    """Generuje vizuální styl pro obsah na základě metadat."""
    
    def generate_style(self, metadata: dict) -> dict:
        """
        Vstup: { genre_ids, vote_average, overview, release_date, ... }
        Výstup: {
            "primary_color": "FF8B0000",    # AARRGGBB
            "secondary_color": "FFB22222",
            "accent_color": "FFFF4444",
            "bg_opacity": "CC",
            "animation_speed": 15000,       # ms
            "animation_zoom": 104,          # procenta
            "mood": "dark",                 # dark | light | warm | cool | vibrant
        }
        """
```

**Logika**:
1. Sestaví prompt z metadat: žánry, hodnocení, rok, overview
2. Prompt instruuje AI vrátit **JSON** s přesně definovanými klíči
3. Systémový prompt obsahuje Kodi AARRGGBB color format pravidla
4. Fallback: pokud AI selže → hardcoded styl podle žánru (bez API callu)
5. **Cache**: Výsledný styl se cachuje přes TMDbCache (klíč = tmdb_id, TTL = 30 dní)

**Prompt design**:
```
Jsi designér Kodi TV rozhraní. Na základě informací o filmu/seriálu vrať vizuální styl jako JSON.

Film: {title} ({year})
Žánry: {genres}
Hodnocení: {rating}/10
Popis: {overview}

Vrať POUZE JSON (žádný markdown, žádný text):
{
  "primary_color": "AARRGGBB barva hlavního pozadí",
  "secondary_color": "AARRGGBB barva sekundárních prvků",
  "accent_color": "AARRGGBB barva akcentů (tlačítka, highlights)",
  "bg_opacity": "AA hex hodnota opacity pozadí (00-FF)",
  "animation_speed": číslo v ms (5000-30000),
  "animation_zoom": číslo procent (100-115),
  "mood": "dark|light|warm|cool|vibrant"
}

Pravidla:
- AARRGGBB: první 2 znaky = alpha (FF=plná, 80=polopruhedná), pak RRGGBB
- Horor → tmavé, červené/fialové tóny, pomalé animace
- Komedie → jasné, teplé barvy, rychlejší animace  
- Sci-fi → studené, neonové tóny
- Drama → tlumené, sofistikované barvy
- Animovaný → výrazné, saturované barvy
```

#### Krok 2: DynamicXMLEngine – injection stylu do XML

**Soubor**: `wcs/ui/DynamicXMLEngine.py` (NEW, ~80 řádků)

```python
class DynamicXMLEngine:
    """Injektuje dynamické hodnoty do XML šablony."""
    
    def inject_style(self, xml_path: str, style: dict) -> str:
        """
        Přečte XML šablonu, nahradí markery hodnotami ze stylu.
        Vrátí cestu k upravenému XML (zapisuje zpět do stejného souboru).
        
        Markery v XML:
        {{PRIMARY_COLOR}} → style["primary_color"]
        {{SECONDARY_COLOR}} → style["secondary_color"]
        {{ACCENT_COLOR}} → style["accent_color"]
        {{BG_OPACITY}} → style["bg_opacity"]
        {{ANIMATION_SPEED}} → style["animation_speed"]
        {{ANIMATION_ZOOM}} → style["animation_zoom"]
        """
```

**Logika**:
1. Přečte XML soubor
2. Nahradí `{{MARKER}}` hodnotami ze style dictu
3. Zapíše zpět do souboru
4. Po zavření dialogu obnoví originální XML s markery (restore)

**Důležité**: Po `dialog.doModal()` se MUSÍ obnovit originální XML s `{{MARKER}}` placeholders, aby další volání mělo z čeho injektovat.

#### Krok 3: Úprava DialogWcsDetails.xml – přidání markerů

Do existující XML šablony přidat markery místo hardcoded hodnot:

```xml
<!-- PŘED -->
<textcolor>FFffffff</textcolor>
<shadowcolor>CC000000</shadowcolor>

<!-- PO -->
<textcolor>{{ACCENT_COLOR}}</textcolor>
<shadowcolor>{{BG_OPACITY}}000000</shadowcolor>
```

Markery se přidají na:
- Barvy textů (title, description, metadata labels)
- Barvy pozadí (overlaye, panely)
- Animační parametry (zoom, speed)
- Opacity vrstev

#### Krok 4: Napojení do DialogWcsDetails.py

Ve funkci `show_detail_dialog()`:

```python
def show_detail_dialog(addon, tmdb_id, media_type):
    # 1. Získej metadata z TMDb
    metadata = get_movie_details(tmdb_id)
    
    # 2. Generuj styl (AI nebo fallback)
    if addon.getSetting('ai_dynamic_ui') == 'true':
        style_gen = AIStyleGenerator(addon)
        style = style_gen.generate_style(metadata)
    else:
        style = DEFAULT_STYLE
    
    # 3. Injektuj styl do XML
    engine = DynamicXMLEngine()
    xml_path = engine.inject_style(detail_xml_path, style)
    
    # 4. Otevři dialog
    dialog = DetailDialog(xml_path, ...)
    dialog.doModal()
    
    # 5. RESTORE originální XML s markery
    engine.restore(detail_xml_path)
```

#### Krok 5: Setting pro zapnutí/vypnutí

```xml
<setting id="ai_dynamic_ui" type="bool" label="AI dynamické UI" default="false"/>
```

Defaultně OFF – uživatel musí mít AI provider nakonfigurovaný.

#### Krok 6: Žánrový fallback (bez AI)

Pokud AI není dostupné nebo selže, použít hardcoded styl mapy:

```python
GENRE_STYLES = {
    28: {"primary_color": "FF1a1a2e", "accent_color": "FFe94560", "mood": "dark"},       # Action
    35: {"primary_color": "FF2d4a3e", "accent_color": "FFf4d03f", "mood": "warm"},       # Comedy
    27: {"primary_color": "FF0d0d0d", "accent_color": "FF8B0000", "mood": "dark"},       # Horror
    10749: {"primary_color": "FF2d1b2e", "accent_color": "FFe91e63", "mood": "warm"},    # Romance
    878: {"primary_color": "FF0a192f", "accent_color": "FF00d4ff", "mood": "cool"},      # Sci-Fi
    16: {"primary_color": "FF1a237e", "accent_color": "FFff6f00", "mood": "vibrant"},     # Animation
    18: {"primary_color": "FF1c1c1c", "accent_color": "FFb0bec5", "mood": "dark"},       # Drama
    99: {"primary_color": "FF1b3a2d", "accent_color": "FF4caf50", "mood": "cool"},       # Documentary
}
```

### Settings změny

| Setting ID | Popis | Typ | Default | Hodnoty |
|-----------|-------|-----|---------|---------:|
| `ai_dynamic_ui` | AI dynamické UI | bool | `false` | true/false |

### Závislosti

- **AIHandler** musí být funkční s alespoň jedním AI providerem
- **TMDbClient** musí vracet žánry a metadata
- **Runtime XML Injection** technika (již ověřená v MyTV Ken Burns)

## Rizika a omezení

- **Latence AI**: Generování stylu trvá 1-3 sekundy → vyřeší cache (30 dní per title)
- **Konzistence**: AI může vracet neplatné barvy → validace + fallback na genre style
- **Náklady**: Každý nový film = 1 AI request (~100 tokenů = $0.0001) → zanedbatelné
- **Restore selhání**: Pokud crash před restore XML → markery zůstanou v XML → dialog se nezobrazí → bezpečnostní fallback: detekce `{{` v XML = automatický restore z backup
- **Thread safety**: Dva dialogy otevřené současně by mohly kolidovat → mutex na XML zápis

## Testování

1. **Horor film** – ověřit tmavé/červené barvy, pomalé animace
2. **Komedie** – ověřit teplé/jasné barvy, rychlejší animace
3. **Sci-fi** – ověřit studené/neonové tóny
4. **AI nedostupné** – ověřit žánrový fallback funguje
5. **Cache** – druhé otevření stejného filmu = okamžité (bez AI callu)
6. **Restore** – po zavření dialogu XML má zpět `{{MARKER}}` placeholders

## Poznámky

### Zvážené alternativy

1. **Generování celého XML od AI** – zamítnuto pro FÁZI 1. AI by musela znát kompletní Kodi XML syntax včetně navigace, focusů, containerů. Příliš velké riziko chyb. Vhodné pro FÁZI 3.
2. **Preset systém bez AI** – zamítnuto. Omezený počet variant, nedokáže reagovat na nuance obsahu.
3. **CSS-like stylesheets** – zamítnuto. Kodi XML engine nepodporuje external stylesheets.

### Budoucí rozšíření (FÁZE 2+)

- AI vybírá z více layout variant (kompaktní/rozšířený/cinematic)
- AI generuje textové popisy scén jako ambient text
- AI adapotuje UI na základě historie sledování uživatele (preference tmavých filmů = tmavší UI)
- Generování celých XML sekcí (EPG grid, cast listing s custom layoutem)
- Aplikace na VŠECHNY dialogy – MyTV, MyCinema, Search, MyList
