#pragma once
#include <stdint.h>

typedef struct MprisPlayer MprisPlayer;

typedef void     (*MprisCallback)            (void *userdata);
typedef void     (*MprisSeekCallback)        (int64_t offset_us, void *userdata);
typedef void     (*MprisSetPositionCallback) (const char *track_id, int64_t position_us, void *userdata);
typedef void     (*MprisVolumeCallback)      (double volume, void *userdata);

// Creates the player and acquires "org.mpris.MediaPlayer2.<player_name>" on the session bus.
// identity is the human-readable name shown in media menus.
// Returns NULL on failure.
MprisPlayer *mpris_player_create(const char *player_name, const char *identity);
void         mpris_player_destroy(MprisPlayer *p);

// Update state (each setter emits PropertiesChanged so media menus update immediately).
// status must be one of: "Playing", "Paused", "Stopped"
void mpris_set_playback_status(MprisPlayer *p, const char *status);

// Pass NULL for any field you don't have. length_us is track duration in microseconds.
void mpris_set_metadata(MprisPlayer *p, const char *track_id, const char *title,
                        const char *artist, const char *album, int64_t length_us);

// position_us is the current playback position; not broadcast automatically,
// only reported when polled. Call mpris_emit_seeked() after an actual seek.
void mpris_set_position(MprisPlayer *p, int64_t position_us);

void mpris_set_volume      (MprisPlayer *p, double volume);
void mpris_set_can_go_next    (MprisPlayer *p, int value);
void mpris_set_can_go_previous(MprisPlayer *p, int value);
void mpris_set_can_play    (MprisPlayer *p, int value);
void mpris_set_can_pause   (MprisPlayer *p, int value);
void mpris_set_can_seek    (MprisPlayer *p, int value);

// Emit the Seeked signal after a seek completes.
void mpris_emit_seeked(MprisPlayer *p, int64_t position_us);

// Register callbacks for incoming control commands.
// userdata is passed through unchanged to your callback.
void mpris_on_play        (MprisPlayer *p, MprisCallback cb,            void *userdata);
void mpris_on_pause       (MprisPlayer *p, MprisCallback cb,            void *userdata);
void mpris_on_play_pause  (MprisPlayer *p, MprisCallback cb,            void *userdata);
void mpris_on_stop        (MprisPlayer *p, MprisCallback cb,            void *userdata);
void mpris_on_next        (MprisPlayer *p, MprisCallback cb,            void *userdata);
void mpris_on_previous    (MprisPlayer *p, MprisCallback cb,            void *userdata);
void mpris_on_seek        (MprisPlayer *p, MprisSeekCallback cb,        void *userdata);
void mpris_on_set_position(MprisPlayer *p, MprisSetPositionCallback cb, void *userdata);
// Called when a remote client changes the Volume property.
void mpris_on_volume      (MprisPlayer *p, MprisVolumeCallback cb,      void *userdata);

// Drive the D-Bus event loop. Call this every frame / in your event loop.
// Returns >0 if messages were processed, 0 if idle, <0 on error.
int mpris_process(MprisPlayer *p);
