#ifndef MPV_LOADER_H
#define MPV_LOADER_H

#include <stdint.h>
#include <stddef.h>

/* Basic mpv types (simplified to avoid mpv/client.h dependency) */
typedef struct mpv_handle mpv_handle;

typedef enum mpv_format {
    MPV_FORMAT_NONE = 0,
    MPV_FORMAT_STRING = 1,
    MPV_FORMAT_OSD_STRING = 2,
    MPV_FORMAT_FLAG = 3,
    MPV_FORMAT_INT64 = 4,
    MPV_FORMAT_DOUBLE = 5,
    MPV_FORMAT_NODE = 6,
    MPV_FORMAT_NODE_ARRAY = 7,
    MPV_FORMAT_NODE_MAP = 8,
    MPV_FORMAT_BYTE_ARRAY = 9
} mpv_format;

typedef enum mpv_event_id {
    MPV_EVENT_NONE = 0,
    MPV_EVENT_SHUTDOWN = 1,
    MPV_EVENT_LOG_MESSAGE = 2,
    MPV_EVENT_GET_PROPERTY_REPLY = 3,
    MPV_EVENT_SET_PROPERTY_REPLY = 4,
    MPV_EVENT_COMMAND_REPLY = 5,
    MPV_EVENT_START_FILE = 6,
    MPV_EVENT_END_FILE = 7,
    MPV_EVENT_FILE_LOADED = 8,
    MPV_EVENT_CLIENT_MESSAGE = 16,
    MPV_EVENT_VIDEO_RECONFIG = 17,
    MPV_EVENT_AUDIO_RECONFIG = 18,
    MPV_EVENT_SEEK = 20,
    MPV_EVENT_PLAYBACK_RESTART = 21,
    MPV_EVENT_PROPERTY_CHANGE = 22,
    MPV_EVENT_QUEUE_OVERFLOW = 24,
    MPV_EVENT_HOOK = 25
} mpv_event_id;

typedef struct mpv_event {
    mpv_event_id event_id;
    int error;
    uint64_t reply_userdata;
    void *data;
} mpv_event;

typedef struct mpv_event_property {
    const char *name;
    mpv_format format;
    void *data;
} mpv_event_property;

typedef enum mpv_end_file_reason {
    MPV_END_FILE_REASON_EOF = 0,
    MPV_END_FILE_REASON_STOP = 2,
    MPV_END_FILE_REASON_QUIT = 3,
    MPV_END_FILE_REASON_ERROR = 4,
    MPV_END_FILE_REASON_REDIRECT = 5
} mpv_end_file_reason;

typedef struct mpv_event_end_file {
    int reason;
    int error;
} mpv_event_end_file;

/* Function pointer types for mpv functions */
typedef const char *(*p_mpv_error_string)(int error);
typedef mpv_handle *(*p_mpv_create)(void);
typedef int (*p_mpv_initialize)(mpv_handle *ctx);
typedef void (*p_mpv_terminate_destroy)(mpv_handle *ctx);
typedef int (*p_mpv_set_option_string)(mpv_handle *ctx, const char *name, const char *data);
typedef void (*p_mpv_set_wakeup_callback)(mpv_handle *ctx, void (*cb)(void *d), void *d);
typedef int (*p_mpv_command_async)(mpv_handle *ctx, uint64_t reply_userdata, const char **args);
typedef int (*p_mpv_set_property_async)(mpv_handle *ctx, uint64_t reply_userdata, const char *name, mpv_format format, void *data);
typedef int (*p_mpv_set_property)(mpv_handle *ctx, const char *name, mpv_format format, void *data);
typedef int (*p_mpv_get_property)(mpv_handle *ctx, const char *name, mpv_format format, void *data);
typedef void (*p_mpv_free)(void *data);
typedef int (*p_mpv_set_property_string)(mpv_handle *ctx, const char *name, const char *data);
typedef mpv_event *(*p_mpv_wait_event)(mpv_handle *ctx, double timeout);
typedef int (*p_mpv_observe_property)(mpv_handle *mpv, uint64_t reply_userdata, const char *name, mpv_format format);
typedef int (*p_mpv_unobserve_property)(mpv_handle *mpv, uint64_t reply_userdata);
typedef const char *(*p_mpv_event_name)(mpv_event_id event);
typedef int (*p_mpv_command)(mpv_handle *ctx, const char **args);

/* Global function pointers */
extern p_mpv_error_string mpv_error_string;
extern p_mpv_create mpv_create;
extern p_mpv_initialize mpv_initialize;
extern p_mpv_terminate_destroy mpv_terminate_destroy;
extern p_mpv_set_option_string mpv_set_option_string;
extern p_mpv_set_wakeup_callback mpv_set_wakeup_callback;
extern p_mpv_command_async mpv_command_async;
extern p_mpv_command mpv_command;
extern p_mpv_set_property_async mpv_set_property_async;
extern p_mpv_set_property mpv_set_property;
extern p_mpv_get_property mpv_get_property;
extern p_mpv_free mpv_free;
extern p_mpv_set_property_string mpv_set_property_string;
extern p_mpv_wait_event mpv_wait_event;
extern p_mpv_observe_property mpv_observe_property;
extern p_mpv_unobserve_property mpv_unobserve_property;
extern p_mpv_event_name mpv_event_name;

/* Loader functions */
int load_mpv_library(void);
void unload_mpv_library(void);

#endif /* MPV_LOADER_H */
