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

#include <main.h>
#include <core.h>

#include <core/version.h>
#include <res/resource.h>

#if __linux__
HMENU SWELL_app_stocksysmenu;
#else
extern HMENU SWELL_app_stocksysmenu;
#endif

double wall_0, wall_1, cpu_0, cpu_1;

extern "C" {

    INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2)
    {
        switch (msg)
        {
        case SWELLAPP_ONLOAD:
            {
                wall_0 = get_wall_time();
                cpu_0 = get_cpu_time();
            }
            break;

        case SWELLAPP_LOADED:
            {

                if (SWELL_app_stocksysmenu)
                {
                    HMENU menu = CreatePopupMenu();
                    HMENU nm = SWELL_DuplicateMenu(SWELL_app_stocksysmenu);

                    if (nm)
                    {
                        MENUITEMINFO mi = { sizeof(mi), MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE, MFT_STRING, 0, 0, nm, NULL, NULL, 0, "Terpsichore" };
                        InsertMenuItem(menu, 0, TRUE, &mi);
                    }

                    SWELL_SetDefaultWindowMenu(menu);
                }


                {
                    HMENU menu = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MENU1));
                    {
                        HMENU sm = GetSubMenu(menu, 0);
                        DeleteMenu(sm, ID_FILE_QUIT, MF_BYCOMMAND);

                        int a = GetMenuItemCount(sm);

                        while (a > 0 && GetMenuItemID(sm, a - 1) == 0)
                        {
                            DeleteMenu(sm, a - 1, MF_BYPOSITION);
                        }

                        a--;
                    }
                    DeleteMenu(menu, GetMenuItemCount(menu) - 1, MF_BYPOSITION);


                    if (SWELL_app_stocksysmenu)
                    {
                        HMENU nm = SWELL_DuplicateMenu(SWELL_app_stocksysmenu);

                        if (nm)
                        {
                            MENUITEMINFO mi = { sizeof(mi), MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE, MFT_STRING, 0, 0, nm, NULL, NULL, 0, "Terpsichore"};

                            InsertMenuItem(menu, 0, TRUE, &mi);
                        }

                    }

                    main_dlg.Create(NULL, true);

                    SetMenu(main_dlg.GetDialog(), menu);

                    if (version.IsPrototypon())
                    {
                        const char msg[] =
                        {
                            "Welcome to " APP_NAME " (the ``Software'').\n\n"
                            "THIS IS A PROTOTYPON STILL IN DEVELOPEMENT PHASE "
                            "AND IS PROVIDED ON AN ``AS IS'' BASIS AND IS BELIEVED "
                            "TO CONTAIN DEFECTS AND A PRIMARY PURPOSE OF THIS "
                            "PROTOTYPON IS TO OBTAIN FEEDBACK ON SOFTWARE PERFORMANCE "
                            "AND THE IDENTIFICATION OF DEFECTS.\n\n"
                            "IT IS ADVISED TO SAFEGUARD IMPORTANT DATA, TO USE CAUTION AND NOT "
                            "TO RELY IN ANY WAY ON THE CORRECT FUNCTIONING OF THIS VERSION.\n\n"
                            APP_COPYRIGHT
                        };


                        double wall_1 = get_wall_time();
                        double cpu_1 = get_cpu_time();
                        double wall_elapsed_sec = wall_1 - wall_0;
                        double cpu_elapsed_sec = cpu_1 - cpu_0;

                        WDL_FastString prototype;
                        prototype.Set(msg);
                        prototype.AppendFormatted(128, "\n\nStartup time.\nWall time: "
                                                  "%f sec.\nCPU time: "
                                                  "%f sec.",
                                                  wall_elapsed_sec,
                                                  cpu_elapsed_sec);

                        MessageBox(main_dlg.GetDialog(), prototype.Get(), "ALPHA PROTOTYPON", MB_OK);
                    }
                }

            }
            break;

        case SWELLAPP_ONCOMMAND:
<            {
                if (main_dlg.GetDialog() && (parm1 & 0xFFFF))
                {
                    SendMessage(main_dlg.GetDialog(), WM_COMMAND, parm1 & 0xFFFF, 0);
                }
            }
            break;

        case SWELLAPP_DESTROY:
            {
                //if (g_main_wnd) DestroyWindow(g_main_wnd);
            } break;

        case SWELLAPP_PROCESSMESSAGE:
            {
                if (MainProcessMessage((MSG *) parm1) > 0)
                {
                    return 1;
                }

                return 0;
            }
            break;
        }

        return 0;
    }

};

#include <whittle/swell/swell-dlggen.h>
#include <winclient/res/terpsichore.rc_mac_dlg>

#undef BEGIN
#undef END
#include <whittle/swell/swell-menugen.h>
#include <winclient/res/terpsichore.rc_mac_menu>


*/

//#define SWELL_PROVIDED_BY_APP

#include "WDL/swell/swell.h"
#include "WDL/swell/swell-functions.h"
#include "WDL/lineparse.h"
#include "WDL/filewrite.h"
#include "WDL/dirscan.h"
#include "RSI/definitions.h"
#include "RSI/preferences.h"
#include "RSI/app_info.h"
#include "RSI/plugin.h"
#include "RSI/main_wnd.h"
#include "RSI/skin.h"

// Get home directory
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

//extern char *strndup(const char *__string, size_t __n);

//HINSTANCE instance;

extern "C"
{
  INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2)
  {
    switch (msg)
    {
    case SWELLAPP_ONLOAD:

      break;

    case SWELLAPP_LOADED:

      break;

    case SWELLAPP_DESTROY:
      {
        //if (g_main_wnd->Handle()) DestroyWindow(g_main_wnd->Handle());
      } break;

    case SWELLAPP_ACTIVATE:
      {
        //if (parm1) SendMessage(g_main_wnd->Handle(), WM_ACTIVATEAPP, TRUE, 0);

        //return 0;
      }
      break;

    case SWELLAPP_PROCESSMESSAGE:
      {
        if (RSI_ProcessMessage((MSG *)parm1) > 0) return 1;

        return 0;
      }
    }

    return 0;
  }
}

#if 0
static HWND TrackControlCreator(HWND parent, const char *cname,
                             int idx, const char *classname,
                             int style, int x, int y, int w,
                             int h)
{
  if (!stricmp(classname, "track_control_superhost"))
  {
    HWND hw = CreateDialog(NULL, 0, parent, (DLGPROC) RSI_TrackWndProc);
    SetWindowLong(hw, GWL_ID, idx);
    SetWindowPos(hw, HWND_TOP, x, y, w, h, SWP_NOZORDER | SWP_NOACTIVATE);
    ShowWindow(hw, SW_SHOWNA);
    return hw;
  }

  return 0;
}
#endif

HWND curses_ControlCreator(HWND parent, const char *cname, int idx, const char *classname, int style, int x, int y, int w, int h);

int main(int argc, char *argv[])
{
  SWELL_ExtendedAPI("APPNAME", (void *)"RSI");

  {
    WDL_FastString args;

    for (int i = 1; i < argc; i++)
    {
      args.Set(argv[i]);
      args.Append(" ");
    }

    LineParser lp;
    lp.parse(args.Get());

    for (int i = 0; i < lp.getnumtokens(); i++)
    {
      if (!strcmp(lp.gettoken_str(i), "--sleep"))
      {
        Sleep(888);
      }
    }
  }

  HWND other_alive = FindWindowEx(NULL, NULL, "rsi_superhost", NULL);

  if (other_alive)
  {
    SetForegroundWindow(other_alive);

    return 0;
  }

  //SWELL_RegisterCustomControlCreator(TrackControlCreator);
  SWELL_RegisterCustomControlCreator(curses_ControlCreator);

  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 RSI.

  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
  {
    struct passwd *pw = getpwuid(getuid());
    const char *homedir = pw->pw_dir;

    WDL_FastString home_dir(homedir);
    home_dir.Append(WDL_DIRCHAR_STR);
    home_dir.Append(".config");
    home_dir.Append(WDL_DIRCHAR_STR);

    CreateDirectory(home_dir.Get(), NULL);

    home_dir.Append("RSI");
    home_dir.Append(WDL_DIRCHAR_STR);

    CreateDirectory(home_dir.Get(), NULL);
    g_setpath.Set(home_dir.Get());
  }

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

  g_preferences = new RSI_Preferences;
  g_preferences->Create();
  if (!g_preferences->Parse())
  {
    WDL_FastString def(g_setpath), usr(g_setpath), err;
    def.Append("preferences-default.txt");
    usr.Append("preferences.txt");

    err.SetFormatted(512, "%s\nin %s\n\nPress OK to try load the default file:\n\n%s",
      g_preferences->GetParseError(), usr.Get(), def.Get());

    MessageBox(NULL, err.Get(), "RSI: preferences parse error found", MB_OK);

    if (!g_preferences->Parse(true))
    {
      goto terminate;
    }
  }

  LoadPlugins();

  g_skin.LoadSkin();

  SWELL_Internal_PostMessage_Init();

  g_mainwnd = new RSI_MainWnd;
  CreateDialogParam(g_inst, MAKEINTRESOURCE(IDD_MAIN), NULL,
    RSI_MainWnd::MainWndProc, (LPARAM)g_mainwnd);

  while (!g_hasrequestedquit)
  {
    SWELL_RunMessageLoop();

    Sleep(10);
  }

  delete g_mainwnd;
  ReleasePlugins();

terminate:
  bool relaunch = g_preferences->WantRelaunch();

  delete g_preferences;

  if (relaunch)
  {
    WDL_FastString mod;
    mod.Append(g_modpath.Get());
    mod.Append(RSI_NAME);
    //ShellExecute(NULL, "", mod.Get(), "", "", SW_SHOWNORMAL);
    system(mod.Get());
  }

  return 0;
}

#include "WDL/swell/swell-dlggen.h"
#include "RSI/res/rsi.rc_mac_dlg"

#undef BEGIN
#undef END
#include "WDL/swell/swell-menugen.h"
#include "RSI/res/rsi.rc_mac_menu"
