#ifndef SPEAKER_H
#define SPEAKER_H

#include <stdint.h>
#include <stdlib.h>
#include <string>
#include <cstring>
#include <vector>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "driver/i2s_std.h"
#include "driver/gpio.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "sd.h"

#define SPEAKER_PIN_BCLK  GPIO_NUM_11
#define SPEAKER_PIN_WS    GPIO_NUM_12
#define SPEAKER_PIN_DOUT  GPIO_NUM_3
#define SAMPLE_RATE 44100
// The maximum number of clips that can be queued at one time.
#define CLIP_QUEUE_SIZE 64

extern i2s_chan_handle_t tx_chan;

typedef struct {
    /// A dynamically allocated string specifying the name of the
    /// file to play. The speaker system will free this once it
    /// is done.
    char* file_name;
    /// A number that all samples will be shifted right by.
    uint8_t prescaler;
    /// A flag for repeating.
    bool repeat;
    /// A flag for starting the clip immediatly,
    /// even if there is another clip playing.
    bool play_immediatly;
} audio_clip_t;

/// @brief Initalizes the speaker
void init_speaker();

/// @brief Plays a wav audio clip.
/// @param file_name The name of the file to play. Fully qualified with the `.wav` extention.
/// @param play_immediatly If `true`, the file will play immediatly even if there is already 
///  another clip being played. The two clips will play simultaniously. If `false` the clip
///  will play once all the previous clips have finished.
/// @param repeat If `true` the clip will repeat until stopped. If `false` the clip will
///  stop when finished.
/// @param prescaler A number to shift right all samples by. This makes the music half as
///  loud. Useful for loud audio files.
/// @param ticks_to_wait The number of ticks to wait if the queue is full.
/// @return true if the clip was added to the queue.
bool play_clip_wav(const char* file_name, bool play_immediately, bool repeat, uint8_t prescaler, TickType_t ticks_to_wait);

/// @brief Stops an audio clip from playing.
/// @param file_name The file name of the audio clip that was played.
/// @param ticks_to_wait The number of ticks to wait if the queue is full.
/// @return true if the clip was added to the queue.
bool stop_clip(const char* file_name, TickType_t ticks_to_wait);

#endif /* SPEAKER_H */