flowchart TD
    A["HyprTile Launcher / hyprtile.c"] -->|"F2"| B["overlay_music_player"]

    B --> API["overlay_music_player.h API"]
    API --> Toggle["music_player_toggle_visible"]
    API --> Update["music_player_update_if_needed"]
    API --> ClickCmd["music_player_click_command"]
    API --> MouseWheel["handle_music_player_mouse_wheel"]
    API --> MouseButton["handle_music_player_mouse_button"]
    API --> Render["render_music_player_overlay"]

    B --> State["MusicPlayerState"]
    State --> Visible["visible"]
    State --> Daemon["daemon_running / state / error"]
    State --> Current["track_index / title / artist / album / filename / path"]
    State --> Time["position_sec / duration_sec / remaining_sec"]
    State --> PlaylistState["playlist_count / playlist_scroll"]
    State --> Cache["playlist_library_mtime / has_playlist_library_mtime"]

    B --> UI["Overlay UI"]
    UI --> Panel["1280x740 Panel"]
    UI --> NowPlaying["NOW PLAYING Box"]
    UI --> Progress["Progressbar + Zeit"]
    UI --> Buttons["Prev / -10s / Play-Pause / Stop / +10s / Next / Scan"]
    UI --> PlaylistView["Playlist-Liste bis 2048 Tracks"]

    Toggle --> EnsureDaemon["music_player_ensure_daemon"]
    EnsureDaemon --> StatusCheck["hyprtile-audioplayer --status"]
    StatusCheck -->|"running"| QueryPlaylist["Playlist laden"]
    StatusCheck -->|"nicht erreichbar"| FirstScan["einmalig: hyprtile-audioplayer --scan"]
    FirstScan --> SpawnDaemon["spawn_hyprtile_utility_daemon('hyprtile-audioplayer')"]
    SpawnDaemon --> Delay["180ms warten"]
    Delay --> StatusAgain["Status neu lesen"]
    StatusAgain --> QueryPlaylist

    QueryPlaylist --> FileLibrary["Library-Datei suchen"]
    FileLibrary --> Musik["$HOME/Musik/hyprtile-audioplayer-library.json"]
    FileLibrary --> Music["$HOME/Music/hyprtile-audioplayer-library.json"]
    FileLibrary --> Local["./hyprtile-audioplayer-library.json"]

    FileLibrary -->|"gefunden + mtime neu"| ReadFile["read_text_file_limited"]
    FileLibrary -->|"nicht gefunden"| CliFallback["hyprtile-audioplayer --playlist"]
    CliFallback --> CliFallback2["Fallback: hyprtile-audioplayer --list"]

    ReadFile --> ParsePlaylist["music_player_parse_playlist_json"]
    CliFallback2 --> ParsePlaylist

    ParsePlaylist --> JsonObj["JSON Objekt mit tracks[]"]
    ParsePlaylist --> JsonArr["JSON Array"]
    ParsePlaylist --> Ndjson["NDJSON: ein Track pro Zeile"]
    JsonObj --> Entries["MusicPlaylistEntry[]"]
    JsonArr --> Entries
    Ndjson --> Entries

    Entries --> EntryFields["index / path / filename / title / artist / album / duration"]
    EntryFields --> FallbackTitle["Titel-Fallback: title → filename → basename(path)"]
    FallbackTitle --> PlaylistState

    Update --> PollStatus["alle 650ms: --status"]
    Update --> PollPlaylist["Playlist refresh"]
    PollStatus --> ParseStatus["music_player_parse_status_json"]
    ParseStatus --> Current
    ParseStatus --> Time
    ParseStatus --> Daemon

    MouseButton --> RowClick["Playlist-Zeile klicken"]
    RowClick --> PlayIndex["--play-index N"]
    PlayIndex --> PlayFallback1["Fallback: --play N"]
    PlayFallback1 --> PlayFallback2["Fallback: --index N"]

    MouseButton --> Prev["--prev"]
    MouseButton --> Back["--seek -10"]
    MouseButton --> TogglePause["--toggle-pause"]
    MouseButton --> Stop["--stop"]
    MouseButton --> Forward["--seek +10"]
    MouseButton --> Next["--next"]
    MouseButton --> Scan["--scan"]

    MouseWheel --> PlaylistScroll["Playlist scroll ±3 Zeilen"]

    A --> RenderLoop["Render Loop"]
    RenderLoop --> TileHide["Tiles ausblenden wenn music_player.visible"]
    RenderLoop --> Render
    Render --> UI

    B -->|"read_hyprtile_utility_command"| Backend["hyprtile-audioplayer Backend / CLI / Daemon"]

    Backend --> Commands["Commands: --status / --playlist / --list / --scan / --prev / --next / --stop / --toggle-pause / --seek / --play-index / --formats"]
    Backend --> ScanRecursive["Scan $HOME/Music oder $HOME/Musik rekursiv"]
    ScanRecursive --> FormatDetect["supported_format_from_path / audio_format_from_path"]

    FormatDetect --> Modern["Moderne Audioformate"]
    Modern --> MP3[".mp3 → TRACK_MP3 / mpg123"]
    Modern --> FLAC[".flac → TRACK_FLAC / libFLAC"]
    Modern --> Vorbis[".ogg .oga → TRACK_VORBIS / libvorbisfile"]
    Modern --> Opus[".opus → TRACK_OPUS / libopusfile"]

    FormatDetect --> Streams["Internet-Radio Playlists"]
    Streams --> PLS[".pls → TRACK_STREAM_PLAYLIST"]
    Streams --> M3U[".m3u → TRACK_STREAM_PLAYLIST"]

    FormatDetect --> SID["C64 SID"]
    SID --> SIDExt[".sid → TRACK_SID / libsidplayfp + reSIDfp"]

    FormatDetect --> XMP["Tracker / Demoscene Module via libxmp"]
    XMP --> XMPDOS["PC/DOS Module"]
    XMPDOS --> DOSList[".669 .amf .ams .dmf .far .gdm .imf .it .j2b .liq .mdl .mgt .mtm .plm .psm .ptm .rtm .s3m .stm .stx .ult .xm .xmf"]

    XMP --> XMPAmiga["Amiga Module"]
    XMPAmiga --> AmigaList[".dbm .digi .med .mfp .mod .okt .wow .mmd0 .mmd1 .mmd2 .mmd3 .abk .emod .fnk .sfx .stim"]

    XMP --> XMPAtari["Atari ST / Falcon"]
    XMPAtari --> AtariList[".dtm"]

    XMP --> XMPUnreal["PC / Unreal Engine"]
    XMPUnreal --> UnrealList[".umx"]

    Backend --> Metadata["Metadaten-Erkennung"]
    Metadata --> Mp3Meta["MP3: ID3v1 / ID3v2 + Dauer"]
    Metadata --> FlacMeta["FLAC: STREAMINFO + Vorbis Comments"]
    Metadata --> VorbisMeta["Vorbis: duration + comments"]
    Metadata --> OpusMeta["Opus: duration + tags"]
    Metadata --> XmpMeta["XMP: Modulname + Duration"]
    Metadata --> SidMeta["SID: title / artist / released"]
    Metadata --> StreamMeta["PLS/M3U: erste Stream-URL"]

    subgraph SIDStack["SID / C64 Audio Stack"]
        SidWrapper["sidplay_wrapper.cpp"]
        SidReadMeta["sid_read_metadata"]
        SidOpen["sid_decoder_open"]
        SidConfig["sidplayfp + ReSIDfpBuilder"]
        SidTune["SidTune laden + selectSong(0)"]
        SidMixer["initMixer + play(cycles) + mix"]
        SidPcm["int16 PCM Samples"]
        SidSeek["sid_decoder_seek"]
        SidTime["sid_decoder_time"]
    end

    SIDExt --> SidWrapper
    SidWrapper --> SidReadMeta
    SidWrapper --> SidOpen
    SidOpen --> SidConfig
    SidConfig --> SidTune
    SidTune --> SidMixer
    SidMixer --> SidPcm
    SidWrapper --> SidSeek
    SidWrapper --> SidTime

    FormatDetect --> Total["Gesamt: 49 unterstützte Endungen"]