#ifndef PLAYER_H
#define PLAYER_H

#include <glib.h>
#include "mpv_loader.h"

typedef struct Player Player;

/* Callback types */
typedef void (*PlayerEventCallback)(Player *player, mpv_event *event, gpointer user_data);

/* Lifecycle */
Player* player_new(void);
void player_destroy(Player *player);
void player_set_window(Player *player, unsigned long wid);
void player_set_config_path(Player *player, const char *path);
int player_init(Player *player);

/* Playback commands */
void player_load_file(Player *player, const char *path, gboolean append);
void player_play(Player *player);
void player_pause(Player *player);
void player_toggle_pause(Player *player);
void player_stop(Player *player);
void player_seek(Player *player, double seconds);
void player_seek_absolute(Player *player, double position);
void player_frame_step(Player *player);
void player_frame_back_step(Player *player);

/* Options */
void player_set_option_string(Player *player, const char *name, const char *value);
void player_set_option_flag(Player *player, const char *name, int value);

/* Property getters */
double player_get_duration(Player *player);
double player_get_position(Player *player);
double player_get_volume(Player *player);
gboolean player_get_paused(Player *player);
gboolean player_get_muted(Player *player);
double player_get_speed(Player *player);
char* player_get_media_title(Player *player);
char* player_get_filename(Player *player);
gboolean player_get_eof_reached(Player *player);
gboolean player_is_idle(Player *player);
char* player_get_metadata_tag(Player *player, const char *tag);
gboolean player_get_shuffle(Player *player);
gboolean player_get_loop(Player *player);

/* Property setters */
void player_set_volume_boost(Player *player, gboolean enable);
void player_set_volume(Player *player, double volume);
void player_set_muted(Player *player, gboolean muted);
void player_set_speed(Player *player, double speed);

/* Track management */
int player_get_audio_track_count(Player *player);
int player_get_subtitle_track_count(Player *player);
int player_get_current_audio_track(Player *player);
int player_get_current_subtitle_track(Player *player);
void player_set_audio_track(Player *player, int track);
void player_set_subtitle_track(Player *player, int track);
void player_load_subtitle(Player *player, const char *path);

/* Audio/Video info */
char** player_get_audio_track_list(Player *player, int *count);
void player_get_video_resolution(Player *player, int *w, int *h);
char** player_get_subtitle_track_list(Player *player, int *count);
void player_free_track_list(char **list, int count);

/* Chapters */
int player_get_chapter_count(Player *player);
int player_get_current_chapter(Player *player);
void player_set_chapter(Player *player, int index);
char** player_get_chapter_list(Player *player, int *count);
double* player_get_chapter_times(Player *player, int *count);
void player_next_chapter(Player *player);
void player_prev_chapter(Player *player);

/* Playlist (internal mpv playlist) */
int player_get_playlist_count(Player *player);
int player_get_playlist_pos(Player *player);
void player_playlist_next(Player *player);
void player_playlist_prev(Player *player);
void player_playlist_play_index(Player *player, int index);
void player_playlist_remove(Player *player, int index);
void player_playlist_move(Player *player, int from, int to);
void player_playlist_clear(Player *player);
void player_playlist_shuffle(Player *player);
void player_set_shuffle(Player *player, gboolean shuffle);
void player_set_loop(Player *player, gboolean loop);

/* A-B Loop */
void player_set_ab_loop_a(Player *player);
void player_set_ab_loop_b(Player *player);
void player_clear_ab_loop(Player *player);
double player_get_ab_loop_a(Player *player);
double player_get_ab_loop_b(Player *player);

/* Screenshot */
void player_screenshot(Player *player);
void player_screenshot_to_file(Player *player, const char *path);

/* Aspect ratio */
void player_set_aspect_ratio(Player *player, const char *aspect);

/* Event handling */
void player_set_event_callback(Player *player, PlayerEventCallback callback, gpointer user_data);
gboolean player_process_events(gpointer player);
mpv_handle* player_get_mpv_handle(Player *player);

/* Property observation */
void player_observe_property(Player *player, const char *name, mpv_format format, guint64 reply_userdata);
void player_unobserve_property(Player *player, guint64 reply_userdata);

/* Script management */
void player_load_script(Player *player, const char *path);

#endif /* PLAYER_H */
