#ifdef TARGET_WII

#include <asndlib.h>
#include <gccore.h>
#include "macros.h"
#include "audio_api.h"

// Number of buffers
#define WII_DSP_DMA_BUFFER_COUNT   4

static int sNextBuffer;
static ndspWaveBuf sDspBuffers[WII_DSP_DMA_BUFFER_COUNT];

static bool audio_wii_init(void)
{
    ASND_Init();
    ASND_Pause(0);

    ndspSetOutputMode(NDSP_OUTPUT_STEREO);
    ndspChnReset(0);
    ndspChnWaveBufClear(0);
    ndspChnSetInterp(0, NDSP_INTERP_LINEAR);
    ndspChnSetRate(0, 32000);
    ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16);

    float mix[12];
    memset(mix, 0, sizeof(mix));
    mix[0] = 1.0;
    mix[1] = 1.0;
    ndspChnSetMix(0, mix);

    u8 *bufferData = linearAlloc(4096 * 4 * WII_DSP_DMA_BUFFER_COUNT);
    for (int i = 0; i < WII_DSP_DMA_BUFFER_COUNT; i++) {
        sDspBuffers[i].data_vaddr = &bufferData[i * 4096 * 4];
        sDspBuffers[i].nsamples = 0;
        sDspBuffers[i].status = NDSP_WBUF_FREE;
    }

    sNextBuffer = 0;

    return true;
}

static int audio_wii_buffered(void)
{
    int total = 0;
    for (int i = 0; i < WII_DSP_DMA_BUFFER_COUNT; i++)
    {
        if (sDspBuffers[i].status == NDSP_WBUF_QUEUED || 
            sDspBuffers[i].status == NDSP_WBUF_PLAYING)
            total += sDspBuffers[i].nsamples;
    }
    return total;
}

static int audio_wii_get_desired_buffered(void)
{
    return 1100;
}

static void audio_wii_play(const uint8_t *buf, size_t len)
{
    if (len > 4096 * 4)
        return;
    if (sDspBuffers[sNextBuffer].status != NDSP_WBUF_FREE &&
        sDspBuffers[sNextBuffer].status != NDSP_WBUF_DONE)
        return;
    s16* dst = (s16*)sDspBuffers[sNextBuffer].data_vaddr;
    memcpy(dst, buf, len);
    DSP_FlushDataCache(dst, len);
    sDspBuffers[sNextBuffer].nsamples = len / 4;
    sDspBuffers[sNextBuffer].status = NDSP_WBUF_FREE;
    ndspChnWaveBufAdd(0, &sDspBuffers[sNextBuffer]);
    sNextBuffer = (sNextBuffer + 1) % WII_DSP_DMA_BUFFER_COUNT;
}

struct AudioAPI audio_wii = 
{ 
    audio_wii_init, 
    audio_wii_buffered, 
    audio_wii_get_desired_buffered,
    audio_wii_play
};

#endif