/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2024, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */

#include "slamdemoApp.h"

//(*AppHeaders
#include <wx/image.h>

#include "slamdemoMain.h"
//*)
#include <wx/msgdlg.h>

IMPLEMENT_APP(slamdemoApp)

#include <mrpt/3rdparty/tclap/CmdLine.h>
#include <mrpt/system/filesystem.h>
#include <mrpt/system/os.h>

using namespace std;

bool slamdemoApp::OnInit()
{
  // Starting in wxWidgets 2.9.0, we must reset numerics locale to "C",
  //  if we want numbers to use "." in all countries. The App::OnInit() is a
  //  perfect place to undo
  //  the default wxWidgets settings. (JL @ Sep-2009)
  wxSetlocale(LC_NUMERIC, wxString(wxT("C")));

  wxInitAllImageHandlers();

  // Process command line args?
  bool gotoGUI = true;

  win = new slamdemoFrame(nullptr);

  if (argc > 1) gotoGUI = doCommandLineProcess();

  if (gotoGUI)
  {
    // Show normal GUI:
    win->Show();
    SetTopWindow(win);
    return true;
  }
  else
  {
    delete win;
    win = nullptr;
    return false;  // Exit now.
  }
}

// Auxiliary class to allow text output in Win32 (in Linux the console keeps
// working for GUIs).
#ifdef MRPT_OS_WINDOWS

std::ostringstream out_cmdLine;

class CMyCmdLineOut : public TCLAP::StdOutput
{
 public:
  CMyCmdLineOut() : StdOutput(out_cmdLine) {}
};

#endif

// Executes the program in "batch" mode, where the user passes some command-line
// args
bool slamdemoApp::doCommandLineProcess()
{
  // Declare the supported options.
  TCLAP::CmdLine cmd("2d-slam-demo", ' ', mrpt::system::MRPT_getVersion().c_str());

  TCLAP::ValueArg<std::string> arg_cfgFil(
      "c", "config", "Config file to load", false, "", "params.ini", cmd);
  TCLAP::SwitchArg arg_nogui(
      "n", "nogui", "Don't stay in the GUI, exit after the experiment.", cmd, false);
  TCLAP::SwitchArg arg_norun("r", "norun", "Just load the config file, don't run it.", cmd, false);

#ifdef MRPT_OS_WINDOWS
  CMyCmdLineOut out_buf;
  cmd.setOutput(&out_buf);
#endif

  vector<char*> auxArgs(argc);
  for (int i = 0; i < argc; i++)
  {
    wxString s(argv[i]);
    auxArgs[i] = new char[s.size() + 10];
    strcpy(auxArgs[i], s.ToUTF8().data());
  }

  // Parse arguments:
  bool res_parse = cmd.parse(argc, &auxArgs[0]);

  // Free aux mem:
  for (int i = 0; i < argc; i++) delete[] auxArgs[i];

  if (!res_parse)
  {
#ifdef MRPT_OS_WINDOWS
    if (!out_cmdLine.str().empty()) wxMessageBox(out_cmdLine.str().c_str(), _("2d-slam-demo"));
#endif
    return false;
  }

  const std::string cfgFil = arg_cfgFil.getValue();

  if (!mrpt::system::fileExists(cfgFil))
  {
    cerr << "The indicated config file does not exist: " << cfgFil << endl;
#ifdef MRPT_OS_WINDOWS
    wxMessageBox(wxT("The indicated config file does not exist"), _("2d-slam-demo"));
#endif
    return false;
  }
  else
  {
    m_option_norun = arg_norun.getValue();

    if (!arg_nogui.getValue())
    {
      win->Show();
      SetTopWindow(win);
    }

    try
    {
      DoBatchExperiments(cfgFil);
    }
    catch (const std::exception& e)
    {
      cerr << mrpt::exception_to_str(e) << endl;
#ifdef MRPT_OS_WINDOWS
      wxMessageBox(mrpt::exception_to_str(e), _("2d-slam-demo"));
#endif
    }
  }

  // return false to exit the program now and NOT proceed with the GUI.
  // return true to continue with the program:
  return !arg_nogui.getValue();
}
