/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2021 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_OS2

/* Allow access to a raw mixing buffer */

#include "../../core/os2/SDL_os2.h"

#include "SDL_audio.h"
#include "../SDL_audio_c.h"
#include "SDL_os2audio.h"

/*
void lockIncr(volatile int *piVal);
#pragma aux lockIncr = \
  "lock add [eax], 1 "\
  parm [eax];

void lockDecr(volatile int *piVal);
#pragma aux lockDecr = \
  "lock sub [eax], 1 "\
  parm [eax];
*/

static ULONG _getEnvULong(const char *name, ULONG ulMax, ULONG ulDefault)
{
    ULONG   ulValue;
    char*   end;
    char*   envval = SDL_getenv(name);

    if (envval == NULL)
        return ulDefault;

    ulValue = SDL_strtoul(envval, &end, 10);
    return (end == envval) || (ulValue > ulMax)? ulDefault : ulMax;
}

static int _MCIError(const char *func, ULONG ulResult)
{
    CHAR    acBuf[128];
    mciGetErrorString(ulResult, acBuf, sizeof(acBuf));
    return SDL_SetError("[%s] %s", func, acBuf);
}

static void _mixIOError(const char *function, ULONG ulRC)
{
    debug_os2("%s() - failed, rc = 0x%X (%s)",
              function, ulRC,
              (ulRC == MCIERR_INVALID_MODE)   ? "Mixer mode does not match request" :
              (ulRC == MCIERR_INVALID_BUFFER) ? "Caller sent an invalid buffer"     : "unknown");
}

static LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
                                       ULONG ulFlags)
{
    SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm;
    ULONG   ulRC;

    if (ulFlags != MIX_WRITE_COMPLETE) {
        debug_os2("flags = 0x%X", ulFlags);
        return 0;
    }

    /*lockDecr((int *)&pAData->ulQueuedBuf);*/
    ulRC = DosPostEventSem(pAData->hevBuf);
    if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
        debug_os2("DosPostEventSem(), rc = %u", ulRC);
    }

    return 1; /* It seems, return value is not matter. */
}

static LONG APIENTRY cbAudioReadEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
                                      ULONG ulFlags)
{
    SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm;
    ULONG   ulRC;

    if (ulFlags != MIX_READ_COMPLETE) {
        debug_os2("flags = 0x%X", ulFlags);
        return 0;
    }

    pAData->stMCIMixSetup.pmixRead(pAData->stMCIMixSetup.ulMixHandle, pBuffer, 1);

    ulRC = DosPostEventSem(pAData->hevBuf);
    if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
        debug_os2("DosPostEventSem(), rc = %u", ulRC);
    }

    return 1;
}


static void OS2_DetectDevices(void)
{
    MCI_SYSINFO_PARMS       stMCISysInfo;
    CHAR                    acBuf[256];
    ULONG                   ulDevicesNum;
    MCI_SYSINFO_LOGDEVICE   stLogDevice;
    MCI_SYSINFO_PARMS       stSysInfoParams;
    ULONG                   ulRC;
    ULONG                   ulHandle = 0;

    acBuf[0] = '\0';
    stMCISysInfo.pszReturn    = acBuf;
    stMCISysInfo.ulRetSize    = sizeof(acBuf);
    stMCISysInfo.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
    ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_QUANTITY,
                          &stMCISysInfo, 0);
    if (ulRC != NO_ERROR) {
        debug_os2("MCI_SYSINFO, MCI_SYSINFO_QUANTITY - failed, rc = 0x%X", ulRC);
        return;
    }

    ulDevicesNum = atol(stMCISysInfo.pszReturn);

    for (stSysInfoParams.ulNumber = 0; stSysInfoParams.ulNumber < ulDevicesNum;
         stSysInfoParams.ulNumber++) {
        /* Get device install name. */
        stSysInfoParams.pszReturn    = acBuf;
        stSysInfoParams.ulRetSize    = sizeof(acBuf);
        stSysInfoParams.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
        ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_INSTALLNAME,
                              &stSysInfoParams, 0);
        if (ulRC != NO_ERROR) {
            debug_os2("MCI_SYSINFO, MCI_SYSINFO_INSTALLNAME - failed, rc = 0x%X", ulRC);
            continue;
        }

        /* Get textual product description. */
        stSysInfoParams.ulItem = MCI_SYSINFO_QUERY_DRIVER;
        stSysInfoParams.pSysInfoParm = &stLogDevice;
        strcpy(stLogDevice.szInstallName, stSysInfoParams.pszReturn);
        ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_ITEM,
                              &stSysInfoParams, 0);
        if (ulRC != NO_ERROR) {
            debug_os2("MCI_SYSINFO, MCI_SYSINFO_ITEM - failed, rc = 0x%X", ulRC);
            continue;
        }

        ulHandle++;
        SDL_AddAudioDevice(0, stLogDevice.szProductInfo, (void *)(ulHandle));
        ulHandle++;
        SDL_AddAudioDevice(1, stLogDevice.szProductInfo, (void *)(ulHandle));
    }
}

static void OS2_WaitDevice(_THIS)
{
    SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
    ULONG   ulRC;

    /* Wait for an audio chunk to finish */
    ulRC = DosWaitEventSem(pAData->hevBuf, 5000);
    if (ulRC != NO_ERROR) {
        debug_os2("DosWaitEventSem(), rc = %u", ulRC);
    }
}

static Uint8 *OS2_GetDeviceBuf(_THIS)
{
    SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
    return (Uint8 *) pAData->aMixBuffers[pAData->ulNextBuf].pBuffer;
}

static void OS2_PlayDevice(_THIS)
{
    SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
    ULONG                 ulRC;
    PMCI_MIX_BUFFER       pMixBuffer = &pAData->aMixBuffers[pAData->ulNextBuf];

    /* Queue it up */
    /*lockIncr((int *)&pAData->ulQueuedBuf);*/
    ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
                                           pMixBuffer, 1);
    if (ulRC != MCIERR_SUCCESS) {
        _mixIOError("pmixWrite", ulRC);
    } else {
        pAData->ulNextBuf = (pAData->ulNextBuf + 1) % pAData->cMixBuffers;
    }
}

static void OS2_CloseDevice(_THIS)
{
    SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
    MCI_GENERIC_PARMS     sMCIGenericParms;
    ULONG                 ulRC;

    if (pAData == NULL)
        return;

    /* Close up audio */
    if (pAData->usDeviceId != (USHORT)~0) {
        /* Device is open. */
        if (pAData->stMCIMixSetup.ulBitsPerSample != 0) {
            /* Mixer was initialized. */
            ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
                                  MCI_WAIT | MCI_MIXSETUP_DEINIT,
                                  &pAData->stMCIMixSetup, 0);
            if (ulRC != MCIERR_SUCCESS) {
                debug_os2("MCI_MIXSETUP, MCI_MIXSETUP_DEINIT - failed");
            }
        }

        if (pAData->cMixBuffers != 0) {
            /* Buffers was allocated. */
            MCI_BUFFER_PARMS    stMCIBuffer;

            stMCIBuffer.ulBufferSize = pAData->aMixBuffers[0].ulBufferLength;
            stMCIBuffer.ulNumBuffers = pAData->cMixBuffers;
            stMCIBuffer.pBufList = pAData->aMixBuffers;

            ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER,
                                  MCI_WAIT | MCI_DEALLOCATE_MEMORY, &stMCIBuffer, 0);
            if (ulRC != MCIERR_SUCCESS) {
                debug_os2("MCI_BUFFER, MCI_DEALLOCATE_MEMORY - failed");
            }
        }

        ulRC = mciSendCommand(pAData->usDeviceId, MCI_CLOSE, MCI_WAIT,
                              &sMCIGenericParms, 0);
        if (ulRC != MCIERR_SUCCESS) {
            debug_os2("MCI_CLOSE - failed");
        }
    }

    if (pAData->hevBuf != NULLHANDLE)
        DosCloseEventSem(pAData->hevBuf);

    SDL_free(pAData);
}

static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
                          int iscapture)
{
    SDL_PrivateAudioData *pAData;
    SDL_AudioFormat       SDLAudioFmt;
    MCI_AMP_OPEN_PARMS    stMCIAmpOpen;
    MCI_BUFFER_PARMS      stMCIBuffer;
    ULONG                 ulRC;
    ULONG                 ulIdx;
    BOOL                  new_freq;

    new_freq = FALSE;
    SDL_zero(stMCIAmpOpen);
    SDL_zero(stMCIBuffer);

    for (SDLAudioFmt = SDL_FirstAudioFormat(_this->spec.format);
         SDLAudioFmt != 0; SDLAudioFmt = SDL_NextAudioFormat()) {
        if (SDLAudioFmt == AUDIO_U8 || SDLAudioFmt == AUDIO_S16)
            break;
    }
    if (SDLAudioFmt == 0) {
        debug_os2("Unsupported audio format, AUDIO_S16 used");
        SDLAudioFmt = AUDIO_S16;
    }

    pAData = (SDL_PrivateAudioData *) SDL_calloc(1, sizeof(struct SDL_PrivateAudioData));
    if (pAData == NULL)
        return SDL_OutOfMemory();
    _this->hidden = pAData;

    ulRC = DosCreateEventSem(NULL, &pAData->hevBuf, DCE_AUTORESET, TRUE);
    if (ulRC != NO_ERROR) {
        debug_os2("DosCreateEventSem() failed, rc = %u", ulRC);
        return -1;
    }

    /* Open audio device */
    stMCIAmpOpen.usDeviceID = (handle != NULL) ? ((ULONG)handle - 1) : 0;
    stMCIAmpOpen.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
    ulRC = mciSendCommand(0, MCI_OPEN,
                          (_getEnvULong("SDL_AUDIO_SHARE", 1, 0) != 0)?
                           MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE :
                           MCI_WAIT | MCI_OPEN_TYPE_ID,
                          &stMCIAmpOpen,  0);
    if (ulRC != MCIERR_SUCCESS) {
        stMCIAmpOpen.usDeviceID = (USHORT)~0;
        return _MCIError("MCI_OPEN", ulRC);
    }
    pAData->usDeviceId = stMCIAmpOpen.usDeviceID;

    if (iscapture != 0) {
        MCI_CONNECTOR_PARMS stMCIConnector;
        MCI_AMP_SET_PARMS   stMCIAmpSet;
        BOOL                fLineIn = _getEnvULong("SDL_AUDIO_LINEIN", 1, 0);

        /* Set particular connector. */
        SDL_zero(stMCIConnector);
        stMCIConnector.ulConnectorType = (fLineIn)? MCI_LINE_IN_CONNECTOR :
                                                    MCI_MICROPHONE_CONNECTOR;
        mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_CONNECTOR,
                       MCI_WAIT | MCI_ENABLE_CONNECTOR |
                       MCI_CONNECTOR_TYPE, &stMCIConnector, 0);

        /* Disable monitor. */
        SDL_zero(stMCIAmpSet);
        stMCIAmpSet.ulItem = MCI_AMP_SET_MONITOR;
        mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_SET,
                       MCI_WAIT | MCI_SET_OFF | MCI_SET_ITEM,
                       &stMCIAmpSet, 0);

        /* Set record volume. */
        stMCIAmpSet.ulLevel = _getEnvULong("SDL_AUDIO_RECVOL", 100, 90);
        stMCIAmpSet.ulItem  = MCI_AMP_SET_AUDIO;
        stMCIAmpSet.ulAudio = MCI_SET_AUDIO_ALL; /* Both cnannels. */
        stMCIAmpSet.ulValue = (fLineIn) ? MCI_LINE_IN_CONNECTOR :
                                          MCI_MICROPHONE_CONNECTOR ;

        mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_SET,
                       MCI_WAIT | MCI_SET_AUDIO | MCI_AMP_SET_GAIN,
                       &stMCIAmpSet, 0);
    }

    _this->spec.format = SDLAudioFmt;
    _this->spec.channels = _this->spec.channels > 1 ? 2 : 1;
    if (_this->spec.freq < 8000) {
        _this->spec.freq = 8000;
        new_freq = TRUE;
    } else if (_this->spec.freq > 48000) {
        _this->spec.freq = 48000;
        new_freq = TRUE;
    }

    /* Setup mixer. */
    pAData->stMCIMixSetup.ulFormatTag     = MCI_WAVE_FORMAT_PCM;
    pAData->stMCIMixSetup.ulBitsPerSample = SDL_AUDIO_BITSIZE(SDLAudioFmt);
    pAData->stMCIMixSetup.ulSamplesPerSec = _this->spec.freq;
    pAData->stMCIMixSetup.ulChannels      = _this->spec.channels;
    pAData->stMCIMixSetup.ulDeviceType    = MCI_DEVTYPE_WAVEFORM_AUDIO;
    if (iscapture == 0) {
        pAData->stMCIMixSetup.ulFormatMode= MCI_PLAY;
        pAData->stMCIMixSetup.pmixEvent   = cbAudioWriteEvent;
    } else {
        pAData->stMCIMixSetup.ulFormatMode= MCI_RECORD;
        pAData->stMCIMixSetup.pmixEvent   = cbAudioReadEvent;
    }

    ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
                          MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0);
    if (ulRC != MCIERR_SUCCESS && _this->spec.freq > 44100) {
        new_freq = TRUE;
        pAData->stMCIMixSetup.ulSamplesPerSec = 44100;
        _this->spec.freq = 44100;
        ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
                              MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0);
    }

    debug_os2("Setup mixer [BPS: %u, Freq.: %u, Channels: %u]: %s",
              pAData->stMCIMixSetup.ulBitsPerSample,
              pAData->stMCIMixSetup.ulSamplesPerSec,
              pAData->stMCIMixSetup.ulChannels,
              (ulRC == MCIERR_SUCCESS)? "SUCCESS" : "FAIL");

    if (ulRC != MCIERR_SUCCESS) {
        pAData->stMCIMixSetup.ulBitsPerSample = 0;
        return _MCIError("MCI_MIXSETUP", ulRC);
    }

    if (_this->spec.samples == 0 || new_freq == TRUE) {
    /* also see SDL_audio.c:prepare_audiospec() */
    /* Pick a default of ~46 ms at desired frequency */
        Uint32 samples = (_this->spec.freq / 1000) * 46;
        Uint32 power2 = 1;
        while (power2 < samples) {
            power2 <<= 1;
        }
        _this->spec.samples = power2;
    }
    /* Update the fragment size as size in bytes */
    SDL_CalculateAudioSpec(&_this->spec);

    /* Allocate memory buffers */
    stMCIBuffer.ulBufferSize = _this->spec.size;/* (_this->spec.freq / 1000) * 100 */
    stMCIBuffer.ulNumBuffers = NUM_BUFFERS;
    stMCIBuffer.pBufList     = pAData->aMixBuffers;

    ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER,
                          MCI_WAIT | MCI_ALLOCATE_MEMORY, &stMCIBuffer, 0);
    if (ulRC != MCIERR_SUCCESS) {
        return _MCIError("MCI_BUFFER", ulRC);
    }
    pAData->cMixBuffers = stMCIBuffer.ulNumBuffers;
    _this->spec.size = stMCIBuffer.ulBufferSize;

    /* Fill all device buffers with data */
    for (ulIdx = 0; ulIdx < stMCIBuffer.ulNumBuffers; ulIdx++) {
        pAData->aMixBuffers[ulIdx].ulFlags        = 0;
        pAData->aMixBuffers[ulIdx].ulBufferLength = stMCIBuffer.ulBufferSize;
        pAData->aMixBuffers[ulIdx].ulUserParm     = (ULONG)pAData;

        memset(((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer,
                _this->spec.silence, stMCIBuffer.ulBufferSize);
    }

    /* Write buffers to kick off the amp mixer */
    /*pAData->ulQueuedBuf = 1;//stMCIBuffer.ulNumBuffers */
    ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
                                           pAData->aMixBuffers,
                                           1 /*stMCIBuffer.ulNumBuffers*/);
    if (ulRC != MCIERR_SUCCESS) {
        _mixIOError("pmixWrite", ulRC);
        return -1;
    }

    return 0;
}


static int OS2_Init(SDL_AudioDriverImpl * impl)
{
    /* Set the function pointers */
    impl->DetectDevices = OS2_DetectDevices;
    impl->OpenDevice    = OS2_OpenDevice;
    impl->PlayDevice    = OS2_PlayDevice;
    impl->WaitDevice    = OS2_WaitDevice;
    impl->GetDeviceBuf  = OS2_GetDeviceBuf;
    impl->CloseDevice   = OS2_CloseDevice;

    /* TODO: IMPLEMENT CAPTURE SUPPORT:
    impl->CaptureFromDevice = ;
    impl->FlushCapture = ;
    impl->HasCaptureSupport = SDL_TRUE;
    */
    return 1; /* this audio target is available. */
}


AudioBootStrap OS2AUDIO_bootstrap = {
    "DART", "OS/2 DART", OS2_Init, 0
};

#endif /* SDL_AUDIO_DRIVER_OS2 */

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