/* +------------------------------------------------------------------------+
   |                     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          |
   +------------------------------------------------------------------------+ */

#pragma once

//(*Headers(ptgConfiguratorframe)
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/choice.h>
#include <wx/frame.h>
#include <wx/menu.h>
#include <wx/notebook.h>
#include <wx/panel.h>
#include <wx/sizer.h>
#include <wx/slider.h>
#include <wx/spinctrl.h>
#include <wx/stattext.h>
#include <wx/statusbr.h>
#include <wx/textctrl.h>

#include "MyGLCanvas.h"
//*)

#include <mrpt/3rdparty/mathplot/mathplot.h>
#include <mrpt/gui/CMyRedirector.h>
#include <mrpt/opengl/CAxis.h>
#include <mrpt/opengl/CMesh.h>
#include <mrpt/opengl/CPointCloud.h>
#include <mrpt/opengl/CSetOfLines.h>
#include <mrpt/opengl/CSetOfObjects.h>
#include <mrpt/opengl/Viewport.h>

// JLBC: Unix X headers have these funny things...
#ifdef Button1
#undef Button1
#undef Button2
#undef Button3
#undef Button4
#undef Button5
#undef Button6
#undef Button7
#endif
// To avoid conflicts between Eigen & X11 headers
#ifdef Success
#undef Success
#endif

class ptgConfiguratorframe : public wxFrame
{
 public:
  ptgConfiguratorframe(wxWindow* parent, wxWindowID id = -1);
  ~ptgConfiguratorframe() override;

  wxTextCtrl* getCfgBox() { return edCfg; }
  bool m_disableLoadDefaultParams = false;

  std::string m_cfgFileSection = "PTG_PARAMS";

 private:
  //(*Handlers(ptgConfiguratorframe)
  void OnAbout(wxCommandEvent& event);
  void OnQuit(wxCommandEvent& event);
  void OnExportSelectedPath(wxCommandEvent& event);
  void OnbtnReloadParamsClick(wxCommandEvent& event);
  void OncbPTGClassSelect(wxCommandEvent& event);
  void OnedPTGIndexChange(wxSpinEvent& event);
  void OncbDrawShapePathClick(wxCommandEvent& event);
  void OncbBuildTPObsClick(wxCommandEvent& event);
  void OnbtnRebuildTPObsClick(wxCommandEvent& event);
  void OnbtnPlaceObsClick(wxCommandEvent& event);
  void OnbtnPlaceTargetClick(wxCommandEvent& event);
  void OnslidPathHighlightCmdScroll(wxCommandEvent&);
  void OncbHighlightOnePathClick(wxCommandEvent& event);
  void OnedIndexHighlightPathChange(wxSpinEvent& event);
  void OnedCfgText(wxCommandEvent& event);
  void OnButton1Click(wxCommandEvent& event);
  void OnrbShowTPSelectSelect(wxCommandEvent& event);
  //*)

  //(*Identifiers(ptgConfiguratorframe)
  static const long ID_STATICTEXT1;
  static const long ID_CHOICE1;
  static const long ID_STATICTEXT5;
  static const long ID_BUTTON1;
  static const long ID_STATICTEXT2;
  static const long ID_SPINCTRL1;
  static const long ID_CHECKBOX1;
  static const long ID_STATICTEXT4;
  static const long ID_TEXTCTRL5;
  static const long ID_BUTTON5;
  static const long ID_CHECKBOX3;
  static const long ID_SLIDER1;
  static const long ID_SPINCTRL2;
  static const long ID_CHECKBOX4;
  static const long ID_CHECKBOX2;
  static const long ID_TEXTCTRL3;
  static const long ID_STATICTEXT3;
  static const long ID_TEXTCTRL4;
  static const long ID_BUTTON3;
  static const long ID_BUTTON2;
  static const long ID_STATICTEXT6;
  static const long ID_TEXTCTRL6;
  static const long ID_STATICTEXT7;
  static const long ID_STATICTEXT7b;
  static const long ID_TEXTCTRL7;
  static const long ID_TEXTCTRL7b;
  static const long ID_STATICTEXT17;
  static const long ID_TEXTCTRL8;
  static const long ID_BUTTON4;
  static const long ID_TEXTCTRL1;
  static const long ID_TEXTCTRL2;
  static const long ID_PANEL1;
  static const long ID_XY_GLCANVAS;
  static const long ID_CHECKBOX5;
  static const long ID_CHECKBOX6;
  static const long ID_CHECKBOX7;
  static const long ID_CUSTOM2;
  static const long ID_PANEL2;
  static const long ID_CUSTOM1;
  static const long ID_PANEL3;
  static const long ID_STATICTEXT8;
  static const long ID_CUSTOM3;
  static const long ID_STATICTEXT9;
  static const long ID_CUSTOM4;
  static const long ID_PANEL4;
  static const long ID_STATICTEXT10;
  static const long ID_CUSTOM5;
  static const long ID_STATICTEXT11;
  static const long ID_CUSTOM6;
  static const long ID_STATICTEXT12;
  static const long ID_CUSTOM7;
  static const long ID_STATICTEXT16;
  static const long ID_CUSTOM11;
  static const long ID_PANEL5;
  static const long ID_STATICTEXT13;
  static const long ID_CUSTOM8;
  static const long ID_STATICTEXT14;
  static const long ID_CUSTOM9;
  static const long ID_STATICTEXT15;
  static const long ID_CUSTOM10;
  static const long ID_PANEL6;
  static const long ID_NOTEBOOK1;
  static const long idMenuQuit;
  static const long idMenuAbout;
  static const long ID_STATUSBAR1;
  //*)

  //(*Declarations(ptgConfiguratorframe)
  wxStaticText* StaticText10;
  mpWindow* m_plotPathW;
  wxStaticText* StaticText9;
  wxTextCtrl* edObsY;
  wxButton* btnLoadPlugin;
  wxPanel* Panel5;
  mpWindow* m_plotHeadAngAll;
  mpWindow* m_plotPathY;
  wxNotebook* Notebook1;
  CMyGLCanvas* m_plotTPSpace;
  wxStaticText* StaticText13;
  wxStaticText* StaticText2;
  wxPanel* Panel4;
  wxStaticText* StaticText14;
  wxCheckBox* cbDrawShapePath;
  wxCheckBox* cbShowOnlySelectedTraj;
  wxSpinCtrl* edPTGIndex;
  wxStaticText* StaticText6;
  wxCheckBox* cbBuildTPObs;
  mpWindow* m_plotPathPhi;
  wxSpinCtrl* edIndexHighlightPath;
  wxButton* btnPlaceObs;
  wxStaticText* StaticText8;
  wxButton* btnRebuildTPObs;
  wxStaticText* StaticText11;
  wxPanel* Panel1;
  wxStaticText* StaticText1;
  mpWindow* m_plotPathDist;
  wxCheckBox* cbShowTPObs;
  wxStaticText* StaticText3;
  wxCheckBox* cbClearanceInterp;
  wxChoice* cbPTGClass;
  wxPanel* Panel6;
  wxPanel* Panel3;
  CMyGLCanvas* m_plot;
  wxTextCtrl* edRelSpeedAtTarget;
  wxButton* btnPlaceTarget;
  mpWindow* m_plotPathYp;
  wxTextCtrl* edTargetX;
  wxCheckBox* cbHighlightOnePath;
  wxTextCtrl* edLog;
  wxStaticText* StaticText5;
  mpWindow* m_plotPathXp;
  mpWindow* m_plotHeadAngIndiv;
  wxStaticText* StaticText7;
  wxStaticText* StaticText7b;
  wxStatusBar* StatusBar1;
  mpWindow* m_plotVelCmds;
  wxTextCtrl* edObsX;
  wxButton* btnReloadParams;
  wxStaticText* StaticText15;
  wxStaticText* StaticText12;
  mpWindow* m_plotPathX;
  wxTextCtrl* edCfg;
  wxPanel* Panel2;
  wxTextCtrl* edMinDistBtwShapes;
  wxStaticText* StaticText17;
  wxStaticText* StaticText4;
  wxCheckBox* cbShowClearance;
  wxStaticText* StaticText16;
  wxTextCtrl* edTargetY;
  wxTextCtrl* edTargetPhiDeg;
  wxSlider* slidPathHighlight;
  //*)
  wxTextCtrl* edSelectedTrajCmd = nullptr;
  wxTextCtrl* edDrawMaxTime = nullptr;

  DECLARE_EVENT_TABLE()

  void Onplot3DMouseMove(wxMouseEvent& event);
  void Onplot3DMouseClick(wxMouseEvent& event);

  void rebuild3Dview();
  void loadPlugin();
  void dumpPTGcfgToTextBox();

  /* Methods: */
  std::unique_ptr<CMyRedirector> m_myRedirector;

  /**  The state of the cursor onto the 3D view */
  enum TCursorPickState
  {
    cpsNone = 0,
    cpsPickObstacle,
    cpsPickTarget
  };

  /** Of the cursor on the 3D view (in world coordinates at Z=0) */
  mrpt::math::TPoint2D m_curCursorPos;
  /** The state of the cursor onto the 3D view: */
  TCursorPickState m_cursorPickState;

  // ========= Opengl View =======
  mrpt::opengl::Viewport::Ptr gl_view_WS, gl_view_TPSpace;
  mrpt::opengl::CSetOfObjects::Ptr gl_TPSpace_TP_obstacles;
  mrpt::opengl::CMesh::Ptr gl_TPSpace_clearance, gl_TPSpace_clearance_interp;
  mrpt::opengl::CCamera::Ptr gl_view_TPSpace_cam;
  mrpt::opengl::CAxis::Ptr gl_axis_WS, gl_axis_TPS;
  mrpt::opengl::CSetOfLines::Ptr gl_robot_ptg_prediction, gl_robot_ptg_prediction_highlight,
      gl_tp_obstacles;
  mrpt::opengl::CPointCloud::Ptr gl_WS_obs;
  mrpt::opengl::CPointCloud::Ptr gl_TP_target;
  mrpt::opengl::CSetOfObjects::Ptr gl_WS_target, gl_WS_target_reprojected;

  // 2D plot views:
  mpFXYVector *m_graph_head_all, *m_graph_head_indiv;
  mpFXYVector *m_graph_path_x, *m_graph_path_y, *m_graph_path_phi, *m_graph_path_dist;
  mpFXYVector *m_graph_path_vx, *m_graph_path_vy, *m_graph_path_omega;

  static void prepareRobotPathPlot(mpWindow* plot, mpFXYVector** graph, const std::string& name);
};
