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

#include "euterpe/pr_general_wnd.h"
#include "euterpe/main_wnd.h"

#include "WDL/win32_utf8.h"
#include "WDL/wdlstring.h"
#include "WDL/heapbuf.h"

RSE_GeneralWnd::RSE_GeneralWnd()
  : m_hwnd(NULL)
  , m_bm_bg(NULL)
  , m_bm_txt(NULL)
  , m_bg(0)
  , txt_(0)
{}

RSE_GeneralWnd::~RSE_GeneralWnd()
{}

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

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

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

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

void RSE_GeneralWnd::DoPaint(HDC dc)
{
  RECT r_bg, r_txt;
  GetWindowRect(GetDlgItem(m_hwnd, IDC_STATIC1), &r_bg);
  ScreenToClient(m_hwnd, (LPPOINT)&r_bg);
  ScreenToClient(m_hwnd, ((LPPOINT)&r_bg)+1);
  GetWindowRect(GetDlgItem(m_hwnd, IDC_STATIC2), &r_txt);
  ScreenToClient(m_hwnd, (LPPOINT)&r_txt);
  ScreenToClient(m_hwnd, ((LPPOINT)&r_txt)+1);

  LICE_FillRect(m_bm_bg, 0, 0, r_bg.right - r_bg.left, r_bg.bottom - r_bg.top,
    LICE_RGBA((m_bg >> 16) & 0xFF, (m_bg >> 8) & 0xFF, (m_bg >> 0) & 0xFF, 255),
    1.0f, LICE_BLIT_MODE_COPY);

  BitBlt(dc, r_bg.left, r_bg.top, m_bm_bg->getWidth(), m_bm_bg->getHeight(),
    m_bm_bg->getDC(), 0, 0, SRCCOPY);

  LICE_FillRect(m_bm_txt, 0, 0, r_txt.right - r_txt.left, r_txt.bottom - r_txt.top,
    LICE_RGBA((txt_ >> 16) & 0xFF, (txt_ >> 8) & 0xFF, (txt_ >> 0) & 0xFF, 255),
    1.0f, LICE_BLIT_MODE_COPY);

  BitBlt(dc, r_txt.left, r_txt.top, m_bm_txt->getWidth(), m_bm_txt->getHeight(),
    m_bm_txt->getDC(), 0, 0, SRCCOPY);
}

WDL_DLGRET RSE_GeneralWnd::GeneralWndProc(UINT msg, WPARAM wparam, LPARAM lparam)
{
  switch(msg)
  {
  case WM_INITDIALOG:
    {
      RECT r_bg, r_txt;
      GetWindowRect(GetDlgItem(m_hwnd, IDC_STATIC1), &r_bg);
      GetWindowRect(GetDlgItem(m_hwnd, IDC_STATIC2), &r_txt);

      m_bm_bg = new LICE_SysBitmap(r_bg.right - r_bg.left, r_bg.bottom - r_bg.top);
      m_bm_txt = new LICE_SysBitmap(r_txt.right - r_txt.left, r_txt.bottom - r_txt.top);

      m_bg = g_ini_file->read_int("pl_bg_color",
        (0 << 16) | (0 << 8) | (0 << 0),
        "preferences");
      txt_ = g_ini_file->read_int("pl_txt_color",
        (192 << 16) | (192 << 8) | (192 << 0),
        "preferences");

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

      HWND ctrl = GetDlgItem(m_hwnd, IDC_COMBO1);

      SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)"16pt sinc");
      SendMessage(ctrl, CB_SETITEMDATA, 0, 16);
      SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)"64pt sinc (default)");
      SendMessage(ctrl, CB_SETITEMDATA, 1, 64);
      SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)"192pt sinc");
      SendMessage(ctrl, CB_SETITEMDATA, 2, 192);
      SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)"384pt sinc");
      SendMessage(ctrl, CB_SETITEMDATA, 3, 384);
      SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)"512pt sinc");
      SendMessage(ctrl, CB_SETITEMDATA, 4, 512);
      SendMessage(ctrl, CB_ADDSTRING, 0, (LPARAM)"768pt sinc");
      SendMessage(ctrl, CB_SETITEMDATA, 5, 768);

      switch (sinc)
      {
      case 16:
        SendMessage(ctrl, CB_SETCURSEL, 0, 0);
        break;
      case 64:
        SendMessage(ctrl, CB_SETCURSEL, 1, 0);
        break;
      case 192:
        SendMessage(ctrl, CB_SETCURSEL, 2, 0);
        break;
      case 384:
        SendMessage(ctrl, CB_SETCURSEL, 3, 0);
        break;
      case 512:
        SendMessage(ctrl, CB_SETCURSEL, 4, 0);
        break;
      case 768:
        SendMessage(ctrl, CB_SETCURSEL, 5, 0);
        break;
      default:
        SendMessage(ctrl, CB_SETCURSEL, 1, 0);
        break;
      }
#endif

    }
    break;
  case WM_DESTROY:
    {
      if (m_bm_bg) { delete m_bm_bg; m_bm_bg = NULL; }
      if (m_bm_txt) { delete m_bm_txt; m_bm_txt = NULL; }

      m_hwnd = NULL;
    }
    break;
  case WM_COMMAND:
    {
      switch(LOWORD(wparam))
      {
      case IDC_BUTTON1: // Background color
        {
#if (_WIN32)
          memset(&m_cc_bg, 0, sizeof(CHOOSECOLOR));
          m_cc_bg.lStructSize = sizeof(CHOOSECOLOR);
          m_cc_bg.hwndOwner = m_hwnd;
          m_cc_bg.lpCustColors = m_bg_custom_colors;
          m_cc_bg.Flags = CC_FULLOPEN | CC_RGBINIT;

          if (ChooseColor(&m_cc_bg))
          {
            RECT r;
            GetWindowRect(GetDlgItem(m_hwnd, IDC_STATIC1), &r);
            ScreenToClient(m_hwnd, (LPPOINT)&r);
            ScreenToClient(m_hwnd, ((LPPOINT)&r)+1);

            m_bg = (GetRValue(m_cc_bg.rgbResult) << 16 |
              (GetGValue(m_cc_bg.rgbResult) << 8) |
              (GetBValue(m_cc_bg.rgbResult) << 0));

            g_preference_settings->Set("pl_bg_color", m_bg);

            InvalidateRect(m_hwnd, &r, FALSE);
          }
#else
          RECT r;
          GetWindowRect(GetDlgItem(m_hwnd, IDC_STATIC1), &r);
          ScreenToClient(m_hwnd, (LPPOINT)&r);
          ScreenToClient(m_hwnd, ((LPPOINT)&r)+1);

          if (SWELL_ChooseColor(m_hwnd, &m_bg, 16, m_bg_custom_colors))
          {
            g_preference_settings->Set("pl_bg_color", m_bg);

            // Same as InvalidateRect?
            {
              HWND h = GetDlgItem(m_hwnd, IDC_STATIC1);
              HDC dc = GetWindowDC(h);
              DoPaint(dc);
              ReleaseDC(h, dc);
              //SWELL_FlushWindow(h); // for macos
            }
          }
#endif
        }
        break;
      case IDC_BUTTON2: // Text color
        {
#if (_WIN32)
          memset(&m_cc_txt, 0, sizeof(CHOOSECOLOR));
          m_cc_txt.lStructSize = sizeof(CHOOSECOLOR);
          m_cc_txt.hwndOwner = m_hwnd;
          m_cc_txt.lpCustColors = m_bg_custom_colors;
          m_cc_txt.Flags = CC_FULLOPEN | CC_RGBINIT;

          if (ChooseColor(&m_cc_txt))
          {
            RECT r;
            GetWindowRect(GetDlgItem(m_hwnd, IDC_STATIC2), &r);
            ScreenToClient(m_hwnd, (LPPOINT)&r);
            ScreenToClient(m_hwnd, ((LPPOINT)&r)+1);

            txt_ = (GetRValue(m_cc_txt.rgbResult) << 16 |
              (GetGValue(m_cc_txt.rgbResult) << 8) |
              (GetBValue(m_cc_txt.rgbResult) << 0));

            g_preference_settings->Set("pl_txt_color", txt_);

            InvalidateRect(m_hwnd, &r, FALSE);
          }
#else
          RECT r;
          GetWindowRect(GetDlgItem(m_hwnd, IDC_STATIC2), &r);
          ScreenToClient(m_hwnd, (LPPOINT)&r);
          ScreenToClient(m_hwnd, ((LPPOINT)&r)+1);

          if (SWELL_ChooseColor(m_hwnd, &txt_, 16, m_txt_custom_colors))
          {
            g_preference_settings->Set("pl_txt_color", txt_);

            // Same as InvalidateRect?
            {
              HWND h = GetDlgItem(m_hwnd, IDC_STATIC2);
              HDC dc = GetWindowDC(h);
              DoPaint(dc);
              ReleaseDC(h, dc);
              //SWELL_FlushWindow(h); // for macos
            }
          }
#endif
        }
        break;
      case IDC_BUTTON3: // Set default colors
        {
          RECT r1, r2;
          GetWindowRect(GetDlgItem(m_hwnd, IDC_STATIC1), &r1);
          ScreenToClient(m_hwnd, (LPPOINT)&r1);
          ScreenToClient(m_hwnd, ((LPPOINT)&r1)+1);
          GetWindowRect(GetDlgItem(m_hwnd, IDC_STATIC2), &r2);
          ScreenToClient(m_hwnd, (LPPOINT)&r2);
          ScreenToClient(m_hwnd, ((LPPOINT)&r2)+1);

          m_bg = (0 << 16) | (0 << 8) | (0 << 0);
          g_preference_settings->Set("pl_bg_color", m_bg);

          txt_ = (192 << 16) | (192 << 8) | (192 << 0);
          g_preference_settings->Set("pl_txt_color", txt_);

          InvalidateRect(m_hwnd, &r1, FALSE);
          InvalidateRect(m_hwnd, &r2, FALSE);
#if (0)
          // Same as InvalidateRect?
          {
            HWND h = GetDlgItem(m_hwnd, IDC_STATIC1);
            HDC dc = GetWindowDC(h);
            DoPaint(dc);
            ReleaseDC(h,dc);
            //SWELL_FlushWindow(h); // for macos
          }
#endif
        }
        break;
#if 0
      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 sinc = (int)SendMessage(ctrl, CB_GETITEMDATA, sel, 0);

            g_preference_settings->Set("resampler_sinc", sinc);
          }
        }
        break;
#endif
      }
    }
    break;
  case WM_PAINT:
    {
      PAINTSTRUCT ps;
      HDC dc = BeginPaint(m_hwnd, &ps);
      DoPaint(dc);
      EndPaint(m_hwnd, &ps);
    }
    break;
  }

  return 0;
}
