//
// Global app state. Everything that lives across frames hangs off `app`.
//

View :: enum {
    LOGIN;
    LIBRARY;
    NOW_PLAYING;
}

App :: struct {
    // Window
    window:        Window_Type;
    window_width:  s32 = 1280;
    window_height: s32 = 800;
    quit:          bool;

    // Time
    current_time: float64;
    last_time:    float64;
    dt:           float;

    // UI
    current_view:  View = .LOGIN;
    current_theme: s32;   // index into default_theme_procs
    theme:         Overall_Theme;

    title_font:  *Simp.Dynamic_Font;
    big_font:    *Simp.Dynamic_Font;
    row_font:    *Simp.Dynamic_Font;   // sized for the artist/album/track rows
    button_font: *Simp.Dynamic_Font;
    body_font:   *Simp.Dynamic_Font;

    // Jellyfin
    jellyfin: Jellyfin_Client;

    // Audio
    audio_inited:    bool;
    current_stream:  *Sound.Sound_Stream;
    current_track:   Track;
    current_format:  Audio_Format;   // format of the bytes we played
    track_finished:  bool;            // set by Sound_Player release_asset callback
    track_entity_id: s64;             // monotonic — identifies the active stream

    paused:          bool;            // real pause: stream's current_rate is 0 while true
    master_volume:   float = 1.0;     // 0..1; persisted in config.json
    scrub_seconds:   float;           // bound to the seek slider in now_playing_view

    // Per-frame audio analysis used by the visualizer shader.
    spectrum: [SPECTRUM_BINS] float;

    // Separate OGG decoder kept open for the visualizer FFT. Sound_Player's
    // OGG_COMPRESSED type gives no PCM access, so we maintain our own handle.
    analysis_vorbis: *void;   // *Stb_Vorbis.stb_vorbis, void to avoid header dep
    analysis_ogg:    string;  // copy of OGG bytes kept alive for the decoder

    // Cover art palette — extracted once per album, used for theming.
    palette:          [4] Vector4;   // [0]=bg  [1]=highlight  [2]=mid  [3]=accent
    palette_ready:    bool;
    palette_album_id: string;

    // Library browse state.
    library: Library_State;
}

SPECTRUM_BINS :: 64;

app: App;

app_init :: () {
    log_info("player starting up");

    setup_data_directory();

    app.window = create_window(app.window_width, app.window_height, "Celica");
    Simp.set_render_target(app.window, .LEFT_HANDED);

    init_fonts();
    ui_init();

    sound_cfg: Sound.Sound_Player_Config;
    sound_cfg.release_asset = sound_release_callback;
    if Sound.sound_player_init(sound_cfg) {
        app.audio_inited = true;
    } else {
        log_warn("sound player init failed — playback disabled");
    }

    jellyfin_client_init(*app.jellyfin);

    gfx_init();
    image_cache_init();

    // Sensible defaults; config_load may overwrite.
    app.jellyfin.server_url = copy_string("http://localhost:8096");
    app.jellyfin.username   = copy_string("");
    app.jellyfin.password   = copy_string("");

    if config_load() {
        app.current_view = .LIBRARY;
        library_refresh_artists();
    }
}

app_shutdown :: () {
    if app.audio_inited  Sound.sound_player_shutdown();
    jellyfin_client_shutdown(*app.jellyfin);
    log_info("bye");
}
