/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2020 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_timer.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(PSZ pszName, ULONG ulMax, ULONG ulDefault)
{
  ULONG      ulValue;
  PCHAR      pcEnd;
  PSZ        pszEnvVal = SDL_getenv( pszName );

  if ( pszEnvVal == NULL )
    return ulDefault;

  ulValue = SDL_strtoul( (const char *)pszEnvVal, &pcEnd, 10 );
  return ( pcEnd == pszEnvVal ) || ( ulValue > ulMax ) ? ulDefault : ulMax;
}

static int _MCIError(PSZ pszFunc, ULONG ulResult)
{
  CHAR			acBuf[128];

  mciGetErrorString( ulResult, acBuf, sizeof(acBuf) );
  return SDL_SetError( "[%s] %s", pszFunc, acBuf );
}

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

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

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

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

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

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

  if ( ulFlags != MIX_READ_COMPLETE )
  {
    debug( "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( "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( "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( "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( "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)
{
  PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)this->hidden;
  ULONG                 ulRC;

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

static Uint8 *OS2_GetDeviceBuf(_THIS)
{
  PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)this->hidden;

  return pAData->aMixBuffers[pAData->ulNextBuf].pBuffer;
}

static void OS2_PlayDevice(_THIS)
{
  PSDL_PrivateAudioData pAData = (PSDL_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)
{
  PSDL_PrivateAudioData pAData = (PSDL_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( "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( "MCI_BUFFER, MCI_DEALLOCATE_MEMORY - failed" );
    }

    ulRC = mciSendCommand( pAData->usDeviceId, MCI_CLOSE, MCI_WAIT,
                           &sMCIGenericParms, 0 );
    if ( ulRC != MCIERR_SUCCESS )
      debug( "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)
{
  PSDL_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( "Unsupported audio format, AUDIO_S16 used" );
    SDLAudioFmt = AUDIO_S16;
  }

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

  ulRC = DosCreateEventSem( NULL, &pAData->hevBuf, DCE_AUTORESET, TRUE );
  if ( ulRC != NO_ERROR )
  {
    debug( "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( "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 = { "MMOS2", "OS/2 DART", OS2_Init, 0 };

#endif /* SDL_AUDIO_DRIVER_OS2 */

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