flowchart TD
    A["HyprTile Launcher"] -->|"F3"| B["overlay_video_player"]

    B --> API["overlay_video_player.h API"]
    API --> SetRenderer["video_player_set_renderer"]
    API --> OpenCenter["video_player_open_media_center"]
    API --> Visible["video_player_is_visible"]
    API --> Fullscreen["video_player_is_fullscreen / toggle"]
    API --> PlaybackAPI["Pause / Seek / Next / Block"]
    API --> ScanAPI["video_player_scan"]
    API --> MouseAPI["Mouse Wheel / Button"]
    API --> RenderAPI["render_video_player_overlay"]

    A --> MainLoop["hyprtile.c Event Loop"]
    MainLoop --> F3["F3 Taste"]
    F3 --> OpenCenter
    OpenCenter --> CloseOtherOverlays["andere Overlays ausblenden"]
    CloseOtherOverlays --> B

    MainLoop --> RenderLoop["Render Loop"]
    RenderLoop --> Update["video_player_update_if_needed"]
    RenderLoop --> Render["render_video_player_overlay"]
    RenderLoop --> TilesHidden["Tiles werden ausgeblendet wenn Video sichtbar"]

    B --> State["VideoPlayerState"]
    State --> UIState["visible / fullscreen / paused / eof"]
    State --> PlaylistState["playlist_count / scroll / current_index"]
    State --> LibraryState["library_mtime / blocklist_path / error"]
    State --> DecodeState["AVFormatContext / AVCodecContext / AVPacket / AVFrame"]
    State --> VideoState["SDL_Texture / tex_w / tex_h / SwsContext"]
    State --> AudioState["SDL_AudioStream / SwrContext / audio clock"]
    State --> ClockState["current_sec / duration_sec / clock_base_ticks"]

    B --> Library["Videothek"]
    Library --> FindLibrary["hyprtile-videoplayer-library.json suchen"]
    FindLibrary --> HomeVideos["$HOME/Videos"]
    FindLibrary --> HomeVideo["$HOME/Video"]
    FindLibrary --> LocalFile["./hyprtile-videoplayer-library.json"]

    Library --> ReadLibrary["Library JSON lesen"]
    ReadLibrary --> JsonFormats["Objekt mit tracks[], Array oder NDJSON"]
    JsonFormats --> ParseEntries["VideoPlaylistEntry[]"]
    ParseEntries --> Playlist["Playlist bis 2048 Einträge"]

    Library --> FallbackCLI["Fallback: hyprtile-videoplayer --library"]
    ScanAPI --> ScanCmd["hyprtile-videoplayer --scan"]

    B --> Blocklist["Blockliste"]
    Blocklist --> BlockFile["hyprtile-videoplayer-blocked.txt"]
    BlockFile --> ApplyBlocked["blocked Flag pro Playlist-Eintrag"]
    ApplyBlocked --> SkipBlocked["Next/Prev überspringt blockierte Videos"]
    PlaybackAPI --> ToggleBlocked["aktuelles Video blockieren"]
    ToggleBlocked --> SaveBlocklist["Blockliste speichern"]

    Playlist --> SelectVideo["Video auswählen"]
    SelectVideo --> CloseOld["video_player_close_loaded"]
    CloseOld --> FreeSDL["SDL_Texture / SDL_AudioStream freigeben"]
    CloseOld --> FreeFFmpeg["AVFrames / AVPacket / Codecs / Format schließen"]

    SelectVideo --> OpenCodecs["video_player_open_codecs"]
    OpenCodecs --> OpenInput["avformat_open_input"]
    OpenInput --> StreamInfo["avformat_find_stream_info"]
    StreamInfo --> BestVideo["av_find_best_stream VIDEO"]
    StreamInfo --> BestAudio["Audio-Stream optional"]
    BestVideo --> VideoCodec["Video decoder öffnen"]
    BestAudio --> AudioCodec["Audio decoder öffnen"]

    VideoCodec --> VideoFrames["Video Frames dekodieren"]
    AudioCodec --> AudioFrames["Audio Frames dekodieren"]

    VideoFrames --> Scale["libswscale nach RGBA"]
    Scale --> Texture["SDL_Texture aktualisieren"]
    Texture --> RenderVideo["Video im Overlay zeichnen"]

    AudioFrames --> Resample["libswresample"]
    Resample --> AudioStream["SDL_AudioStream"]
    AudioStream --> AudioClock["Audio Clock als Master"]

    B --> Playback["Playback Engine"]
    Playback --> Clock["video_player_clock_now"]
    Clock --> AudioMaster{"Audio vorhanden und gültig?"}
    AudioMaster -->|"Ja"| QueueComp["audio_clock_sec minus SDL queued seconds"]
    AudioMaster -->|"Nein"| WallClock["SDL_GetTicks Wallclock"]
    QueueComp --> CurrentSec["current_sec"]
    WallClock --> CurrentSec

    Playback --> Pause["Pause"]
    Playback --> Seek["Seek relativ"]
    Playback --> NextPrev["Next / Previous"]
    Playback --> EOF["EOF"]
    EOF --> AutoNext["nächstes spielbares Video"]

    B --> UI["Overlay UI"]
    UI --> Panel["1120x700 Panel"]
    UI --> VideoArea["Video-Fläche"]
    UI --> PlaylistArea["Playlist-Liste"]
    UI --> ProgressBar["Progress / Seekbar"]
    UI --> ScanButton["Scan Button"]
    UI --> Controls["Pause / Seek / Next / Fullscreen / Block"]

    MouseAPI --> Wheel["Mausrad"]
    Wheel --> PlaylistScroll["Playlist scrollen"]
    Wheel --> SeekWheel["ggf. seeken"]
    MouseAPI --> Click["Mausklick"]
    Click --> RowSelect["Playlist-Row auswählen"]
    Click --> ProgressSeek["Progressbar Seek"]
    Click --> TogglePauseClick["Pause/Controls"]
    Click --> DoubleClick["Fullscreen Toggle"]

    Render --> FullscreenMode{"fullscreen?"}
    FullscreenMode -->|"Nein"| Panel
    FullscreenMode -->|"Ja"| FullscreenRender["Video randlos/groß rendern"]