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

#include "euterpe/pr_audio_system_wnd.h"

#include "WDL/win32_utf8.h"
#include "WDL/assocarray.h"

bool IsWin7OrLater()
{
#if defined(_WIN32)
  DWORD version = GetVersion();
  DWORD major = (DWORD) (LOBYTE(LOWORD(version)));
  DWORD minor = (DWORD) (HIBYTE(LOWORD(version)));

  if ((major == 6) && (minor >= 1)) return true;
  if (major > 6) return true;
#endif
  return false;
}

RSE_AudioSystemWnd::RSE_AudioSystemWnd()
  : m_hwnd(NULL)
{}

RSE_AudioSystemWnd::~RSE_AudioSystemWnd()
{}

WDL_DLGRET RSE_AudioSystemWnd::ST_AudioSystemWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
  RSE_AudioSystemWnd *self = (RSE_AudioSystemWnd *)GetWindowLongPtr(hwnd, GWLP_USERDATA);

  if (!self && msg == WM_INITDIALOG)
  {
    SetWindowLongPtr(hwnd, GWLP_USERDATA, lparam);
    self = (RSE_AudioSystemWnd *)lparam;
    self->m_hwnd = hwnd;
  }

  if (self)
  {
    return self->AudioSystemWndProc(msg, wparam, lparam);
  }
  else
  {
    return 0;
  }
}

WDL_DLGRET RSE_AudioSystemWnd::AudioSystemWndProc(UINT msg, WPARAM wparam, LPARAM lparam)
{
  switch (msg)
  {
  case WM_INITDIALOG:
    {
      WDL_FastString name, asn;
      HWND ctrl = GetDlgItem(m_hwnd, IDC_COMBO1);
      WDL_UTF8_HookComboBox(ctrl);

      int active = -1;

#if defined(_WIN32)
      asn.Set(g_ini_file->read_str("audio_system_name", "WaveOut", "preferences"));
#elif defined(__linux__)
      asn.Set(g_ini_file->read_str("audio_system_name", "PulseAudio", "preferences"));
#endif

      asn.Insert("audio_device:", 0);

      for (int i = 0, n = 0; i < g_plugin_import.GetSize(); i++)
      {
        if (!strncmp(g_plugin_import.Enumerate(i), "audio_device", 12))
        {
          name.Set(g_plugin_import.Enumerate(i));

          name.DeleteSub(0, 13);

          SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)name.Get());
          SendMessage(ctrl, CB_SETITEMDATA, n, n);

          if (!strcmp(g_plugin_import.Enumerate(i), asn.Get()))
          {
            active = n;
          }

          n++;
        }
      }

      SendMessage(ctrl, CB_SETCURSEL, active, 0);

      int sinc = g_ini_file->read_int("resampler_sinc", 64, "preferences");

      HWND resamplermode = GetDlgItem(m_hwnd, IDC_COMBO2);
      SendMessage(resamplermode, CB_ADDSTRING, 0, (LPARAM)"16pt sinc");
      SendMessage(resamplermode, CB_SETITEMDATA, 0, 16);
      SendMessage(resamplermode, CB_ADDSTRING, 0, (LPARAM)"64pt sinc (default)");
      SendMessage(resamplermode, CB_SETITEMDATA, 1, 64);
      SendMessage(resamplermode, CB_ADDSTRING, 0, (LPARAM)"192pt sinc");
      SendMessage(resamplermode, CB_SETITEMDATA, 2, 192);
      SendMessage(resamplermode, CB_ADDSTRING, 0, (LPARAM)"384pt sinc");
      SendMessage(resamplermode, CB_SETITEMDATA, 3, 384);
      SendMessage(resamplermode, CB_ADDSTRING, 0, (LPARAM)"512pt sinc");
      SendMessage(resamplermode, CB_SETITEMDATA, 4, 512);
      SendMessage(resamplermode, CB_ADDSTRING, 0, (LPARAM)"768pt sinc");
      SendMessage(resamplermode, CB_SETITEMDATA, 5, 768);

      switch (sinc)
      {
      case 16:
        SendMessage(resamplermode, CB_SETCURSEL, 0, 0);
        break;
      case 64:
        SendMessage(resamplermode, CB_SETCURSEL, 1, 0);
        break;
      case 192:
        SendMessage(resamplermode, CB_SETCURSEL, 2, 0);
        break;
      case 384:
        SendMessage(resamplermode, CB_SETCURSEL, 3, 0);
        break;
      case 512:
        SendMessage(resamplermode, CB_SETCURSEL, 4, 0);
        break;
      case 768:
        SendMessage(resamplermode, CB_SETCURSEL, 5, 0);
        break;
      default:
        SendMessage(resamplermode, CB_SETCURSEL, 1, 0);
        break;
      }
    }
    break;
  case WM_DESTROY:
    {
      m_hwnd = NULL;
    }
    break;
  case WM_COMMAND:
    {
      switch (LOWORD(wparam))
      {
      case IDC_COMBO1:
        if (HIWORD(wparam) == CBN_SELCHANGE)
        {
          HWND ctrl = GetDlgItem(m_hwnd, IDC_COMBO1);
          int sel = (int)SendMessage(ctrl, CB_GETCURSEL, 0, 0);
          int dev = (int)SendMessage(ctrl, CB_GETITEMDATA, sel, 0);

          WDL_TypedBuf<char> text;
          text.Resize(512);
          GetDlgItemText(m_hwnd, IDC_COMBO1, text.Get(), text.GetSize());
          g_ini_file->write_str("audio_system_name", text.Get(), "preferences");
        }
        break;
      }
      case IDC_COMBO2:
        {
          if (HIWORD(wparam) == CBN_SELCHANGE)
          {
            HWND resamplermode = GetDlgItem(m_hwnd, IDC_COMBO2);
            int sel = (int)SendMessage(resamplermode, CB_GETCURSEL, 0, 0);
            int sinc = (int)SendMessage(resamplermode, CB_GETITEMDATA, sel, 0);

            g_preference_settings->Set("resampler_sinc", sinc);
          }
        }
        break;
    }
    break;
  }

  return 0;
}
