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

#include "euterpe/exactvol_wnd.h"
#include "euterpe/app_info.h"
#include "euterpe/playlist_wnd.h"

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

#include "WDL/fpcmp.h"
#include "WDL/wdlstring.h"

RSE_ExactVolWnd::RSE_ExactVolWnd()
  : m_hwnd(NULL)
  , m_edit(NULL)
{}

RSE_ExactVolWnd::~RSE_ExactVolWnd()
{}

HWND RSE_ExactVolWnd::Handle() const
{
  return m_hwnd;
}

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

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

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

WDL_DLGRET RSE_ExactVolWnd::ExactVolWndProc(UINT msg, WPARAM wparam, LPARAM lparam)
{
#if defined(__linux__)
  if (msg == WM_KEYDOWN && LOWORD(wparam) == VK_RETURN)
  {
    SendMessage(m_hwnd, WM_COMMAND, MAKEWPARAM(IDOK, 0), 0);
    return 0;
  }
#endif

  switch (msg)
  {
  case WM_INITDIALOG:
    {
      m_edit = GetDlgItem(m_hwnd, IDC_EDIT1);

      //int x = g_ini_file->read_int("volexact_wnd_x", 0, EUTERPE_NAME);
      //int y = g_ini_file->read_int("volexact_wnd_y", 50, EUTERPE_NAME);

      POINT pt;
      GetCursorPos(&pt);
      SetWindowPos(m_hwnd, NULL, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
    }
    break;
  case WM_ERASEBKGND:
    {
      return 1;
    }
    break;
  case WM_MOVE:
    {

    }
    break;
  case WM_DESTROY:
    {
      RECT r;
      GetWindowRect(m_hwnd, &r);

      //g_ini_file->write_int("volexact_wnd_x", r.left, EUTERPE_NAME);
      ///g_ini_file->write_int("volexact_wnd_y", r.top, EUTERPE_NAME);

      m_hwnd = NULL;
    }
    break;
  case WM_COMMAND:
    {
      switch(LOWORD(wparam))
      {
      case IDOK:
        {
          char text[2048];
          GetDlgItemText(m_hwnd, IDC_EDIT1, text, sizeof(text));
          int len = (int)strlen(text);

          char *c = text;
          int spaces = 0;

          while (*c)
          {
            if (*c++ == ' ') spaces++;
            else break;
          }

          if (spaces)
          {
            memmove(text, text + spaces, len - spaces);
            text[len - spaces] = '\0';
            len = (int)strlen(text);
          }

          c = text + len - 1;

          while (*c == ' ')
          {
            *c-- = '\0';
          }

          len = (int)strlen(text);

          bool isdb = false;

          for (int i = 0, pt = 0; i < len; i++)
          {
            if (!i)
            {
              if (text[i] == '-' || isdigit_safe(text[i])) isdb = true;
              else { isdb = false; break; }
            }
            else
            {
              if (text[i] == '.') pt++;
              else if (isdigit_safe(text[i])) isdb = true;
              else { isdb = false; break; }
            }

            if (pt > 1) { isdb = false; break; }
          }

          if (isdb)
          {
            double db = atof(text);

            if (WDL_EssentiallyEqual(db, -150.0) || WDL_EssentiallyEqual(db, 0.0) ||
              (WDL_DefinitelyGreaterThan(db, -150.0) && WDL_DefinitelyLessThan(db, 0.0)))
            {
              g_main_loop_mutex.Enter();
              g_main_loop->SetVolume(db);
              g_main_loop_mutex.Leave();

              DestroyWindow(m_hwnd);
            }
          }
        }
        break;
      case IDCANCEL:
        {
          DestroyWindow(m_hwnd);
        }
        break;
      }
    }
    break;
  }

  return 0;
}
