#include "./audio.hpp"
#include "../core.hpp"

#include <sndfile.h>

#include <alsa/asoundlib.h>
#include <alsa/pcm.h>

static snd_pcm_t* device;

namespace polygun::audio {

    void configure_device(snd_pcm_t* pcm, unsigned int channels, unsigned int rate)
    {
        snd_pcm_hw_params_t *hw_params;
        snd_pcm_hw_params_alloca(&hw_params);

        snd_pcm_hw_params_any(pcm, hw_params);
        snd_pcm_hw_params_set_access(pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
        snd_pcm_hw_params_set_format(pcm, hw_params, SND_PCM_FORMAT_S16_LE);
        snd_pcm_hw_params_set_channels(pcm, hw_params, channels);
        snd_pcm_hw_params_set_rate(pcm, hw_params, rate, 0);

        snd_pcm_hw_params(pcm, hw_params);
    }

    void init() {
        // Open device
        snd_pcm_open(&device, "default", SND_PCM_STREAM_PLAYBACK, 0);
    }

    void _play_sound_thread(std::string filename) {   
        auto sfinfo = SF_INFO {};
        auto file = sf_open(filename.c_str(), SFM_READ, &sfinfo);

        if (file == NULL) {
            std::cout << "Couldn't open the file \"" << filename << "\"" << std::endl;
            return;
        }

        auto sound_buf = (short*)malloc(sfinfo.frames * sfinfo.channels * sizeof(short));
        auto frames = sf_readf_short(file, sound_buf, sfinfo.frames);

        configure_device(device, sfinfo.channels, sfinfo.samplerate);
        snd_pcm_writei(device, sound_buf, frames);

        free(sound_buf);
        sf_close(file);
    }

    void play_sound(std::string filename) {
        std::thread play(_play_sound_thread, filename);
        play.join();
    }

}