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

#include <shlobj.h>

#include "mnemosyne/definitions.h"
#include "mnemosyne/app_info.h"
#include "mnemosyne/main_wnd.h"
#include "mnemosyne/picture_wnd.h"

#if defined(_WIN32) && defined(_DEBUG)
#include <vld.h>
#endif

#include "WDL/win32_curses/curses.h"

#include "WDL/wdlcstring.h"
#include "WDL/wdlstring.h"
#include "WDL/dirscan.h"
#include "WDL/wdlutf8.h"

int WINAPI WinMain(_In_ HINSTANCE instance,
  _In_opt_ HINSTANCE previous_instance,
  _In_ LPSTR cmd_param, _In_ int show_cmd)
{
  g_inst = instance;

  CoInitialize(NULL);
  //CoInitializeEx(NULL, ); // COINIT_APARTMENTTHREADED, COINIT_MULTITHREADED

  InitCommonControls();
  //LoadLibrary("riched20.dll");

  g_scrollmessage = RegisterWindowMessage("MSWHEEL_ROLLMSG");

  HICON icon = LoadIcon(g_inst, MAKEINTRESOURCE(IDI_ICON1));

  {
    WNDCLASS wc = { 0 };
    GetClassInfo(NULL, "#32770", &wc);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = icon;
    wc.hInstance = g_inst;
    RegisterClass(&wc);

    //wc.style = CS_HREDRAW | CS_VREDRAW;
    //wc.style = CS_GLOBALCLASS;
    wc.style = CS_DBLCLKS;
    wc.lpszClassName = "mnemosyne_superhost";
    RegisterClass(&wc);

    wc.lpszClassName = "about_superhost";
    RegisterClass(&wc);

    wc.lpszClassName = "license_superhost";
    RegisterClass(&wc);

    wc.lpszClassName = "changelog_superhost";
    RegisterClass(&wc);

    wc.lpfnWndProc = (WNDPROC)RSM_PictureWnd::PictureWndProc;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = "picture_control_superhost";
    RegisterClass(&wc);

    curses_registerChildClass(g_inst);

    //wc.style = CS_GLOBALCLASS;
    //wc.lpfnWndProc = (WNDPROC)main_draw_proc;
    //wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    //wc.lpszClassName = "maindraw_superhost";
    //RegisterClass(&wc);

    //wc.lpfnWndProc = (WNDPROC)custom_playlist_control_proc;
    //wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    //wc.lpszClassName = "playlist_control_superhost";
    //RegisterClass(&wc);
  }

  char modfn[2048];
  GetModuleFileName(g_inst, modfn, sizeof(modfn));

  g_modpath.Set(modfn);
  g_modpath.remove_filepart(true);

  bool portable_settings = false;

  // In order to have portable settings
  // create an empty directory with the
  // name |portable| in the root directory
  // of Terpsichore.

  if (!portable_settings)
  {
    WDL_DirScan dir;
    WDL_FastString fn;

    if (!dir.First(g_modpath.Get()))
    {
      do
      {
        if (dir.GetCurrentIsDirectory())
        {
          dir.GetCurrentFullFN(&fn);

          if (strcmp(fn.get_filepart(), "portable") == 0)
          {
            portable_settings = true;
            break;
          }
        }
      }
      while (!dir.Next());
    }
  }

  if (portable_settings)
  {
    g_setpath.Set(g_modpath.Get());
    g_setpath.Append("portable");
    g_setpath.Append(WDL_DIRCHAR_STR);
  }
  else
  {
    char user_path[2048];

    // CSIDL_APPDATA to get the equivalent of %APPDATA%
    // CSIDL_PROFILE to get the equivalent of %USERPROFILE%
    if (SHGetSpecialFolderPathUTF8(NULL, user_path, sizeof(user_path), CSIDL_APPDATA, 0))
    {
      g_setpath.Set(user_path);
      g_setpath.Append("\\" MNEMOSYNE_NAME_MARKETING "\\");
      CreateDirectory(g_setpath.Get(), NULL);
    }
    else
    {
      MessageBox(NULL, "Mnemosyne cannot retrieve user's roaming directory. Press OK to exit Mnemosyne.", "Mnemosyne error", MB_OK);
      exit(1);
    }
  }

  g_inipath.Set(g_setpath.Get());
  g_inipath.Append(MNEMOSYNE_NAME);
  g_inipath.Append(".ini");

  g_mainwnd = new RSM_MainWnd;

  CreateDialogParam(g_inst, MAKEINTRESOURCE(IDD_MAIN), GetDesktopWindow(), RSM_MainWnd::MainWndProc, (LPARAM)g_mainwnd);

  const int exitcode = RSM_RunMessageLoop();

  delete g_mainwnd;

  CoUninitialize();

  return exitcode;
}
