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

#ifndef _DSCENEVIEWERMAIN_H
#define _DSCENEVIEWERMAIN_H

#include <mrpt/gui/CWxGLCanvasBase.h>
#include <mrpt/gui/WxUtils.h>
#include <mrpt/system/datetime.h>
#include <wx/artprov.h>
#include <wx/bitmap.h>
#include <wx/frame.h>
#include <wx/image.h>
#include <wx/intl.h>
#include <wx/menu.h>
#include <wx/msgdlg.h>
#include <wx/statline.h>
#include <wx/statusbr.h>
#include <wx/string.h>
#include <wx/things/toggle.h>
#include <wx/timer.h>
#include <wx/toolbar.h>

#include <optional>

class CDlgCamTracking;
class CMyGLCanvas : public mrpt::gui::CWxGLCanvasBase
{
   public:
	CMyGLCanvas(
		wxWindow* parent, wxWindowID id = wxID_ANY,
		const wxPoint& pos = wxDefaultPosition,
		const wxSize& size = wxDefaultSize, long style = 0,
		const wxString& name = _T("CWxGLCanvasBase"))
		: CWxGLCanvasBase(parent, id, pos, size, style, name)
	{
	}

	void OnCharCustom(wxKeyEvent& event) override;

	void OnPreRender() override;
	void OnPostRender() override;
	void OnPostRenderSwapBuffers(double At, wxPaintDC& dc) override;
	void OnRenderError(const wxString& str) override;
};

class _DSceneViewerFrame : public wxFrame
{
	friend class CMyGLCanvas;
	friend class CDlgCamTracking;

   public:
	_DSceneViewerFrame(wxWindow* parent, wxWindowID id = -1);
	~_DSceneViewerFrame() override;

   private:
	//(*Handlers(_DSceneViewerFrame)
	void OnQuit(wxCommandEvent& event);
	void OnAbout(wxCommandEvent& event);
	void OnNewScene(wxCommandEvent& event);
	void OnOpenFile(wxCommandEvent& event);
	void OntimLoadFileCmdLineTrigger(wxTimerEvent& event);
	void OnbtnAutoplayClicked(wxCommandEvent& event);
	void OnMenuBackColor(wxCommandEvent& event);
	void OnMenuOptions(wxCommandEvent& event);
	void OnPrevious(wxCommandEvent& event);
	void OnNext(wxCommandEvent& event);
	void OnClose(wxCloseEvent& event);
	void OnBtnRecordClicked(wxCommandEvent& event);
	void OnbtnOrthoClicked(wxCommandEvent& event);
	void OnReload(wxCommandEvent& event);
	void OnInsert3DS(wxCommandEvent& event);
	void OnMenuSave(wxCommandEvent& event);
	void OnChangeCameraPose(wxCommandEvent& event);
	void OnTravellingTrigger(wxTimerEvent& event);
	void OnStartCameraTravelling(wxCommandEvent& event);
	void OnClose1(wxCloseEvent& event);
	void OnMenuAddSICK(wxCommandEvent& event);
	void OnMenuDeleteAll(wxCommandEvent& event);
	void OnMenuItem14Selected(wxCommandEvent& event);
	void OnMenuCameraTrackingArbitrary(wxCommandEvent& event);
	void OnmnuItemShowCloudOctreesSelected(wxCommandEvent& event);
	void OnmnuItemChangeMaxPointsPerOctreeNodeSelected(wxCommandEvent& event);
	void OnmnuSceneStatsSelected(wxCommandEvent& event);
	void OnMenuPrintScene(wxCommandEvent& event);
	void OnMenuItemImportPLYPointCloud(wxCommandEvent& event);
	void OnMenuItemExportPointsPLY(wxCommandEvent& event);
	void OnMenuItemHighResRender(wxCommandEvent& event);
	void OnmnuSelectionDeleteSelected(wxCommandEvent& event);
	void OnmnuSelectionScaleSelected(wxCommandEvent& event);
	void OnmnuSelectByClassSelected(wxCommandEvent& event);
	void OnmnuSelectNoneSelected(wxCommandEvent& event);
	void OnmnuImportLASSelected(wxCommandEvent& event);
	//*)
	void OnmnuImportImageView(wxCommandEvent& event);

	void OntimAutoplay(wxTimerEvent& event);

	//(*Identifiers(_DSceneViewerFrame)
	static const long ID_BUTTON1;
	static const long ID_BUTTON2;
	static const long ID_STATICLINE1;
	static const long ID_BUTTON3;
	static const long ID_BUTTON4;
	static const long ID_BUTTON5;
	static const long ID_STATICLINE2;
	static const long ID_BUTTON6;
	static const long ID_BUTTON7;
	static const long ID_BUTTON8;
	static const long ID_BUTTON9;
	static const long ID_STATICLINE3;
	static const long ID_BUTTON10;
	static const long ID_BUTTON11;
	static const long ID_MENUITEM1;
	static const long ID_MENUITEM2;
	static const long ID_MENUITEM5;
	static const long ID_MENUITEM7;
	static const long ID_MENUITEM6;
	static const long ID_MENUITEM_ImportImage;
	static const long ID_MENUITEM20;
	static const long ID_MENUITEM25;
	static const long ID_MENUITEM19;
	static const long ID_MENUITEM22;
	static const long ID_MENUITEM21;
	static const long ID_MENUITEM29;
	static const long ID_MENUITEM30;
	static const long ID_MENUITEM12;
	static const long ID_MENUITEM23;
	static const long ID_MENUITEM18;
	static const long ID_MENUITEM_PRINT_TEXT;
	static const long idMenuQuit;
	static const long ID_MENUITEM24;
	static const long ID_MENUITEM26;
	static const long ID_MENUITEM27;
	static const long ID_MENUITEM28;
	static const long ID_MENUITEM4;
	static const long ID_MENUITEM3;
	static const long ID_MENUITEM15;
	static const long ID_MENUITEM17;
	static const long ID_MENUITEM16;
	static const long ID_MENUITEM11;
	static const long ID_MENUITEM9;
	static const long ID_MENUITEM8;
	static const long ID_MENUITEM10;
	static const long ID_MENUITEM14;
	static const long ID_MENUITEM13;
	static const long idMenuAbout;
	static const long ID_STATUSBAR1;
	static const long ID_TIMER1;
	//*)

	static const long ID_TRAVELLING_TIMER;
	static const long ID_TIMER_AUTOPLAY;

	//(*Declarations(_DSceneViewerFrame)
	wxMenuItem* MenuItem8;
	wxMenuItem* MenuItemImportImage;
	wxMenuItem* mnuSelectionDelete;
	wxMenuItem* MenuItem7;
	wxCustomButton* btnCapture;
	wxCustomButton* btnNew;
	wxCustomButton* btnNext;
	wxMenuItem* MenuItem5;
	wxMenu* Menu3;
	wxMenu* MenuItem20;
	wxMenuItem* MenuItem14;
	wxCustomButton* btnToolbarOpen;
	wxMenuItem* mnuItemChangeMaxPointsPerOctreeNode;
	wxCustomButton* btnQuit;
	wxCustomButton* btnAutoplay;
	wxMenuItem* MenuItem22;
	wxMenuItem* MenuItem10;
	wxStaticLine* StaticLine2;
	wxMenuItem* MenuItem24;
	wxCustomButton* btnOptions;
	wxMenuItem* mnuSelectNone;
	wxMenuItem* mnuSceneStats;
	wxMenuItem* mnuPrintScene;
	wxMenuItem* mnuSelectionScale;
	wxMenuItem* mnuImportLAS;
	wxCustomButton* btnOrtho;
	wxStatusBar* StatusBar1;
	wxMenuItem* MenuItem6;
	wxStaticLine* StaticLine3;
	wxStaticLine* StaticLine1;
	wxMenuItem* MenuItem23;
	wxTimer timLoadFileCmdLine;
	wxCustomButton* btnAbout;
	wxMenuItem* MenuItem21;
	wxMenuItem* mnuSelectByClass;
	wxMenuItem* MenuItem16;
	wxMenuItem* MenuItem9;
	wxMenu* MenuItem18;
	wxMenuItem* mnuItemShowCloudOctrees;
	wxCustomButton* btnReload;
	wxCustomButton* btnPrev;
	wxMenu* Menu4;
	wxMenuItem* MenuItem19;
	wxMenu* MenuItem11;
	wxMenu* MenuItem17;
	//*)

	CMyGLCanvas* m_canvas;
	std::unique_ptr<wxTimer> m_autoplayTimer;

	/** The list of currently selected objects */
	std::vector<mrpt::opengl::CRenderizable::Ptr> m_selected_gl_objects;

	wxTimer m_tTravelling;
	bool m_travelling_is_arbitrary;
	std::optional<mrpt::Clock::time_point> m_travelling_start_time;

	int m_nTicksNumber;
	double m_nCurrentAzimuth;
	int maxv;
	void loadFromFile(const std::string& fil, bool isInASequence = false);
	void updateTitle();
	void clear_all_octrees_in_scene();

	CDlgCamTracking* m_dlg_tracking;

	DECLARE_EVENT_TABLE()
};

#endif	// _DSCENEVIEWERMAIN_H
