// Copyright (c) 2019 Giorgos Vougioukas
//
// The license can be found in the LICENSE file.

#include "rsi_wasapi/audio_streamer_wasapi_dev.h"

#include <stdlib.h>
#include <string.h>

static void free_str(const char *p)
{
  free((void *)p);
}

RSI_WasapiDevice::RSI_WasapiDevice()
  : m_error(paNoError)
  //, input_dev(free_str)
  //, output_dev(free_str)
  , m_default_input_dev(-1)
  , m_default_output_dev(-1)
{
  //m_host_api_id = host_api_id;
}

int RSI_WasapiDevice::GetDefaultInputDevice() const
{
  return m_default_input_dev;
}

int RSI_WasapiDevice::GetDefaultOutputDevice() const
{
  return m_default_output_dev;
}

RSI_WasapiDevice::~RSI_WasapiDevice()
{
  input_dev.DeleteAll();
  output_dev.DeleteAll();
}

void RSI_WasapiDevice::Scan()
{
  m_error = Pa_Initialize();

  m_host_api_id = paWASAPI;

  if (WDL_NOT_NORMALLY(m_error != paNoError))
  {
    wdl_log("cannot initialize portaudio\n");
  }

  PaHostApiIndex host_api = Pa_HostApiTypeIdToHostApiIndex(m_host_api_id);

  int device_count = Pa_GetDeviceCount();

  if (WDL_NOT_NORMALLY(device_count < 0))
  {
    wdl_log("cannot find any devices\n");
  }

  const PaDeviceInfo *device_info;

  input_dev.DeleteAll();
  output_dev.DeleteAll();

  for (int i = 0; i < device_count; i++)
  {
    device_info = Pa_GetDeviceInfo(i);

    if (device_info->hostApi == host_api &&
      device_info->maxInputChannels > 0)
    {
      input_dev.AddUnsorted(i, strdup(device_info->name));

      if (i == Pa_GetHostApiInfo(host_api)->defaultInputDevice)
      {
        m_default_input_dev = i;
      }
    }

    if (device_info->hostApi == host_api &&
      device_info->maxOutputChannels > 0)
    {
      output_dev.AddUnsorted(i, strdup(device_info->name));

      if (i == Pa_GetHostApiInfo(host_api)->defaultOutputDevice)
      {
        m_default_output_dev = i;
      }
    }
  }

  m_error = Pa_Terminate();

  if (WDL_NOT_NORMALLY(m_error != paNoError))
  {
    wdl_log("cannot terminate portaudio\n");
  }
}
