/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2023, 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);
};
