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

#include "RSI/preferences_wnd.h"

#define RSI_PREFERENCES_UPDATE_ID 340
#define RSI_PREFERENCES_UPDATE_MS 50

static win32CursesCtx s_preview_ctx;
static win32CursesCtx s_editor_ctx;

RSI_PreferencesWnd::RSI_PreferencesWnd()
  : m_hwnd(NULL)
  , m_preview(&s_preview_ctx)
  , m_editor(&s_editor_ctx)
{}

RSI_PreferencesWnd::~RSI_PreferencesWnd()
{
  DestroyWindow(m_hwnd);
}

void RSI_PreferencesWnd::OnInitDialog()
{
  HWND ccp = GetDlgItem(m_hwnd, IDC_CUSTOM3);
  HWND cce = GetDlgItem(m_hwnd, IDC_CUSTOM2);
  curses_setWindowContext(ccp, &s_preview_ctx);
  curses_setWindowContext(cce, &s_editor_ctx);

  m_resize.init(m_hwnd);
  m_resize.init_itemhwnd(ccp, 0.0f, 0.0f, 0.5f, 1.0f);
  m_resize.init_itemhwnd(cce, 0.5f, 0.0f, 1.0f, 1.0f);

  int x = GetPrivateProfileInt(RSI_NAME, "preferences_wnd_x", 0, g_inipath.Get());
  int y = GetPrivateProfileInt(RSI_NAME, "preferences_wnd_y", 50, g_inipath.Get());
  int w = GetPrivateProfileInt(RSI_NAME, "preferences_wnd_w", 1120, g_inipath.Get());
  int h = GetPrivateProfileInt(RSI_NAME, "preferences_wnd_h", 720, g_inipath.Get());
  SetWindowPos(m_hwnd, NULL, x, y, w, h, SWP_NOZORDER | SWP_NOACTIVATE);

  WDL_FastString defpref;
  defpref.Set(g_setpath.Get());
  defpref.Append("preferences-default.txt");

  WDL_FastString usrpref;
  usrpref.Set(g_setpath.Get());
  usrpref.Append("preferences.txt");

  m_preview.SetParent(m_hwnd);
  m_preview.init(defpref.Get());
  m_preview.draw();
  m_preview.setCursor();

  m_editor.SetParent(m_hwnd);
  m_editor.init(usrpref.Get());
  m_editor.draw();
  m_editor.setCursor();

  bool crf = g_preferences->WantCursesRightFocus();
  if (crf) SetFocus(cce); else SetFocus(ccp);
  SetTimer(m_hwnd, RSI_PREFERENCES_UPDATE_ID, RSI_PREFERENCES_UPDATE_MS, NULL);
}

void RSI_PreferencesWnd::OnTimer()
{
  if (m_wparam == RSI_PREFERENCES_UPDATE_ID)
  {
    m_preview.RunEditor();
    m_editor.RunEditor();
  }
}

void RSI_PreferencesWnd::OnDestroy()
{
  KillTimer(m_hwnd, RSI_PREFERENCES_UPDATE_ID);

  m_preview.ClearText();
  m_editor.ClearText();

  RECT r;
  GetWindowRect(m_hwnd, &r);

  WDL_FastString rleft, rtop, rwidth, rheight;
  rleft.SetFormatted(32, "%d", r.left);
  rtop.SetFormatted(32, "%d", r.top);
  rwidth.SetFormatted(32, "%d", r.right - r.left);
  rheight.SetFormatted(32, "%d", r.bottom - r.top);

  WritePrivateProfileString(RSI_NAME,"preferences_wnd_x", rleft.Get(), g_inipath.Get());
  WritePrivateProfileString(RSI_NAME,"preferences_wnd_y", rtop.Get(), g_inipath.Get());
  WritePrivateProfileString(RSI_NAME,"preferences_wnd_w", rwidth.Get(), g_inipath.Get());
  WritePrivateProfileString(RSI_NAME,"preferences_wnd_h", rheight.Get(), g_inipath.Get());
}

void RSI_PreferencesWnd::OnSize()
{
  if (m_wparam != SIZE_MINIMIZED)
  {
    m_resize.onResize();
  }
}

void RSI_PreferencesWnd::OnCommand()
{
  switch(LOWORD(m_wparam))
  {
    case IDCANCEL:
    {
      if (g_prefwnd) { delete g_prefwnd; g_prefwnd = NULL; }
    }
    break;
  }
}

void RSI_PreferencesWnd::OnSysCommand()
{
  if (LOWORD(m_wparam) == SC_CLOSE)
  {
    if (g_prefwnd) { delete g_prefwnd; g_prefwnd = NULL; }
  }
}

void RSI_PreferencesWnd::OnToggleFocus()
{
  HWND ccp = GetDlgItem(m_hwnd, IDC_CUSTOM3);
  HWND cce = GetDlgItem(m_hwnd, IDC_CUSTOM2);
  if (GetFocus() == ccp) SetFocus(cce); else SetFocus(ccp);
}

void RSI_PreferencesWnd::OnPaint()
{
  RECT r;
  GetClientRect(m_hwnd, &r);

  m_painter.PaintBegin(m_hwnd, RGB(255, 255, 128));
  m_painter.PaintEnd();
}

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

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

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

WDL_DLGRET RSI_PreferencesWnd::PreferencesWndLoop(UINT msg, WPARAM wparam, LPARAM lparam)
{
  m_msg = msg;
  m_wparam = wparam;
  m_lparam = lparam;

  switch (msg)
  {
    case WM_INITDIALOG: OnInitDialog(); break;
    case WM_TIMER: OnTimer(); break;
    case WM_DESTROY: OnDestroy(); break;
    case WM_SIZE: OnSize(); break;
    case WM_COMMAND: OnCommand(); break;
    case WM_SYSCOMMAND: OnSysCommand(); break;
    case WM_TOGGLE_FOCUS: OnToggleFocus(); break;
    case WM_PAINT: OnPaint(); break;
  }

  return 0;
}
