/**
 * @file audiotypes.h
 * @brief Decoders.
 *
 * Supported Audio types. Built-in are miniaudios supported audio types flac, mp3 and wav.
 */

#ifndef AUDIOTYPES_H
#define AUDIOTYPES_H

#include "loader/songdatatype.h"

#include <miniaudio.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stdint.h>
#include <pthread.h>

typedef enum {
        SOUND_STATE_STOPPED = 0,
        SOUND_STATE_PLAYING,
        SOUND_STATE_PAUSED
} sound_playback_state_t;

typedef enum {
        SOUND_STATE_REPEAT_OFF = 0,
        SOUND_STATE_REPEAT,
        SOUND_STATE_REPEAT_LIST
} sound_playback_repeat_state_t;

struct sound_system {
        void *decoder;
        ma_device *device;

        bool audio_thread_priority_set;
        int replay_gain_check_first; // 0 = track, 1 = album, 2 = disabled
        float gain_linear;

        ma_uint32 channels;
        ma_uint32 sample_rate;
        ma_format format;

        atomic_bool request_pause;
        atomic_int drain_callbacks_remaining;

        ma_uint64 current_frame;
        ma_uint64 total_frames;
        ma_uint64 total_song_frames;

        ma_uint32 avg_bit_rate;

        SongData *songdataA;
        SongData *songdataB;

        ma_uint32 chunk_frames;
        pthread_t decode_thread;

#ifndef __cplusplus
        atomic_llong track_frames_sent;
        atomic_llong track_end_frame;
        atomic_llong fade_boundary;
        atomic_bool end_of_list_reached;
        atomic_bool decode_thread_running;
        atomic_bool decode_finished;
        atomic_bool request_switch_metadata;
        atomic_bool request_switch_decoder;
        atomic_bool buffer_ready;
        atomic_bool using_song_slot_A;
        atomic_bool clock_reset_done;
        atomic_bool fade_boundary_reached;
        atomic_int clock_reset_ms;
#endif

        float volume;
        sound_playback_state_t state;

        int ring_buffer_secs;

        bool always_fade;
        int always_fade_ms;
        bool fade_allowed;
        bool fade_requested;
        bool fade_seek_performed;
        int fade_ms;
        int fade_enter_song_ms;
        ma_uint64 fade_enter_frame;
        ma_uint64 fade_current_frame;
        ma_uint64 fade_total_frames;
        ma_uint64 fade_frames;

        pthread_mutex_t decoder_mutex;
        pthread_cond_t  decoder_cond;
};

enum decoder_type_t {
        PCM,
        BUILTIN,
        VORBIS,
        OPUS,
        M4A,
        WEBM,
        NONE
};

typedef enum {
        k_unknown = 0,
        k_aac = 1,
        k_rawAAC = 2, // Raw aac (.aac file) decoding is included here for convenience although they are not .m4a files
        k_ALAC = 3,
        k_FLAC = 4
} k_m4adec_filetype;

struct m4a_decoder;
typedef struct m4a_decoder ma_m4a;

#endif
