#ifndef REMISID_H
#define REMISID_H

#include <stdint.h>

#ifdef __cplusplus
  #define REMI_EXTERN_C extern "C"
#else
  #define REMI_EXTERN_C
#endif

typedef void* PSidplayfp;
typedef void* PReSIDfpBuilder;
typedef void* PSidTune;
typedef void* PSidTuneInfo;
typedef void* PSidConfig;

REMI_EXTERN_C PSidplayfp sidplayfp_new(void);
REMI_EXTERN_C void sidplayfp_free(PSidplayfp ctx);
REMI_EXTERN_C void sidplayfp_setroms(PSidplayfp ctx, const uint8_t* kernal, const uint8_t* basic, const uint8_t* character);
REMI_EXTERN_C void sidplayfp_setKernal(PSidplayfp ctx, const uint8_t* rom);
REMI_EXTERN_C void sidplayfp_setBasic(PSidplayfp ctx, const uint8_t* rom);
REMI_EXTERN_C void sidplayfp_setChargen(PSidplayfp ctx, const uint8_t* rom);
REMI_EXTERN_C const char* sidplayfp_info_name(PSidplayfp ctx);
REMI_EXTERN_C const char* sidplayfp_info_version(PSidplayfp ctx);
REMI_EXTERN_C unsigned int sidplayfp_info_numberOfCredits(PSidplayfp ctx);
REMI_EXTERN_C unsigned int sidplayfp_info_maxsids(PSidplayfp ctx);
REMI_EXTERN_C unsigned int sidplayfp_info_channels(PSidplayfp ctx);
REMI_EXTERN_C uint16_t sidplayfp_info_driverAddr(PSidplayfp ctx);
REMI_EXTERN_C uint16_t sidplayfp_info_driverLength(PSidplayfp ctx);
REMI_EXTERN_C uint16_t sidplayfp_info_powerOnDelay(PSidplayfp ctx);
REMI_EXTERN_C const char* sidplayfp_info_speedString(PSidplayfp ctx);
REMI_EXTERN_C const char* sidplayfp_info_kernalDesc(PSidplayfp ctx);
REMI_EXTERN_C const char* sidplayfp_info_basicDesc(PSidplayfp ctx);
REMI_EXTERN_C const char* sidplayfp_info_chargenDesc(PSidplayfp ctx);
REMI_EXTERN_C bool sidplayfp_load(PSidplayfp ctx, PSidTune tune);
REMI_EXTERN_C uint_least32_t sidplayfp_play(PSidplayfp ctx, short* buffer, uint_least32_t count);
REMI_EXTERN_C bool sidplayfp_isPlaying(PSidplayfp ctx);
REMI_EXTERN_C void sidplayfp_stop(PSidplayfp ctx);
REMI_EXTERN_C uint_least32_t sidplayfp_time(PSidplayfp ctx);
REMI_EXTERN_C const char* sidplayfp_error(PSidplayfp ctx);

REMI_EXTERN_C PReSIDfpBuilder reisidfpbuilder_new(const char* name);
REMI_EXTERN_C const char* residfpbuilder_name(PReSIDfpBuilder ctx);
REMI_EXTERN_C const char* residfpbuilder_credits(PReSIDfpBuilder ctx);
REMI_EXTERN_C unsigned int residfpbuilder_create(PReSIDfpBuilder ctx, unsigned int sids);
REMI_EXTERN_C unsigned int residfpbuilder_usedDevices(PReSIDfpBuilder ctx);
REMI_EXTERN_C unsigned int residfpbuilder_availDevices(PReSIDfpBuilder ctx);
REMI_EXTERN_C bool residfpbuilder_getStatus(PReSIDfpBuilder ctx);
REMI_EXTERN_C const char* residfpbuilder_error(PReSIDfpBuilder ctx);
REMI_EXTERN_C void residfpbuilder_free(PReSIDfpBuilder ctx);

REMI_EXTERN_C PSidTune sidtune_new(const char* path, const char** filenameExt, int separatorIsSlash);
REMI_EXTERN_C PSidTune sidtune_new_from_mem(const uint_least8_t* mem, uint_least32_t sidtuneLength);
REMI_EXTERN_C bool sidtune_getStatus(PSidTune tune);
REMI_EXTERN_C PSidTuneInfo sidtune_getInfo(PSidTune tune);
REMI_EXTERN_C const char* sidtune_statusString(PSidTune tune);
REMI_EXTERN_C unsigned int sidtune_selectSong(PSidTune tune, unsigned int songNum);
REMI_EXTERN_C const char* sidtune_createMD5(PSidTune tune, char* buf);
REMI_EXTERN_C void sidtune_free(PSidTune tune);

REMI_EXTERN_C unsigned int sidtuneinfo_songs(PSidTuneInfo info);
REMI_EXTERN_C unsigned int sidtuneinfo_startSong(PSidTuneInfo info);
REMI_EXTERN_C unsigned int sidtuneinfo_currentSong(PSidTuneInfo info);
REMI_EXTERN_C int sidtuneinfo_sidChips(PSidTuneInfo info);
REMI_EXTERN_C int sidtuneinfo_songSpeed(PSidTuneInfo info);
REMI_EXTERN_C int sidtuneinfo_sidModel(PSidTuneInfo info, unsigned int num);
REMI_EXTERN_C int sidtuneinfo_compatibility(PSidTuneInfo info);
REMI_EXTERN_C int sidtuneinfo_numberOfInfoStrings(PSidTuneInfo info);
REMI_EXTERN_C const char* sidtuneinfo_infoString(PSidTuneInfo info, unsigned int num);
REMI_EXTERN_C int sidtuneinfo_numberOfCommentStrings(PSidTuneInfo info);
REMI_EXTERN_C const char* sidtuneinfo_commentString(PSidTuneInfo info, unsigned int num);
REMI_EXTERN_C int sidtuneinfo_clockSpeed(PSidTuneInfo info);
REMI_EXTERN_C const char* sidtuneinfo_formatString(PSidTuneInfo info);

REMI_EXTERN_C PSidConfig sidconfig_new(void);
REMI_EXTERN_C SidConfig::c64_model_t sidconfig_defaultC64Model(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_defaultC64Model(PSidConfig cfg, SidConfig::c64_model_t model);
REMI_EXTERN_C SidConfig::c64_model_t sidconfig_defaultC64Model(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_defaultC64Model(PSidConfig cfg, SidConfig::c64_model_t model);
REMI_EXTERN_C bool sidconfig_forceC64Model(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_forceC64Model(PSidConfig cfg, bool value);
REMI_EXTERN_C SidConfig::sid_model_t sidconfig_defaultSidModel(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_defaultSidModel(PSidConfig cfg, SidConfig::sid_model_t value);
REMI_EXTERN_C bool sidconfig_forceSidModel(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_forceSidModel(PSidConfig cfg, bool value);
REMI_EXTERN_C SidConfig::playback_t sidconfig_playback(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_playback(PSidConfig cfg, SidConfig::playback_t value);
REMI_EXTERN_C uint_least32_t sidconfig_frequency(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_frequency(PSidConfig cfg, uint_least32_t value);
REMI_EXTERN_C uint_least16_t sidconfig_secondSidAddress(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_secondSidAddress(PSidConfig cfg, uint_least16_t value);
REMI_EXTERN_C uint_least16_t sidconfig_thirdSidAddress(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_thirdSidAddress(PSidConfig cfg, uint_least16_t value);
REMI_EXTERN_C sidbuilder* sidconfig_sidEmulation(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_sidEmulation(PSidConfig cfg, sidbuilder* value);
REMI_EXTERN_C uint_least32_t sidconfig_leftVolume(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_leftVolume(PSidConfig cfg, uint_least32_t value);
REMI_EXTERN_C uint_least32_t sidconfig_rightVolume(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_rightVolume(PSidConfig cfg, uint_least32_t value);
REMI_EXTERN_C uint_least16_t sidconfig_powerOnDelay(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_powerOnDelay(PSidConfig cfg, uint_least16_t value);
REMI_EXTERN_C SidConfig::sampling_method_t sidconfig_samplingMethod(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_samplingMethod(PSidConfig cfg, SidConfig::sampling_method_t value);
REMI_EXTERN_C bool sidconfig_fastSampling(PSidConfig cfg);
REMI_EXTERN_C void sidconfig_set_fastSampling(PSidConfig cfg, bool value);
REMI_EXTERN_C bool sidconfig_apply_to_sidplayfp(PSidConfig cfg, PSidplayfp engine);

REMI_EXTERN_C void sidconfig_free(PSidConfig cfg);

#endif
