#ifdef WITH_RIVE_AUDIO
#ifndef _RIVE_AUDIO_SOUND_HPP_
#define _RIVE_AUDIO_SOUND_HPP_

#include "miniaudio.h"
#include "rive/refcnt.hpp"
#include "rive/audio/audio_source.hpp"

namespace rive
{
class AudioEngine;
class Artboard;

struct ma_end_clipped_decoder
{
    ma_data_source_base base;
    ma_decoder decoder;
    ma_uint64 frameCursor;
    ma_uint64 endFrame;
};

static ma_result ma_end_clipped_decoder_read(ma_data_source* pDataSource,
                                             void* pFramesOut,
                                             ma_uint64 frameCount,
                                             ma_uint64* pFramesRead)
{
    ma_end_clipped_decoder* clipped = (ma_end_clipped_decoder*)pDataSource;

    ma_result result = ma_decoder_read_pcm_frames(&clipped->decoder,
                                                  pFramesOut,
                                                  frameCount,
                                                  pFramesRead);

    clipped->frameCursor += *pFramesRead;
    if (clipped->frameCursor >= clipped->endFrame)
    {
        ma_uint64 overflow = clipped->frameCursor - clipped->endFrame;
        if (*pFramesRead > overflow)
        {
            *pFramesRead -= overflow;
        }
        else
        {
            *pFramesRead = 0;
            return MA_AT_END;
        }
    }

    return result;
}

static ma_result ma_end_clipped_decoder_seek(ma_data_source* pDataSource,
                                             ma_uint64 frameIndex)
{
    ma_end_clipped_decoder* clipped = (ma_end_clipped_decoder*)pDataSource;
    ma_result result =
        ma_decoder_seek_to_pcm_frame(&clipped->decoder, frameIndex);
    if (result != MA_SUCCESS)
    {
        return result;
    }

    clipped->frameCursor = frameIndex;
    return result;
}

static ma_result ma_end_clipped_decoder_get_data_format(
    ma_data_source* pDataSource,
    ma_format* pFormat,
    ma_uint32* pChannels,
    ma_uint32* pSampleRate,
    ma_channel* pChannelMap,
    size_t channelMapCap)
{
    ma_end_clipped_decoder* clipped = (ma_end_clipped_decoder*)pDataSource;
    return ma_decoder_get_data_format(&clipped->decoder,
                                      pFormat,
                                      pChannels,
                                      pSampleRate,
                                      pChannelMap,
                                      channelMapCap);
}

static ma_result ma_end_clipped_decoder_get_cursor(ma_data_source* pDataSource,
                                                   ma_uint64* pCursor)
{
    ma_end_clipped_decoder* clipped = (ma_end_clipped_decoder*)pDataSource;
    *pCursor = clipped->frameCursor;
    return MA_SUCCESS;
}

static ma_result ma_end_clipped_decoder_get_length(ma_data_source* pDataSource,
                                                   ma_uint64* pLength)
{
    ma_end_clipped_decoder* clipped = (ma_end_clipped_decoder*)pDataSource;
    return ma_decoder_get_length_in_pcm_frames(&clipped->decoder, pLength);
}

static ma_data_source_vtable g_ma_end_clipped_decoder_vtable = {
    ma_end_clipped_decoder_read,
    ma_end_clipped_decoder_seek,
    ma_end_clipped_decoder_get_data_format,
    ma_end_clipped_decoder_get_cursor,
    ma_end_clipped_decoder_get_length};

class AudioSound : public RefCnt<AudioSound>
{
    friend class AudioEngine;

public:
    bool seek(uint64_t timeInFrames);
    bool seekSeconds(float timeInSeconds);
    uint64_t timeInFrames();
    float timeInSeconds();
    ~AudioSound();
    void stop(uint64_t fadeTimeInFrames = 0);
    void play();
    void pause();
    void resume();
    float volume();
    void volume(float value);
    bool completed() const;

private:
    AudioSound(AudioEngine* engine,
               rcp<AudioSource> source,
               Artboard* artboard);
    ma_end_clipped_decoder* clippedDecoder() { return &m_decoder; }
    ma_audio_buffer* buffer() { return &m_buffer; }
    ma_sound* sound() { return &m_sound; }
    void dispose();

    ma_end_clipped_decoder m_decoder;
    ma_audio_buffer m_buffer;
    ma_sound m_sound;
    rcp<AudioSource> m_source;

    // This is storage used by the AudioEngine.
    bool m_isDisposed;
    rcp<AudioSound> m_nextPlaying;
    rcp<AudioSound> m_prevPlaying;
    AudioEngine* m_engine;
    Artboard* m_artboard;
};
} // namespace rive

#endif
#endif