/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#if SDL_AUDIO_DRIVER_HAIKU

/* Allow access to the audio stream on Haiku */

#include <SoundPlayer.h>
#include <signal.h>

#include "../../main/haiku/SDL_BeApp.h"

extern "C"
{

#include "SDL_audio.h"
#include "../SDL_audio_c.h"
#include "../SDL_sysaudio.h"
#include "SDL_haikuaudio.h"

}


/* !!! FIXME: have the callback call the higher level to avoid code dupe. */
/* The Haiku callback for handling the audio buffer */
static void
FillSound(void *device, void *stream, size_t len,
          const media_raw_audio_format & format)
{
    SDL_AudioDevice *audio = (SDL_AudioDevice *) device;

    /* Only do soemthing if audio is enabled */
    if (!SDL_AtomicGet(&audio->enabled)) {
        return;
    }

    if (!SDL_AtomicGet(&audio->paused)) {
        if (audio->convert.needed) {
            SDL_LockMutex(audio->mixer_lock);
            (*audio->spec.callback) (audio->spec.userdata,
                                     (Uint8 *) audio->convert.buf,
                                     audio->convert.len);
            SDL_UnlockMutex(audio->mixer_lock);
            SDL_ConvertAudio(&audio->convert);
            SDL_memcpy(stream, audio->convert.buf, audio->convert.len_cvt);
        } else {
            SDL_LockMutex(audio->mixer_lock);
            (*audio->spec.callback) (audio->spec.userdata,
                                     (Uint8 *) stream, len);
            SDL_UnlockMutex(audio->mixer_lock);
        }
    }
}

static void
HAIKUAUDIO_CloseDevice(_THIS)
{
    if (_this->hidden->audio_obj) {
        _this->hidden->audio_obj->Stop();
        delete _this->hidden->audio_obj;
    }
    delete _this->hidden;
}


static const int sig_list[] = {
    SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGWINCH, 0
};

static inline void
MaskSignals(sigset_t * omask)
{
    sigset_t mask;
    int i;

    sigemptyset(&mask);
    for (i = 0; sig_list[i]; ++i) {
        sigaddset(&mask, sig_list[i]);
    }
    sigprocmask(SIG_BLOCK, &mask, omask);
}

static inline void
UnmaskSignals(sigset_t * omask)
{
    sigprocmask(SIG_SETMASK, omask, NULL);
}


static int
HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    int valid_datatype = 0;
    media_raw_audio_format format;
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format);

    /* Initialize all variables that we clean on shutdown */
    _this->hidden = new SDL_PrivateAudioData;
    if (_this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_zerop(_this->hidden);

    /* Parse the audio format and fill the Be raw audio format */
    SDL_zero(format);
    format.byte_order = B_MEDIA_LITTLE_ENDIAN;
    format.frame_rate = (float) _this->spec.freq;
    format.channel_count = _this->spec.channels;        /* !!! FIXME: support > 2? */
    while ((!valid_datatype) && (test_format)) {
        valid_datatype = 1;
        _this->spec.format = test_format;
        switch (test_format) {
        case AUDIO_S8:
            format.format = media_raw_audio_format::B_AUDIO_CHAR;
            break;

        case AUDIO_U8:
            format.format = media_raw_audio_format::B_AUDIO_UCHAR;
            break;

        case AUDIO_S16LSB:
            format.format = media_raw_audio_format::B_AUDIO_SHORT;
            break;

        case AUDIO_S16MSB:
            format.format = media_raw_audio_format::B_AUDIO_SHORT;
            format.byte_order = B_MEDIA_BIG_ENDIAN;
            break;

        case AUDIO_S32LSB:
            format.format = media_raw_audio_format::B_AUDIO_INT;
            break;

        case AUDIO_S32MSB:
            format.format = media_raw_audio_format::B_AUDIO_INT;
            format.byte_order = B_MEDIA_BIG_ENDIAN;
            break;

        case AUDIO_F32LSB:
            format.format = media_raw_audio_format::B_AUDIO_FLOAT;
            break;

        case AUDIO_F32MSB:
            format.format = media_raw_audio_format::B_AUDIO_FLOAT;
            format.byte_order = B_MEDIA_BIG_ENDIAN;
            break;

        default:
            valid_datatype = 0;
            test_format = SDL_NextAudioFormat();
            break;
        }
    }

    if (!valid_datatype) {      /* shouldn't happen, but just in case... */
        return SDL_SetError("Unsupported audio format");
    }

    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&_this->spec);

    format.buffer_size = _this->spec.size;

    /* Subscribe to the audio stream (creates a new thread) */
    sigset_t omask;
    MaskSignals(&omask);
    _this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio",
                                                FillSound, NULL, _this);
    UnmaskSignals(&omask);

    if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
        _this->hidden->audio_obj->SetHasData(true);
    } else {
        return SDL_SetError("Unable to start Be audio");
    }

    /* We're running! */
    return 0;
}

static void
HAIKUAUDIO_Deinitialize(void)
{
    SDL_QuitBeApp();
}

static int
HAIKUAUDIO_Init(SDL_AudioDriverImpl * impl)
{
    /* Initialize the Be Application, if it's not already started */
    if (SDL_InitBeApp() < 0) {
        return 0;
    }

    /* Set the function pointers */
    impl->OpenDevice = HAIKUAUDIO_OpenDevice;
    impl->CloseDevice = HAIKUAUDIO_CloseDevice;
    impl->Deinitialize = HAIKUAUDIO_Deinitialize;
    impl->ProvidesOwnCallbackThread = 1;
    impl->OnlyHasDefaultOutputDevice = 1;

    return 1;   /* this audio target is available. */
}

extern "C"
{
    extern AudioBootStrap HAIKUAUDIO_bootstrap;
}
AudioBootStrap HAIKUAUDIO_bootstrap = {
    "haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, 0
};

#endif /* SDL_AUDIO_DRIVER_HAIKU */

/* vi: set ts=4 sw=4 expandtab: */
