/*
 * $Id: mainwindow.cpp 4933 2018-04-26 13:50:38Z ext.lukas.ruzicka@skoda-auto.cz $
 *
 * Description  : One line description of file.
 * Author       : Vaclav Kyba <mail/Jabber: vaseo1@gmail.com>  <ICQ: 98576293>
 *
 * Purpose      :
 *     Long description of what the file is for.
 */


#include <wx/menu.h>
#include <wx/msgdlg.h>
#include <wx/aboutdlg.h> 
#include <wx/artprov.h>
#include <wx/filedlg.h>
#include <wx/popupwin.h>
#include <wx/combobox.h>
#include <wx/button.h>

#include "mainwindow.h"

#ifdef GUI_RIBBON_BAR
 #include <wx/ribbon/bar.h>
 #include <wx/ribbon/buttonbar.h>
 #include <wx/ribbon/toolbar.h>

#include "../data/resources/modules/module_unknown.png.h"
#include "../data/resources/modules/AdamsToDG.png.h"
#include "../data/resources/modules/ArHud.png.h"
#include "../data/resources/modules/AutoTest.png.h"
#include "../data/resources/modules/CANPeak.png.h"
#include "../data/resources/modules/CarHW.png.h"
#include "../data/resources/modules/ClippingEditor.png.h"
#include "../data/resources/modules/Cluster.png.h"
#include "../data/resources/modules/Cluster2.png.h"
#include "../data/resources/modules/collision_detection.png.h"
#include "../data/resources/modules/C3Dconnexion.png.h"
#include "../data/resources/modules/C3DMenu.png.h"
#include "../data/resources/modules/FITTracer.png.h"
#include "../data/resources/modules/GIRT.png.h"
#include "../data/resources/modules/IO3d.png.h"
#include "../data/resources/modules/IOAc3d.png.h"
#include "../data/resources/modules/IOCsb.png.h"
#include "../data/resources/modules/IODof.png.h"
#include "../data/resources/modules/IOFbx.png.h"
#include "../data/resources/modules/IOFhs.png.h"
#include "../data/resources/modules/IOIges.png.h"
#include "../data/resources/modules/IOImage.png.h"
#include "../data/resources/modules/IOJt.png.h"
#include "../data/resources/modules/IOJtTk.png.h"
#include "../data/resources/modules/IOObj.png.h"
#include "../data/resources/modules/IOOsb.png.h"
#include "../data/resources/modules/IOPly.png.h"
#include "../data/resources/modules/IORdf.png.h"
#include "../data/resources/modules/IOStl.png.h"
#include "../data/resources/modules/IOVrml.png.h"
#include "../data/resources/modules/IOVrut.png.h"
#include "../data/resources/modules/JSScripting.png.h"
#include "../data/resources/modules/LeapMotion.png.h"
#include "../data/resources/modules/LightEditor.png.h"
#include "../data/resources/modules/MaterialAssign.png.h"
#include "../data/resources/modules/MaterialEditor.png.h"
#include "../data/resources/modules/Navigation.png.h"
#include "../data/resources/modules/Optimize.png.h"
#include "../data/resources/modules/RayTracer.png.h"
#include "../data/resources/modules/RenderGl.png.h"
#include "../data/resources/modules/RenderGl2.png.h"
#include "../data/resources/modules/RenderGl3.png.h"
#include "../data/resources/modules/Render4x.png.h"
#include "../data/resources/modules/SceneGraph.png.h"
#include "../data/resources/modules/SeatStitcher.png.h"
#include "../data/resources/modules/SoundRenderer.png.h"
#include "../data/resources/modules/Tesselator.png.h"
#include "../data/resources/modules/TextureManager.png.h"
#include "../data/resources/modules/TrackingManipulator.png.h"
#include "../data/resources/modules/Tracking.png.h"
#include "../data/resources/modules/Traffic.png.h"
#include "../data/resources/modules/Variants.png.h"
#include "../data/resources/modules/VehicleSimulator.png.h"
#include "../data/resources/modules/VirtualTraining.png.h"
#include "../data/resources/modules/VRender.png.h"
#include "../data/resources/modules/Wiimote.png.h"
#endif /* GUI_RIBBON_BAR */

//#include "flexilog.h"
#include "kernel.h"
#include "draganddrop.h"
#include "iomanager.h"
#include "manipmanager.h"
#include "generalmanager.h"
#include "glwindow.h"
#include "rendermanager.h"
#include "shortcuts.h"

#include "../data/resources/main.png.h"
#include "../data/resources/file_new.png.h"
#include "../data/resources/file_open.png.h"
#include "../data/resources/file_open_no_render.png.h"
#include "../data/resources/file_add.png.h"
#include "../data/resources/file_add_active.png.h"
#include "../data/resources/file_save.png.h"
#include "../data/resources/file_save_as.png.h"
#include "../data/resources/file_save_active.png.h"
#include "../data/resources/file_save_all.png.h"
#include "../data/resources/file_close_active.png.h"
#include "../data/resources/file_close_all.png.h"
#include "../data/resources/file_exit.png.h"
#include "../data/resources/logging.png.h"
#include "../data/resources/logging_point.png.h"
#include "../data/resources/view_console.png.h"
#include "../data/resources/view_log.png.h"
#include "../data/resources/view_render.png.h"
#include "../data/resources/view_parameters.png.h"
#include "../data/resources/view_save_layout.png.h"
#include "../data/resources/view_shortcuts.png.h"
#include "../data/resources/help_help_en.png.h"
#include "../data/resources/help_help_cz.png.h"
#include "../data/resources/help_about.png.h"
#ifdef GUI_STATUS_BAR
#include "../data/resources/view_statusbar_32.xpm"
#endif /* GUI_STATUS_BAR */
#include <wx/mimetype.h>


using namespace VRUT;


MainWindow::MainWindow(const wxString& title, const wxPoint& pos, const wxSize& size, const wxString &appPath) : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size)
{
	wxMemoryInputStream istream(main_png, sizeof(main_png));
	wxImage img(istream, wxBITMAP_TYPE_PNG);
	wxIcon icon;
	icon.CopyFromBitmap(wxBitmap(img));
	SetIcon(icon);
	iconsSize = 32;
#ifdef GUI_RIBBON_BAR
	initializeIcons();
	/*for (IconsHashMap::iterator it=iconsHashMap.begin(); it!=iconsHashMap.end(); ++it)
		fprintf(stderr, (it->first+(it->second.IsOk()?wxT(" is OK"):wxT(" is BAD"))).char_str());*/
	//wxBitmap bmpFileSave = wxBITMAP_PNG_FROM_DATA(main);

	wxSizer* boxSizer = new wxBoxSizer(wxVERTICAL);
	panel = new wxPanel(this, wxID_ANY);
#endif /* GUI_RIBBON_BAR */
	auiMgr.SetManagedWindow( GetSubWindowParent() );
#if 0
	auiMgr.GetArtProvider()->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, *wxBLUE);
	auiMgr.GetArtProvider()->SetColour(wxAUI_DOCKART_SASH_COLOUR, *wxBLUE);
	auiMgr.GetArtProvider()->SetColour(wxAUI_DOCKART_BORDER_COLOUR, *wxBLUE);
#endif
	
#ifdef GUI_STATUS_BAR
	wxImage iViewStatus(view_statusbar_xpm);
	wxBitmap bmpViewStatus(iViewStatus);
#endif /* GUI_STATUS_BAR */

	logLevelMenu = new wxMenu;
	wxMenuItem *mi = new wxMenuItem(0, ID_MainWin_LogDisable, wxT("&Disable"), wxT("Stop logging"), wxITEM_RADIO, 0);
	mi->SetBitmap(GetIcon(wxT("logging_point"), 10));
	logLevelMenu->Append(mi);
	mi = new wxMenuItem(0, ID_MainWin_LogError, wxT("&Errors"), wxT("Log error messages only"), wxITEM_RADIO, 0);
	mi->SetBitmap(GetIcon(wxT("logging_point"), 10));
	logLevelMenu->Append(mi);
	mi = new wxMenuItem(0, ID_MainWin_LogWarning, wxT("&Warnings"), wxT("Log warnings and errors"), wxITEM_RADIO, 0);
	mi->SetBitmap(GetIcon(wxT("logging_point"), 10));
	logLevelMenu->Append(mi);
	mi = new wxMenuItem(0, ID_MainWin_LogMessage, wxT("&Messages"), wxT("Log standard messages and higher priority messages"), wxITEM_RADIO, 0);
	mi->SetBitmap(GetIcon(wxT("logging_point"), 10));
	logLevelMenu->Append(mi);
	mi = new wxMenuItem(0, ID_MainWin_LogAll, wxT("&All"), wxT("Log all messages"), wxITEM_RADIO, 0);
	mi->SetBitmap(GetIcon(wxT("logging_point"), 10));
	logLevelMenu->Append(mi)->Check();
	/*logLevelMenu->AppendRadioItem(ID_MainWin_LogDisable, wxT("&Disable"), wxT("Stop logging"));
	logLevelMenu->AppendRadioItem(ID_MainWin_LogError, wxT("&Errors"), wxT("Log error messages only"));
	logLevelMenu->AppendRadioItem(ID_MainWin_LogWarning, wxT("&Warnings"), wxT("Log warnings and errors"));
	logLevelMenu->AppendRadioItem(ID_MainWin_LogMessage, wxT("&Messages"), wxT("Log standard messages and higher priority messages"));
	logLevelMenu->AppendRadioItem(ID_MainWin_LogAll, wxT("&All"), wxT("Log all messages"))->Check();*/

#ifdef GUI_STATUS_BAR
	///Status bar
	CreateStatusBar();
	GetStatusBar()->SetStatusText(_("Ready"));
#endif /* GUI_STATUS_BAR */

#ifdef GUI_RIBBON_BAR
	ribbonBar = new wxRibbonBar(this, ID_MainWin_Ribbon_Toolbar, wxDefaultPosition, wxDefaultSize, wxRIBBON_BAR_FLOW_HORIZONTAL | wxRIBBON_BAR_SHOW_PAGE_LABELS | wxRIBBON_BAR_SHOW_PANEL_EXT_BUTTONS | wxRIBBON_BAR_SHOW_TOGGLE_BUTTON);
	//ribbonBar->GetArtProvider()->SetColourScheme(*wxBLUE, *wxLIGHT_GREY, *wxLIGHT_GREY);
	ribbonBar->GetArtProvider()->SetColourScheme(*wxLIGHT_GREY, *wxWHITE, *wxWHITE);

	wxRibbonPage* fileRibbonPage = new wxRibbonPage(ribbonBar, wxID_ANY, wxT("File"), wxNullBitmap);
	wxRibbonPage* loggingRibbonPage = new wxRibbonPage(ribbonBar, wxID_ANY, wxT("Logging"), wxNullBitmap);
	wxRibbonPage* viewRibbonPage = new wxRibbonPage(ribbonBar, wxID_ANY, wxT("View"), wxNullBitmap);
	wxRibbonPage* modulesRibbonPage = new wxRibbonPage(ribbonBar, wxID_ANY, wxT("Modules"), wxNullBitmap);
	wxRibbonPage* helpRibbonPage = new wxRibbonPage(ribbonBar, wxID_ANY, wxT("Help"), wxNullBitmap);

	// File page
	wxRibbonPanel *filePanel = new wxRibbonPanel(fileRibbonPage, wxID_ANY, wxT(""), wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE /*| wxRIBBON_PANEL_EXT_BUTTON*/);
	wxRibbonToolBar *fileToolbar = new wxRibbonToolBar(filePanel, ID_MainWin_File_Toolbar);
	fileToolbar->AddTool(ID_MainWin_File_New,					GetIcon(wxT("file_new")),			wxT("New scene and render"));
	fileToolbar->AddTool(wxID_OPEN,								GetIcon(wxT("file_open")),			wxT("Open and render"));
	fileToolbar->AddTool(ID_MainWin_File_Open_No_Render,		GetIcon(wxT("file_open_no_render")),	wxT("Open without rendering"));
	fileToolbar->AddSeparator();
	fileToolbar->AddTool(ID_MainWin_File_Add,					GetIcon(wxT("file_add")),			wxT("Add to selected scene"));
	fileToolbar->AddTool(ID_MainWin_File_Add_To_Active_Scene,	GetIcon(wxT("file_add_active")),		wxT("Add to active scene"));
	fileToolbar->AddSeparator();
	fileToolbar->AddTool(ID_MainWin_File_Save,					GetIcon(wxT("file_save")),			wxT("Save selected scenes"));
	fileToolbar->AddTool(ID_MainWin_File_Save_As,				GetIcon(wxT("file_save_as")),		wxT("Save as selected scenes"));
	fileToolbar->AddTool(ID_MainWin_File_Save_Active_Scene,		GetIcon(wxT("file_save_active")),	wxT("Save active scene"));
	fileToolbar->AddTool(ID_MainWin_File_Save_All_Scenes,		GetIcon(wxT("file_save_all")),		wxT("Save all scenes"));
	fileToolbar->AddSeparator();
	fileToolbar->AddTool(ID_MainWin_File_Close_Active_Scene,	GetIcon(wxT("file_close_active")),	wxT("Close active scene"));
	fileToolbar->AddTool(ID_MainWin_File_Close_All_Scenes,		GetIcon(wxT("file_close_all")),		wxT("Close all scenes"));
	fileToolbar->AddSeparator();
	fileToolbar->AddTool(wxID_EXIT,								GetIcon(wxT("file_exit")),			wxT("Exit application"));

	/* just for testing purposes
	wxRibbonButtonBar *closeFileToolbar = new wxRibbonButtonBar(closeFilePanel, ID_MainWin_CloseFile_Toolbar);
	closeFileToolbar->AddButton(ID_MainWin_File_Close_Active_Scene, wxT(""), bmpFileCloseActive, wxT("Close active scene"));
	closeFileToolbar->AddButton(ID_MainWin_File_Close_All_Scenes,   wxT(""), bmpFileCloseAll,    wxT("Close all scenes"));
	*/

	Connect(ID_MainWin_File_New,                 wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);
	Connect(wxID_OPEN,                           wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_File_Open_No_Render,      wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_File_Save,                wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_File_Save_As,             wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_File_Save_Active_Scene,   wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_File_Save_All_Scenes,     wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_File_Add,                 wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_File_Add_To_Active_Scene, wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_File_Close_Active_Scene,  wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_File_Close_All_Scenes,    wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);
	Connect(wxID_EXIT,                           wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onFileMenu), (wxObject *)NULL, this);

	// Logging page
	wxRibbonPanel *loggingPanel = new wxRibbonPanel(loggingRibbonPage, wxID_ANY, wxT(""), wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE /*| wxRIBBON_PANEL_EXT_BUTTON*/);
	wxRibbonToolBar *loggingToolbar = new wxRibbonToolBar(loggingPanel, ID_MainWin_Logging_Toolbar);
	loggingToolbar->AddHybridTool(ID_MainWin_Log, GetIcon(wxT("logging")), "Set logging level");

	Connect(ID_MainWin_Log, wxEVT_RIBBONTOOLBAR_DROPDOWN_CLICKED, wxRibbonToolBarEventHandler(MainWindow::OnLogLevelDropdown), (wxObject *)NULL, this);
	Connect(ID_MainWin_Log, wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onLogMenu), (wxObject *)NULL, this);

	// View page
	wxRibbonPanel *viewPanel = new wxRibbonPanel(viewRibbonPage, wxID_ANY, wxT(""), wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE /*| wxRIBBON_PANEL_EXT_BUTTON*/);
	viewToolbar = new wxRibbonToolBar(viewPanel, ID_MainWin_View_Toolbar);
	viewToolbar->AddToggleTool(ID_MainWin_View_Console,			GetIcon(wxT("view_console")), wxT("Show/hide console"));
	viewToolbar->AddToggleTool(ID_MainWin_View_Log,				GetIcon(wxT("view_log")), wxT("Show/hide log window"));
	viewToolbar->AddToggleTool(ID_MainWin_View_RenderNotebook,	GetIcon(wxT("view_render")), wxT("Show/hide Render window"));
	viewToolbar->AddToggleTool(ID_MainWin_View_Parameters,		GetIcon(wxT("view_parameters")), wxT("Show/hide Parameters window"));
#ifdef GUI_STATUS_BAR
	viewToolbar->AddToggleTool(ID_MainWin_View_Status, bmpViewStatus, wxT("Show/hide status bar"));
#endif /* GUI_STATUS_BAR */
	viewToolbar->AddSeparator();
	viewToolbar->AddTool(ID_MainWin_SaveWindowLayout,			GetIcon(wxT("view_save_layout")),    wxT("Save Window Layout"));
	viewToolbar->AddSeparator();
	viewToolbar->AddTool(ID_MainWin_View_Shortcuts,				GetIcon(wxT("view_shortcuts")), wxT("View application shortcuts"));

	viewToolbar->ToggleTool(ID_MainWin_View_Console, false);
	viewToolbar->ToggleTool(ID_MainWin_View_Log, false);
	viewToolbar->ToggleTool(ID_MainWin_View_RenderNotebook, true);
	viewToolbar->ToggleTool(ID_MainWin_View_Parameters, true);
#ifdef GUI_STATUS_BAR
	viewToolbar->ToggleTool(ID_MainWin_View_Status, true);
#endif /* GUI_STATUS_BAR */		

	Connect(ID_MainWin_View_Console,        wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onViewMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_View_Log,            wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onViewMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_View_RenderNotebook, wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onViewMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_View_Parameters,     wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onViewMenu), (wxObject *)NULL, this);
#ifdef GUI_STATUS_BAR
	Connect(ID_MainWin_View_Status,         wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onViewMenu), (wxObject *)NULL, this);
#endif /* GUI_STATUS_BAR */
	Connect(ID_MainWin_SaveWindowLayout,    wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onViewMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_View_Shortcuts,      wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onViewMenu), (wxObject *)NULL, this);

	// Modules page
	wxRibbonPanel *generalModulesPanel = new wxRibbonPanel(modulesRibbonPage, wxID_ANY, wxT("General modules"), wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE /*| wxRIBBON_PANEL_EXT_BUTTON*/);
	generalModulesToolbar = new wxRibbonToolBar(generalModulesPanel, ID_MainWin_GeneralModules_Toolbar);

	wxRibbonPanel *renderModulesPanel = new wxRibbonPanel(modulesRibbonPage, wxID_ANY, wxT("Render modules"), wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE /*| wxRIBBON_PANEL_EXT_BUTTON*/);
	renderModulesToolbar = new wxRibbonToolBar(renderModulesPanel, ID_MainWin_RenderModules_Toolbar);

	wxRibbonPanel *manipModulesPanel = new wxRibbonPanel(modulesRibbonPage, wxID_ANY, wxT("Manipulators"), wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE /*| wxRIBBON_PANEL_EXT_BUTTON*/);
	manipModulesToolbar = new wxRibbonToolBar(manipModulesPanel, ID_MainWin_ManipModules_Toolbar);

	wxRibbonPanel *ioModulesPanel = new wxRibbonPanel(modulesRibbonPage, wxID_ANY, wxT("IO modules"), wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE /*| wxRIBBON_PANEL_EXT_BUTTON*/);
	ioModulesToolbar = new wxRibbonToolBar(ioModulesPanel, ID_MainWin_IOModules_Toolbar);

	// Help page
	wxRibbonPanel *helpPanel = new wxRibbonPanel(helpRibbonPage, wxID_ANY, wxT(""), wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxRIBBON_PANEL_NO_AUTO_MINIMISE /*| wxRIBBON_PANEL_EXT_BUTTON*/);

	wxRibbonToolBar *helpToolbar = new wxRibbonToolBar(helpPanel, ID_MainWin_Help_Toolbar);
	helpToolbar->AddTool(wxID_HELP,				GetIcon(wxT("help_help_en")),	wxT("Help english"));
	helpToolbar->AddTool(ID_MainWin_Help_CZ,	GetIcon(wxT("help_help_cz")),	wxT("Help czech"));
	helpToolbar->AddSeparator();
	helpToolbar->AddTool(wxID_ABOUT,			GetIcon(wxT("help_about")),		wxT("About"));

	Connect(wxID_HELP, wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onHelpMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_Help_CZ, wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onHelpMenu), (wxObject *)NULL, this);
	Connect(wxID_ABOUT, wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onHelpMenu), (wxObject *)NULL, this);

	//ribbonBar->SetArtProvider(new wxRibbonAUIArtProvider);
	//ribbonBar->ShowPanels(false);
	ribbonBar->Realize();

	moduleMenu = NULL;

#endif /* GUI_RIBBON_BAR */

#ifdef VRUT_HPC
	wxLog::SetActiveTarget(new FlexiLog(appPath));
#else //VRUT_HPC
	///Log window
	long logStyle = wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH | wxTE_AUTO_URL | wxTE_LEFT | wxTE_BESTWRAP | wxTE_NOHIDESEL;
	loggingToolbar->AddSeparator();
	logPanel = new wxRibbonPanel(loggingRibbonPage);
	logCtrl = new wxTextCtrl(logPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, logStyle);
	wxLog::SetActiveTarget(new FlexiLog(logCtrl, appPath));
#endif //VRUT_HPC

	///Console
	helpToolbar->AddSeparator();
	consolePanel = new wxRibbonPanel(helpRibbonPage);
	console = new Console(consolePanel, appPath);
#ifndef VRUT_HPC
	console->SetDropTarget(new DropTarget(console, DropTarget::FILE, false));
#endif

	///Notebook for render windows
	renderNotebook = new wxAuiNotebook(GetSubWindowParent(), ID_MainWin_RenderNotebook, wxDefaultPosition, wxDefaultSize,
		wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_TAB_EXTERNAL_MOVE | wxAUI_NB_SCROLL_BUTTONS| wxAUI_NB_TOP | wxAUI_NB_CLOSE_ON_ALL_TABS | wxAUI_NB_WINDOWLIST_BUTTON);
	renderNotebook->SetName(RENDER_NOTEBOOK_NAME);
#ifndef VRUT_HPC
	renderNotebook->SetDropTarget(new DropTarget(this, DropTarget::FILE));
#endif
	/*renderNotebook->GetArtProvider()->SetColour(*wxBLUE);
	renderNotebook->GetArtProvider()->SetActiveColour(*wxBLUE);
	renderNotebook->SetBackgroundColour(*wxBLUE);
	renderNotebook->SetForegroundColour(*wxBLUE);*/

	renderNotebook->Show();
	auiMgr.AddPane(renderNotebook, wxAuiPaneInfo().DefaultPane().Name(RENDER_NOTEBOOK_NAME).Caption(RENDER_NOTEBOOK_NAME).Center().PinButton().BestSize(640, 480));
	auiMgr.Update();

#ifdef GUI_RIBBON_BAR
	boxSizer->Add(ribbonBar, 0, wxEXPAND);
	boxSizer->Add(panel, 1, wxEXPAND);
	SetSizer(boxSizer);
	Layout();
#endif /* GUI_RIBBON_BAR */

	///Connect event handler
	Connect(wxID_ANY, wxEVT_CLOSE_WINDOW, wxCloseEventHandler(MainWindow::onClose), (wxObject *)NULL, this);

	Connect(ID_MainWin_LogDisable, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::onLogMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_LogError, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::onLogMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_LogWarning, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::onLogMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_LogMessage, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::onLogMenu), (wxObject *)NULL, this);
	Connect(ID_MainWin_LogAll, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::onLogMenu), (wxObject *)NULL, this);

	GetSubWindowParent()->Connect(wxID_ANY, wxEVT_AUI_PANE_CLOSE, wxAuiManagerEventHandler(MainWindow::onPaneClose), (wxObject *)NULL, this);
	GetSubWindowParent()->Connect(ID_MainWin_RenderNotebook, wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiManagerEventHandler(MainWindow::onPaneSelect), (wxObject *)NULL, this);
	GetSubWindowParent()->Connect(ID_MainWin_RenderNotebook, wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, wxAuiNotebookEventHandler(MainWindow::onPaneRDown), (wxObject *)NULL, this);
	
#ifndef VRUT_HPC
	logCtrl->Connect(wxID_ANY, wxEVT_KEY_UP, wxKeyEventHandler(MainWindow::onKeyEvent), (wxObject *)NULL, this);
	this->SetDropTarget(new DropTarget(this, DropTarget::FILE));
#endif

	shortCutManager = new ShortCutManager();

	ShortCut shortCutCtrlC(wxMOD_CONTROL, (int)'C');
	shortCutManager->RegisterShortCut(shortCutCtrlC, ShortCutManager::ShortCutOwnerID::SHORTCUT_OWNER_MAINWINDOW, NULL, NULL, "", "Copy");
	ShortCut shortCutCtrlV(wxMOD_CONTROL, (int)'V');
	shortCutManager->RegisterShortCut(shortCutCtrlV, ShortCutManager::ShortCutOwnerID::SHORTCUT_OWNER_MAINWINDOW, NULL, NULL, "", "Paste");
	ShortCut shortCutCtrlX(wxMOD_CONTROL, (int)'X');
	shortCutManager->RegisterShortCut(shortCutCtrlX, ShortCutManager::ShortCutOwnerID::SHORTCUT_OWNER_MAINWINDOW, NULL, NULL, "", "Cut");

	//FlexiLog::SetTextCtrlLogging(false); // <- LUKAS_RUZICKA : uncommented = LOG is written only to file
}

MainWindow::~MainWindow()
{
	FlexiLog::SetTextCtrlLogging(false);

	auiMgr.UnInit();
	SAFE_DELETE(logLevelMenu);

	SAFE_DELETE(shortCutManager);

#ifdef GUI_RIBBON_BAR
	SAFE_DELETE(moduleMenu);

	while (!moduleToolsList.empty())
	{
		ModuleToolUserData *data = moduleToolsList.back();
		moduleToolsList.pop_back();
		delete data;
	}
#endif // GUI_RIBBON_BAR
	wxLog::DontCreateOnDemand();
	wxLog *tmplog=wxLog::SetActiveTarget(NULL);
	SAFE_DELETE(tmplog);
}

bool MainWindow::HandleShortCut(int modifiers, int keyCode)
{
	if (shortCutManager && keyCode != WXK_NONE)
		return shortCutManager->HandleShortCut(modifiers, keyCode);

	return false;
}

void MainWindow::ApplyVariantState(ShortCutManager::ShortCutOwnerID scID, ShortCutManager::ShortCutUserData* userData)
{
	if ((scID != ShortCutManager::SHORTCUT_OWNER_VARIANTS) || (userData == NULL))
		return;

	KERNEL->GetMessageSink()->PostEvent(GET_EVT_SCENE_VARIANT_ACTIVESTATE_SET(userData->data.variantData.sceneID, userData->data.variantData.variantID, userData->data.variantData.stateID));

	// !!!!!!!!!! nahradit volanim scene metody !!!!!!
}

#ifdef GUI_RIBBON_BAR

void MainWindow::initializeIcons()
{
#define ADDICONTOMAP(name) addIconToMap(name##_png, sizeof(name##_png), wxString(#name).Lower());

	ADDICONTOMAP(file_new);
	ADDICONTOMAP(file_open);
	ADDICONTOMAP(file_open_no_render);
	ADDICONTOMAP(file_add);
	ADDICONTOMAP(file_add_active);
	ADDICONTOMAP(file_save);
	ADDICONTOMAP(file_save_as);
	ADDICONTOMAP(file_save_active);
	ADDICONTOMAP(file_save_all);
	ADDICONTOMAP(file_close_active);
	ADDICONTOMAP(file_close_all);
	ADDICONTOMAP(file_exit);
	ADDICONTOMAP(logging);
	ADDICONTOMAP(logging_point);
	ADDICONTOMAP(view_console);
	ADDICONTOMAP(view_log);
	ADDICONTOMAP(view_render);
	ADDICONTOMAP(view_parameters);
	ADDICONTOMAP(view_save_layout);
	ADDICONTOMAP(view_shortcuts);
	ADDICONTOMAP(help_help_en);
	ADDICONTOMAP(help_help_cz);
	ADDICONTOMAP(help_about);

	ADDICONTOMAP(module_unknown);
	ADDICONTOMAP(AdamsToDG);
	ADDICONTOMAP(ArHud);
	ADDICONTOMAP(AutoTest);
	ADDICONTOMAP(CANPeak);
	ADDICONTOMAP(CarHW);
	ADDICONTOMAP(ClippingEditor);
	ADDICONTOMAP(Cluster);
	ADDICONTOMAP(Cluster2);
	ADDICONTOMAP(collision_detection);
	ADDICONTOMAP(C3Dconnexion);
	ADDICONTOMAP(C3DMenu);
	ADDICONTOMAP(FITTracer);
	ADDICONTOMAP(GIRT);
	ADDICONTOMAP(IO3d);
	ADDICONTOMAP(IOAc3d);
	ADDICONTOMAP(IOCsb);
	ADDICONTOMAP(IODof);
	ADDICONTOMAP(IOFbx);
	ADDICONTOMAP(IOFhs);
	ADDICONTOMAP(IOIges);
	ADDICONTOMAP(IOImage);
	ADDICONTOMAP(IOJt);
	ADDICONTOMAP(IOJtTk);
	ADDICONTOMAP(IOObj);
	ADDICONTOMAP(IOOsb);
	ADDICONTOMAP(IOPly);
	ADDICONTOMAP(IORdf);
	ADDICONTOMAP(IOStl);
	ADDICONTOMAP(IOVrml);
	ADDICONTOMAP(IOVrut);
	ADDICONTOMAP(JSScripting);
	ADDICONTOMAP(LeapMotion);
	ADDICONTOMAP(LightEditor);
	ADDICONTOMAP(MaterialAssign);
	ADDICONTOMAP(MaterialEditor);
	ADDICONTOMAP(Navigation);
	ADDICONTOMAP(Optimize);
	ADDICONTOMAP(RayTracer);
	ADDICONTOMAP(RenderGl);
	ADDICONTOMAP(RenderGl2);
	ADDICONTOMAP(RenderGl3);
	ADDICONTOMAP(Render4x);
	ADDICONTOMAP(SceneGraph);
	ADDICONTOMAP(SeatStitcher);
	ADDICONTOMAP(SoundRenderer);
	ADDICONTOMAP(Tesselator);
	ADDICONTOMAP(TextureManager);
	ADDICONTOMAP(TrackingManipulator);
	ADDICONTOMAP(Tracking);
	ADDICONTOMAP(Traffic);
	ADDICONTOMAP(Variants);
	ADDICONTOMAP(VehicleSimulator);
	ADDICONTOMAP(VirtualTraining);
	ADDICONTOMAP(VRender);
	ADDICONTOMAP(Wiimote);
}

wxImage MainWindow::GetModuleIcon(const wxString &moduleName, bool instancesEmpty)
{
	IconsHashMap::iterator pos=iconsHashMap.find(moduleName.Lower());
#ifndef NDEBUG
	if ((pos==iconsHashMap.end()) && (moduleName.size()>2))
		pos=iconsHashMap.find(moduleName.substr(0, moduleName.size()-2).Lower());
#endif
	wxImage result;
	if (pos!=iconsHashMap.end())
		result=pos->second.Scale(iconsSize, iconsSize, wxIMAGE_QUALITY_HIGH);
	else
		result=iconsHashMap[wxT("module_unknown")].Scale(iconsSize, iconsSize, wxIMAGE_QUALITY_HIGH);
	if (instancesEmpty)
		result=result.ConvertToGreyscale();
	if (KERNEL->IsPrefered(moduleName))
	{
		for (int i = 0; i < iconsSize; ++i)
		{
			if (i % 2 == 0)
			{
				result.SetRGB(i, 0, 255, 255, 255);
				result.SetRGB(i, iconsSize - 1, 255, 255, 255);
				result.SetRGB(0, i, 255, 255, 255);
				result.SetRGB(iconsSize - 1, i, 255, 255, 255);
			}
			else
			{
				result.SetRGB(i, 0, 0, 0, 0);
				result.SetRGB(i, iconsSize - 1, 0, 0, 0);
				result.SetRGB(0, i, 0, 0, 0);
				result.SetRGB(iconsSize - 1, i, 0, 0, 0);
			}
		}
	}
	else if (KERNEL->IsForbidden(moduleName))
	{
		for (int i = 0; i < iconsSize; ++i)
		{
			if (i % 2 == 0)
			{
				result.SetRGB(i, i, 255, 255, 255);
				result.SetRGB(iconsSize - 1 - i, i, 255, 255, 255);
			}
			else
			{
				result.SetRGB(i, i, 0, 0, 0);
				result.SetRGB(iconsSize - 1 - i, i, 0, 0, 0);
			}
		}
	}
	return result;
}

wxBitmap MainWindow::GetIcon(const wxString &iconName, int scaleTo)
{
	if (scaleTo == -1)
		scaleTo = iconsSize;
	IconsHashMap::iterator pos = iconsHashMap.find(iconName.Lower());
	if (pos != iconsHashMap.end())
		return wxBitmap(pos->second.Scale(scaleTo, scaleTo, wxIMAGE_QUALITY_HIGH));
	else
		return wxBitmap(iconsHashMap[wxT("module_unknown")].Scale(scaleTo, scaleTo, wxIMAGE_QUALITY_HIGH));
}

void MainWindow::ResizeIcons(int iconsSize)
{
	if (this->iconsSize == iconsSize)
		return;
	if (iconsSize!=-1)
		this->iconsSize = iconsSize;

	wxRibbonToolBar *tmp = (wxRibbonToolBar*)wxWindow::FindWindowById(ID_MainWin_File_Toolbar);
	tmp->SetToolNormalBitmap(ID_MainWin_File_New, GetIcon(wxT("file_new")));
	tmp->SetToolNormalBitmap(wxID_OPEN, GetIcon(wxT("file_open")));
	tmp->SetToolNormalBitmap(ID_MainWin_File_Open_No_Render, GetIcon(wxT("file_open_no_render")));
	tmp->SetToolNormalBitmap(ID_MainWin_File_Add, GetIcon(wxT("file_add")));
	tmp->SetToolNormalBitmap(ID_MainWin_File_Add_To_Active_Scene, GetIcon(wxT("file_add_active")));
	tmp->SetToolNormalBitmap(ID_MainWin_File_Save, GetIcon(wxT("file_save")));
	tmp->SetToolNormalBitmap(ID_MainWin_File_Save_As, GetIcon(wxT("file_save_as")));
	tmp->SetToolNormalBitmap(ID_MainWin_File_Save_Active_Scene, GetIcon(wxT("file_save_active")));
	tmp->SetToolNormalBitmap(ID_MainWin_File_Save_All_Scenes, GetIcon(wxT("file_save_all")));
	tmp->SetToolNormalBitmap(ID_MainWin_File_Close_Active_Scene, GetIcon(wxT("file_close_active")));
	tmp->SetToolNormalBitmap(ID_MainWin_File_Close_All_Scenes, GetIcon(wxT("file_close_all")));
	tmp->SetToolNormalBitmap(wxID_EXIT, GetIcon(wxT("file_exit")));

	tmp = (wxRibbonToolBar*)wxWindow::FindWindowById(ID_MainWin_Logging_Toolbar);
	tmp->SetToolNormalBitmap(ID_MainWin_Log, GetIcon(wxT("logging")));

	tmp = (wxRibbonToolBar*)wxWindow::FindWindowById(ID_MainWin_View_Toolbar);
	tmp->SetToolNormalBitmap(ID_MainWin_View_Console, GetIcon(wxT("view_console")));
	tmp->SetToolNormalBitmap(ID_MainWin_View_Log, GetIcon(wxT("view_log")));
	tmp->SetToolNormalBitmap(ID_MainWin_View_RenderNotebook, GetIcon(wxT("view_render")));
	tmp->SetToolNormalBitmap(ID_MainWin_View_Parameters, GetIcon(wxT("view_parameters")));
#ifdef GUI_STATUS_BAR
	tmp->SetToolNormalBitmap(ID_MainWin_View_Status, GetIcon(wxT("view_console")));
#endif /* GUI_STATUS_BAR */
	tmp->SetToolNormalBitmap(ID_MainWin_SaveWindowLayout, GetIcon(wxT("view_save_layout")));
	tmp->SetToolNormalBitmap(ID_MainWin_View_Shortcuts, GetIcon(wxT("view_shortcuts")));

	tmp = (wxRibbonToolBar*)wxWindow::FindWindowById(ID_MainWin_Help_Toolbar);
	tmp->SetToolNormalBitmap(wxID_HELP, GetIcon(wxT("help_help_en")));
	tmp->SetToolNormalBitmap(ID_MainWin_Help_CZ, GetIcon(wxT("help_help_cz")));
	tmp->SetToolNormalBitmap(wxID_ABOUT, GetIcon(wxT("help_about")));

	//update Modules toolbar
	wxRibbonToolBar *modulesToolbar;
	for (auto &moduleTool : moduleToolsList)
	{
		switch (moduleTool->managerType)
		{
		case SERVER_ID::IO_MANAGER:
			modulesToolbar = ioModulesToolbar;
			break;
		case SERVER_ID::RENDER_MANAGER:
			modulesToolbar = renderModulesToolbar;
			break;
		case SERVER_ID::MANIP_MANAGER:
			modulesToolbar = manipModulesToolbar;
			break;
		case SERVER_ID::GENERAL_MANAGER:
			modulesToolbar = generalModulesToolbar;
			break;
		default:
			LOGERROR(wxT("MainWindow::ResizeIcons: unknown module type"));
			continue;
		}
		ModuleList moduleInstances;
		KERNEL->GetModules(&moduleInstances, moduleTool->moduleName);
		wxImage iModule(GetModuleIcon(moduleTool->moduleName, moduleInstances.empty()));
		modulesToolbar->SetToolNormalBitmap(moduleTool->toolID, wxBitmap(iModule));
	}

	//update and repaint the whole toolbar
	wxRibbonBar *tmp2 = (wxRibbonBar*)wxWindow::FindWindowById(ID_MainWin_Ribbon_Toolbar);
	tmp2->Realize();
	tmp2->GetParent()->Layout();
	tmp2->GetParent()->Refresh();
}

void MainWindow::ModuleToolbarUpdate(MODULE_ID moduleID)
{
	MODULE_HANDLE_ID moduleHandleID = moduleID.GetHandleID();

	wxString moduleName;
	wxRibbonToolBar *modulesToolbar;

	switch (moduleID.GetServerID())
	{
		case SERVER_ID::MANIP_MANAGER:
		{
			ModuleHandle<ManipulatorModule> *moduleHandle = KERNEL->manipManager->getModuleHandle(moduleHandleID);
			moduleName = moduleHandle->GetFileName().GetName();
			break;
		}
		case SERVER_ID::IO_MANAGER:
		{
			ModuleHandle<IOModule> *moduleHandle = KERNEL->ioManager->getModuleHandle(moduleHandleID);
			moduleName = moduleHandle->GetFileName().GetName();
			break;
		}
		case SERVER_ID::RENDER_MANAGER:
		{
			ModuleHandle<RenderModule> *moduleHandle = KERNEL->renderManager->getModuleHandle(moduleHandleID);
			moduleName = moduleHandle->GetFileName().GetName();
			break;
		}
		case SERVER_ID::GENERAL_MANAGER:
		{
			ModuleHandle<Module> *moduleHandle = KERNEL->generalManager->getModuleHandle(moduleHandleID);
			moduleName = moduleHandle->GetFileName().GetName();
			break;
		}
		default:
			// unknown module manager type
			return;
	}

	// find tool to be updated
	for (auto &moduleTool : moduleToolsList)
	{
		if (moduleTool->moduleName == moduleName)
		{
			switch (moduleTool->managerType)
			{
				case SERVER_ID::IO_MANAGER:
					modulesToolbar = ioModulesToolbar;
					break;
				case SERVER_ID::RENDER_MANAGER:
					modulesToolbar = renderModulesToolbar;
					break;
				case SERVER_ID::MANIP_MANAGER:
					modulesToolbar = manipModulesToolbar;
					break;
				case SERVER_ID::GENERAL_MANAGER:
					modulesToolbar = generalModulesToolbar;
					break;
				default:
					// unknown module type
					return;
			}

			ModuleList moduleInstances;
			KERNEL->GetModules(&moduleInstances, moduleName);
			wxImage iModule(GetModuleIcon(moduleName, moduleInstances.empty()));
			modulesToolbar->SetToolNormalBitmap(moduleTool->toolID, wxBitmap(iModule));
			modulesToolbar->Refresh();
			break;
		}
	}
}

void MainWindow::onModuleInstance(wxCommandEvent & evt)
{
	int instanceIdx = evt.GetId() - ID_MainWin_ModuleInstances;

	wxString instanceName = moduleInstancesList.at(instanceIdx).first->GetName() + wxString::Format(".%lu", (unsigned long)moduleInstancesList.at(instanceIdx).second);

	if (paramsNotebook)
	{
		for (size_t idx=0; idx<paramsNotebook->GetPageCount(); idx++)
		{
			wxWindow *win = paramsNotebook->GetPage(idx);
			if (win->GetName() == instanceName)
			{
				paramsNotebook->SetSelection(idx);
				win->SetFocus();
				break;
			}
		}
	}
}

void MainWindow::OnModuleDropdown(wxRibbonToolBarEvent& evt)
{
	moduleInstancesList.clear();

	if (moduleMenu)
	{
		moduleMenu->Disconnect();
		SAFE_DELETE(moduleMenu);
	}
	moduleMenu = new wxMenu();

	int toolID = evt.GetId();

	wxString moduleName;
	bool found = false;

	// get tool data -> module info
	for (auto &moduleTool : moduleToolsList)
	{
		if (moduleTool->toolID == toolID)
		{
			moduleName = moduleTool->moduleName;
			if (found)
				LOGERROR(wxT("<MainWindow::onModule> toolID assigned twice."));
			found = true;
		}
	}

	if (!found)
	{
		LOGERROR(wxT("MainWindow::onModule() - invalid tool data pointer."));
		return;
	}

	// return value (bool) indicates whether there are any module instances or not
	if (KERNEL->GetModules(&moduleInstancesList, moduleName))
	{
		int moduleIdx = 0;

		for (auto &moduleInstance : moduleInstancesList)
		{
			//LOG(wxT("\t")+it->first->GetName()+wxString::Format(wxT(".%lu ("), (unsigned long)it->second)+it->first->GetID().ToString()+wxT(")"));

			wxMenuItem *menuItem = new wxMenuItem(moduleMenu, ID_MainWin_ModuleInstances+moduleIdx, moduleInstance.first->GetName()+wxString::Format(".%lu", (unsigned long)moduleInstance.second));

			moduleMenu->Append(menuItem);
			moduleIdx++;
		}

		moduleMenu->Connect(ID_MainWin_ModuleInstances, ID_MainWin_ModuleInstances+moduleIdx-1, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::onModuleInstance), (wxObject *)NULL, this);

		evt.PopupMenu(moduleMenu);
	}
}

void MainWindow::onModule(wxCommandEvent & evt)
{
	int toolID = evt.GetId();

	bool found = false;
	wxString moduleName;

	for (auto &moduleTool : moduleToolsList)
	{
		if (moduleTool->toolID == toolID)
		{
			moduleName = moduleTool->moduleName;
			if (found)
				LOGERROR(wxT("<MainWindow::onModule> toolID assigned twice."));
			found = true;
		}
	}

	if (!found)
	{
		LOGERROR(wxT("MainWindow::onModule() - invalid tool data pointer."));
		return;
	}

	if (moduleName.Upper().EndsWith(wxT("_D")))
		moduleName.RemoveLast(2);

	KERNEL->GetMessageSink()->PostEvent(GET_EVT_MODULE_RUN(moduleName));
}

void MainWindow::InitModulesToolbar(wxAuiNotebook *paramsNotebook)
{
	if (paramsNotebook)
		this->paramsNotebook = paramsNotebook;

	if (KERNEL->ioManager)
	{
		int moduleIdx = 0;
		std::vector<MODULE_HANDLE_ID> moduleHandles = KERNEL->ioManager->findModuleHandles(wxT("*"));
		for (auto &moduleHandleID : moduleHandles)
		{
			ModuleHandle<IOModule> *moduleHandle =  KERNEL->ioManager->getModuleHandle(moduleHandleID);

			ModuleList moduleInstances;
			moduleHandle->GetModules(&moduleInstances);

			wxString moduleName = moduleHandle->GetFileName().GetName();

			ModuleToolUserData *moduleToolUserData = new ModuleToolUserData(moduleName, SERVER_ID::IO_MANAGER, ID_MainWin_IOModule_Tool + moduleIdx);

			moduleToolsList.push_back(moduleToolUserData);

			if (moduleName.Upper().EndsWith(wxT("_D")))
				moduleName.RemoveLast(2);

			wxImage iModule(GetModuleIcon(moduleName, moduleInstances.empty()));
			ioModulesToolbar->AddHybridTool(moduleToolUserData->toolID, wxBitmap(iModule), moduleName);

			Connect(moduleToolUserData->toolID, wxEVT_RIBBONTOOLBAR_DROPDOWN_CLICKED, wxRibbonToolBarEventHandler(MainWindow::OnModuleDropdown), (wxObject *)NULL, this);
			Connect(moduleToolUserData->toolID, wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onModule), (wxObject *)NULL, this);

			moduleIdx++;
		}
	}

	if (KERNEL->renderManager)
	{
		int moduleIdx = 0;
		std::vector<MODULE_HANDLE_ID> moduleHandles = KERNEL->renderManager->findModuleHandles(wxT("*"));
		for (auto &moduleHandleID : moduleHandles)
		{
			ModuleHandle<RenderModule> *moduleHandle =  KERNEL->renderManager->getModuleHandle(moduleHandleID);

			ModuleList moduleInstances;
			moduleHandle->GetModules(&moduleInstances);

			wxString moduleName = moduleHandle->GetFileName().GetName();

			ModuleToolUserData *moduleToolUserData = new ModuleToolUserData(moduleName, SERVER_ID::RENDER_MANAGER, ID_MainWin_RenderModule_Tool + moduleIdx);

			moduleToolsList.push_back(moduleToolUserData);

			if (moduleName.Upper().EndsWith(wxT("_D")))
				moduleName.RemoveLast(2);

			wxImage iModule(GetModuleIcon(moduleName, moduleInstances.empty()));
			renderModulesToolbar->AddHybridTool(moduleToolUserData->toolID, wxBitmap(iModule), moduleName);

			Connect(moduleToolUserData->toolID, wxEVT_RIBBONTOOLBAR_DROPDOWN_CLICKED, wxRibbonToolBarEventHandler(MainWindow::OnModuleDropdown), (wxObject *)NULL, this);
			Connect(moduleToolUserData->toolID, wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onModule), (wxObject *)NULL, this);

			moduleIdx++;
		}
	}

	if (KERNEL->manipManager)
	{
		int moduleIdx = 0;
		std::vector<MODULE_HANDLE_ID> moduleHandles = KERNEL->manipManager->findModuleHandles(wxT("*"));
		for (auto &moduleHandleID : moduleHandles)
		{
			ModuleHandle<ManipulatorModule> *moduleHandle =  KERNEL->manipManager->getModuleHandle(moduleHandleID);

			ModuleList moduleInstances;
			moduleHandle->GetModules(&moduleInstances);

			wxString moduleName = moduleHandle->GetFileName().GetName();

			ModuleToolUserData *moduleToolUserData = new ModuleToolUserData(moduleName, SERVER_ID::MANIP_MANAGER, ID_MainWin_ManipModule_Tool + moduleIdx);

			moduleToolsList.push_back(moduleToolUserData);

			if (moduleName.Upper().EndsWith(wxT("_D")))
				moduleName.RemoveLast(2);

			wxImage iModule(GetModuleIcon(moduleName, moduleInstances.empty()));
			manipModulesToolbar->AddHybridTool(moduleToolUserData->toolID, wxBitmap(iModule), moduleName);

			Connect(moduleToolUserData->toolID, wxEVT_RIBBONTOOLBAR_DROPDOWN_CLICKED, wxRibbonToolBarEventHandler(MainWindow::OnModuleDropdown), (wxObject *)NULL, this);
			Connect(moduleToolUserData->toolID, wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onModule), (wxObject *)NULL, this);

			moduleIdx++;
		}
	}

	if (KERNEL->generalManager)
	{
		int moduleIdx = 0;
		std::vector<MODULE_HANDLE_ID> moduleHandles = KERNEL->generalManager->findModuleHandles(wxT("*"));
		for (auto &moduleHandleID : moduleHandles)
		{
			ModuleHandle<Module> *moduleHandle =  KERNEL->generalManager->getModuleHandle(moduleHandleID);

			ModuleList moduleInstances;
			moduleHandle->GetModules(&moduleInstances);

			wxString moduleName = moduleHandle->GetFileName().GetName();

			ModuleToolUserData *moduleToolUserData = new ModuleToolUserData(moduleName, SERVER_ID::GENERAL_MANAGER, ID_MainWin_GeneralModule_Tool + moduleIdx);

			moduleToolsList.push_back(moduleToolUserData);

			if (moduleName.Upper().EndsWith(wxT("_D")))
				moduleName.RemoveLast(2);

			wxImage iModule(GetModuleIcon(moduleName, moduleInstances.empty()));
			generalModulesToolbar->AddHybridTool(moduleToolUserData->toolID, wxBitmap(iModule), moduleName);

			Connect(moduleToolUserData->toolID, wxEVT_RIBBONTOOLBAR_DROPDOWN_CLICKED, wxRibbonToolBarEventHandler(MainWindow::OnModuleDropdown), (wxObject *)NULL, this);
			Connect(moduleToolUserData->toolID, wxEVT_RIBBONTOOLBAR_CLICKED, wxCommandEventHandler(MainWindow::onModule), (wxObject *)NULL, this);

			moduleIdx++;
		}
	}

	ribbonBar->Realize();
}
#endif /* GUI_RIBBON_BAR */

void MainWindow::onFileMenu(wxCommandEvent & evt)
{
	switch (evt.GetId())
	{
	case wxID_EXIT:
		{
			wxMessageDialog dial(this, wxT("Really quit?"), wxT("Really quit?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
			if (dial.ShowModal() == wxID_YES)
			{
				///This prevents calling process idle in \c EventHandler
				//Disconnect(wxID_ANY, wxEVT_IDLE);
				KERNEL->GetMessageSink()->PostEvent(GET_EVT_EXIT(), true);
			}
		}
		break;
	case ID_MainWin_File_New: // create new scene and render it
		{
			SCENE_ID newSceneID=KERNEL->sceneManager->AddScene(wxT("NewScene"), SCENE_ID_NONE);
			smart_pointer_v2<Scene> scene;
			KERNEL->sceneManager->GetScene(scene, newSceneID);
			if (scene)
			{
				NODE_ID	rootID=scene->Insert(smart_pointer<SceneNode>(new SceneNode(wxT("NewScene.vrut"), SceneNode::FILE_ROOT)), scene->GetRootID());
				KERNEL->GetMessageSink()->PostEvent(GET_EVT_RENDER_SCENE(newSceneID));
			}
		}
		break;
	case wxID_OPEN: // open and render the selected scenes
		{
			wxString fileSelector = KERNEL->ioManager->GetFileSelector();
			wxFileDialog fileOpenDialog(this, wxT("Import and render selected scenes"), wxEmptyString, wxEmptyString, fileSelector, wxFD_OPEN|wxFD_MULTIPLE|wxFD_FILE_MUST_EXIST);
			if (fileOpenDialog.ShowModal() == wxID_OK)
			{
				wxArrayString selectedFiles;
				fileOpenDialog.GetPaths(selectedFiles); // get full paths of all selected files

				for (auto &selectedFile : selectedFiles)
				{
					SCENE_ID newSceneID = KERNEL->sceneManager->GetNewSceneID();

					KERNEL->GetMessageSink()->PostEvent(GET_EVT_IO_SCENE_IMPORT(selectedFile, newSceneID), true);
					// todo: if import fails we have to remove scene with newSceneID since it is empty

					KERNEL->GetMessageSink()->PostEvent(GET_EVT_RENDER_SCENE(newSceneID));
				}
			}
		}
		break;
	case ID_MainWin_File_Open_No_Render: // open the selected scenes only (do not render it)
		{
			wxString fileSelector = KERNEL->ioManager->GetFileSelector();
			wxFileDialog fileOpenDialog(this, wxT("Import selected scenes"), wxEmptyString, wxEmptyString, fileSelector, wxFD_OPEN|wxFD_MULTIPLE|wxFD_FILE_MUST_EXIST);
			if (fileOpenDialog.ShowModal() == wxID_OK)
			{
				wxArrayString selectedFiles;
				fileOpenDialog.GetPaths(selectedFiles); // get full paths of all selected files

				for (auto &selectedFile : selectedFiles)
					KERNEL->GetMessageSink()->PostEvent(GET_EVT_IO_SCENE_IMPORT(selectedFile), true);
			}
		}
		break;
	case ID_MainWin_File_Save: // save selected scenes
		{
			std::vector<smart_pointer_v2<Scene> > scenes;
			KERNEL->sceneManager->GetScenes(scenes);

			if (scenes.empty())
				LOGWARNING(wxT("MainWindow: Currently there is no scene to save."));
			else
			{
				wxArrayInt selectedScenes;
				selectedScenes.push_back(0);

				if (scenes.size() > 1)
				{
					wxArrayString choices;
	
					for (auto &scene : scenes)
						choices.push_back(wxString::Format(wxT("%lu ("), (unsigned long)scene->GetID()) + scene->GetName() + wxT(")"));

					wxMultiChoiceDialog multiChoiceDialog(this, wxT("Select scenes you want to save."), wxT("Please select a scene"), choices);
					selectedScenes.clear();

					if (multiChoiceDialog.ShowModal() == wxID_OK)
						selectedScenes = multiChoiceDialog.GetSelections();
				}

				for (auto selectedScene : selectedScenes)
				{
					//the filename will be generated automatically from node name (path and extension will be used from closest ROOT)
					KERNEL->GetMessageSink()->PostEvent(GET_EVT_IO_SCENE_EXPORT(scenes[selectedScene]->GetID(), scenes[selectedScene]->GetRootID(), wxT("")), true);
				}
			}
		}
		break;
	case ID_MainWin_File_Save_As:
		{
			std::vector<smart_pointer_v2<Scene> > scenes;
			KERNEL->sceneManager->GetScenes(scenes);

			if (scenes.empty())
				LOGWARNING(wxT("MainWindow: Currently there is no scene to save as."));
			else
			{
				wxArrayInt selectedScenes;
				selectedScenes.push_back(0);

				if (scenes.size() > 1)
				{
					wxArrayString choices;
	
					for (auto &scene : scenes)
						choices.push_back(wxString::Format(wxT("%lu ("), (unsigned long)scene->GetID()) + scene->GetName() + wxT(")"));

					wxMultiChoiceDialog multiChoiceDialog(this, wxT("Select scenes you want to save as."), wxT("Please select scenes"), choices);
					selectedScenes.clear();

					if (multiChoiceDialog.ShowModal() == wxID_OK)
					{	
						selectedScenes = multiChoiceDialog.GetSelections();
					}
				}

				for (auto selectedScene : selectedScenes)
				{
					smart_pointer<SceneNode> snode;
					scenes[selectedScene]->GetNode(snode, scenes[selectedScene]->GetRootID());

					if (!snode)
					{
						LOGERROR(wxT("Cannot save scene") + scenes[selectedScene]->GetName() + wxT(", root node does not exist"));
						continue;
					}

					wxFileName wxFname("");
					wxFname = snode->GetName();

					//wxMessageBox(wxFname.GetFullPath(), wxT("Original path"));
					wxString fileSelector = KERNEL->ioManager->GetFileSelector();

					wxFileDialog fileSaveDialog(this, wxT("Save scene ")+wxString::Format(wxT("%lu ("), (unsigned long)scenes[selectedScene]->GetID()) + scenes[selectedScene]->GetName()
						+ wxT(")")+wxT(" as ..."), wxFname.GetPath(), wxFname.GetFullName(), fileSelector, wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
					if (fileSaveDialog.ShowModal() == wxID_OK)
						KERNEL->GetMessageSink()->PostEvent(GET_EVT_IO_SCENE_EXPORT(scenes[selectedScene]->GetID(), scenes[selectedScene]->GetRootID(), fileSaveDialog.GetPath()), true);
				}
			}
		}
		break;
	case ID_MainWin_File_Save_Active_Scene:
		{
			// get the scene with active renderer (if any)
			GLWindow *win = (GLWindow *)renderNotebook->GetCurrentPage();
			bool fail = true;

			if (win != NULL)
			{
				RenderModule *renderModule = win->GetRenderModule();
				if (renderModule != NULL)
				{
					fail = false;
					smart_pointer_v2<Scene> scene;
					VRUT::SCENE_ID sceneID = renderModule->GetSceneID();
					KERNEL->sceneManager->GetScene(scene, sceneID);

					// the filename will be generated automatically from node name (path and extension will be used from closest ROOT)
					KERNEL->GetMessageSink()->PostEvent(GET_EVT_IO_SCENE_EXPORT(sceneID, scene->GetRootID(), wxT("")), true);
				}
			}
			if (fail == true)
				LOGWARNING(wxT("Currently there is no active renderer to select the scene to save."));
		}
		break;
	case ID_MainWin_File_Save_All_Scenes:
		{
			std::vector<smart_pointer_v2<Scene> > scenes;
			KERNEL->sceneManager->GetScenes(scenes);

			if (scenes.empty())
				LOGWARNING(wxT("MainWindow: Currently there is no scene to save."));
			else
			{	
				for (auto &scene : scenes)
				{
					// the filename will be generated automatically from node name (path and extension will be used from closest ROOT)
					KERNEL->GetMessageSink()->PostEvent(GET_EVT_IO_SCENE_EXPORT(scene->GetID(), scene->GetRootID(), wxT("")), true);
				}
			}
		}
		break;
	case ID_MainWin_File_Add: // adds selected files into the scenegraph of the scene chosen by means of the wxSingleChoiceDialog
		{
			std::vector<smart_pointer_v2<Scene> > scenes;
			KERNEL->sceneManager->GetScenes(scenes);

			if (scenes.empty())
				LOGWARNING(wxT("MainWindow: Currently there is no scene to add into."));
			else
			{
				int addToScene = 0; // scene into which we will import selected files

				if (scenes.size() > 1) // more that one scene -> allow scene selection
				{
					wxArrayString choices;

					for (auto &scene : scenes)
						choices.push_back(wxString::Format(wxT("%lu ("), (unsigned long)scene->GetID()) + scene->GetName() + wxT(")"));

					wxSingleChoiceDialog singleChoiceDialog(this, wxT("Select a scene into which you want to add a selected file."), wxT("Please select a scene"), choices);
					singleChoiceDialog.SetSelection(addToScene);

					if (singleChoiceDialog.ShowModal() == wxID_OK)
					{
						addToScene = singleChoiceDialog.GetSelection();
					}
					else // cancel button pressed
					{
						addToScene = -1;
					}
				}

				if (addToScene != -1)
				{
					wxString fileSelector = KERNEL->ioManager->GetFileSelector();
					wxFileDialog fileOpenDialog(this, wxT("Add Files into the Scene ")+wxString::Format(wxT("%lu ("), (unsigned long)scenes[addToScene]->GetID()) + scenes[addToScene]->GetName() + wxT(")"),
						wxEmptyString, wxEmptyString, fileSelector, wxFD_OPEN|wxFD_MULTIPLE|wxFD_FILE_MUST_EXIST);
					if (fileOpenDialog.ShowModal() == wxID_OK)
					{
						wxArrayString selectedFiles;
						fileOpenDialog.GetPaths(selectedFiles); // get full paths of all selected files

						for (auto &selectedFile : selectedFiles)
							KERNEL->GetMessageSink()->PostEvent(GET_EVT_IO_SCENE_IMPORT(selectedFile, scenes[addToScene]->GetID(), scenes[addToScene]->GetRootID()), true);
					}
				}
			}
		}
		break;
	case ID_MainWin_File_Add_To_Active_Scene: // adds selected files into the scenegraph of the scene with active renderer window
		{
			// get the scene with active renderer (if any)
			GLWindow *win = (GLWindow *)renderNotebook->GetCurrentPage();
			bool fail = true;

			if (win != NULL)
			{
				RenderModule *renderModule = win->GetRenderModule();
				if (renderModule != NULL)
				{
					fail = false;

					VRUT::SCENE_ID sceneID = renderModule->GetSceneID();
					smart_pointer_v2<Scene> scene;
					KERNEL->sceneManager->GetScene(scene, sceneID);

					wxString fileSelector = KERNEL->ioManager->GetFileSelector();
					wxFileDialog fileOpenDialog(this, wxT("Add Files into the Active Scene ")+wxString::Format(wxT("%lu ("), (unsigned long)sceneID) + scene->GetName() + wxT(")"), wxEmptyString, wxEmptyString, fileSelector, wxFD_OPEN|wxFD_MULTIPLE|wxFD_FILE_MUST_EXIST);
					if (fileOpenDialog.ShowModal() == wxID_OK)
					{
						wxArrayString selectedFiles;
						fileOpenDialog.GetPaths(selectedFiles); // get full paths of all selected files

						for (auto &selectedFile : selectedFiles)
							KERNEL->GetMessageSink()->PostEvent(GET_EVT_IO_SCENE_IMPORT(selectedFile, sceneID, scene->GetRootID()), true);
					}
				}
			}
			if (fail == true)
			{
				// there is no active renderer window
				LOGWARNING(wxT("MainWindow: Currently there is no active renderer to select the scene to add into."));
			}
		}
		break;
	case ID_MainWin_File_Close_Active_Scene:
		{
			// get the scene with active renderer (if any)
			GLWindow *win = KERNEL->renderManager->GetActiveGLWindow();
			if (win)
			{
				RenderModule *renderModule = win->GetRenderModule();
				SCENE_ID sceneID=SCENE_ID_NONE;
				if (renderModule)
					sceneID = renderModule->GetSceneID();
				KERNEL->manipManager->StopManipulateCamera(win->GetID());
				delete win;
				// test zda je scena modifikovana -> ulozit (?da se to nejak poznat?)
				KERNEL->GetMessageSink()->PostEvent(GET_EVT_SCENE_REMOVE(sceneID));
			}
			else
				LOGWARNING(wxT("MainWindow: CloseActiveScene: no active window exists."));
		}
		break;
	case ID_MainWin_File_Close_All_Scenes:
		{
			for (GLWindow *win = KERNEL->renderManager->GetActiveGLWindow(); win; win = KERNEL->renderManager->GetActiveGLWindow())
			{
				KERNEL->manipManager->StopManipulateCamera(win->GetID());
				delete win;
			}
			std::vector<SCENE_ID> sceneIDs;
			KERNEL->sceneManager->GetSceneIDs(sceneIDs);
			for (auto sceneID : sceneIDs)
				KERNEL->GetMessageSink()->PostEvent(GET_EVT_SCENE_REMOVE(sceneID), true);
		}
		break;
/*
	case wxID_SAVE:
		LOG(wxT("Save"));
		break;
	case ID_MainWin_Scenes:
		LOG(wxT("menu Scenes"));
		break;
*/
	default:
		LOG(wxString::Format(wxT("unknown menu item %i, %i"), evt.GetId(), evt.GetInt()));
		break;
	}
}

#ifdef GUI_RIBBON_BAR
void MainWindow::OnLogLevelDropdown(wxRibbonToolBarEvent& evt)
{
	evt.PopupMenu(logLevelMenu);
}
#endif /* GUI_RIBBON_BAR */

void MainWindow::onViewMenu(wxCommandEvent & evt)
{
	switch (evt.GetId())
	{
	case ID_MainWin_View_Console:
#ifdef GUI_RIBBON_BAR
		{
			DockUnDockConsole(evt.IsChecked());
		}
		break;
#endif /* GUI_RIBBON_BAR */
	case ID_MainWin_View_Log:
#ifdef GUI_RIBBON_BAR
		{
			DockUnDockLog(evt.IsChecked());
		}
		break;
#endif /* GUI_RIBBON_BAR */

	case ID_MainWin_View_Parameters:
#ifdef GUI_RIBBON_BAR
		{
			auiMgr.GetPane(PARAMS_NOTEBOOK_NAME).Show(evt.IsChecked());
		}
		break;
#endif /* GUI_RIBBON_BAR */
	case ID_MainWin_View_RenderNotebook:
		{
#ifdef GUI_RIBBON_BAR
			auiMgr.GetPane(RENDER_NOTEBOOK_NAME).Show(evt.IsChecked());
#endif /* GUI_RIBBON_BAR */
		}
		break;
	case ID_MainWin_SaveWindowLayout:
		{
			KERNEL->VRUTConfig->Write(wxT("/MainWindow/aui_perspective"), auiMgr.SavePerspective());
			KERNEL->VRUTConfig->Write(wxT("/MainWindow/maximized"), IsMaximized());
			KERNEL->WinPosSizeToVRUTConfig(this, wxT("/MainWindow/"));
			KERNEL->VRUTConfig->Write(wxT("/MainWindow/LOGundocked"), !(logCtrl->GetParent() == logPanel));
			if (logCtrl->GetParent() != logPanel)
				KERNEL->WinPosSizeToVRUTConfig(logCtrl->GetParent(), wxT("/MainWindow/LOG"));
			KERNEL->VRUTConfig->Write(wxT("/MainWindow/CONSOLEundocked"), !(console->GetParent() == consolePanel));
			if (console->GetParent() != consolePanel)
				KERNEL->WinPosSizeToVRUTConfig(console->GetParent(), wxT("/MainWindow/CONSOLE"));
			((GUIEnvironment*)GetParamsNotebook())->StoreUserPerspective();
			KERNEL->SaveVRUTConfig();
		}
		break;
#ifdef GUI_STATUS_BAR
	case ID_MainWin_View_Status:
		{
			if (evt.IsChecked())
				SetStatusBar(CreateStatusBar());
			else
				SetStatusBar((wxStatusBar *)NULL);
		}
		break;
#endif /* GUI_STATUS_BAR */
	case ID_MainWin_View_Shortcuts:
		{
			wxDialog* dialog = new wxDialog( this, wxID_ANY,  wxT("Application shortcuts"));

			//dialog->SetSizeHints( wxDefaultSize, wxDefaultSize );

			wxBoxSizer* mainBoxSizer = new wxBoxSizer( wxVERTICAL );

			wxListCtrl *listCtrl = new wxListCtrl(dialog, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT);

			// Add first column
			wxListItem col0;
			col0.SetId(0);
			col0.SetText( wxT("module name") );
			listCtrl->InsertColumn(0, col0);

			// Add second column
			wxListItem col1;
			col1.SetId(1);
			col1.SetText( wxT("shortcut") );
			listCtrl->InsertColumn(1, col1);

			// Add third column
			wxListItem col2;
			col2.SetId(2);
			col2.SetText( wxT("description") );
			listCtrl->InsertColumn(2, col2);

			const int itemsCount = shortCutManager->ShortCutsCount();

			for (int i=0; i<itemsCount; i++)
			{
				ShortCutManager::ShortCutItem& currentItem = shortCutManager->GetShortCut(i);

				wxListItem item;
				item.SetId(i);
				item.SetText( wxString::Format("shortcut-%i", i) );

				listCtrl->InsertItem( item );

				// set value in first column
				listCtrl->SetItem(i, 0, currentItem.moduleName);
				// set value in second column
				listCtrl->SetItem(i, 1, shortCutManager->GetKeyName(currentItem.shortCut));
				// set value in third column
				listCtrl->SetItem(i, 2, currentItem.description); 
			}
			mainBoxSizer->Add( listCtrl, 0, wxALL|wxEXPAND, 5 );

			wxButton *okButton = new wxButton( dialog, wxID_OK );
			mainBoxSizer->Add( okButton, 1, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );

			listCtrl->SetColumnWidth (0, wxLIST_AUTOSIZE);
			listCtrl->SetColumnWidth (1, wxLIST_AUTOSIZE);
			listCtrl->SetColumnWidth (2, wxLIST_AUTOSIZE);

			dialog->SetSizerAndFit(mainBoxSizer);

			dialog->ShowModal();

		}
		break;
	}

	//Layout();
	auiMgr.Update();
}


void MainWindow::onLogMenu(wxCommandEvent & evt)
{
	int loglevel = 4;
	switch (evt.GetId())
	{
	case ID_MainWin_LogDisable:
		loglevel = 0;
		break;
	case ID_MainWin_LogError:
		loglevel = 1;
		break;
	case ID_MainWin_LogWarning:
		loglevel = 2;
		break;
	case ID_MainWin_LogMessage:
		loglevel = 3;
		break;
	case ID_MainWin_LogAll:
		loglevel = 4;
		break;
	default:
		LOGWARNING(wxT("Unknown log level. Ignored."));
		break;
	}
	FlexiLog::SetLogLevel(loglevel);
}

void MainWindow::onHelpMenu(wxCommandEvent & evt)
{
	switch (evt.GetId())
	{
	case wxID_ABOUT:
		{
			wxAboutDialogInfo aboutInfo;
			aboutInfo.SetName(wxT("VRUT"));
			wxString version(wxString::Format(wxT("SVN Rev: %i"), KERNEL->VRUTVersion()));
#if VRUT_LICENCE_VERSION & 2
			//time expiration
			wxString buildDateRaw(__DATE__);
			//read year
			long buildYear = 0;
			buildDateRaw.substr(buildDateRaw.size() - 4).ToLong(&buildYear);
			//read month
			wxString months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" };
			int buildMonth = 0;
			for (; buildMonth < 12; ++buildMonth)
				if (buildDateRaw.substr(0, 3) == months[buildMonth])
					break;
			//read day
			long buildDay = 0;
			buildDateRaw.substr(4).ToLong(&buildDay);
			wxDateTime buildDate(wxDateTime::Now());
			buildDate.SetYear(buildYear);
			buildDate.SetMonth((wxDateTime::Month)buildMonth);
			buildDate.SetDay(buildMonth);
			buildDate += wxDateSpan(0, 0, 0, 62);
#endif //VRUT_LICENCE_VERSION
			aboutInfo.SetVersion(version + wxT("\n") + wxVERSION_STRING/*wxGetLibraryVersionInfo().GetVersionString()*/ + ((sizeof(void*) == 8) ? wxT("\n64 bit") : wxT("\n32 bit"))
#ifdef NDEBUG
				+ wxT(" Release")
#else
				+ wxT(" Debug")
#endif
#ifdef _MSC_VER
				+ wxString::Format(wxT(" _MSC_VER=%i"), _MSC_VER)
#endif
#ifdef __VERSION__
				+ wxT(" __VERSION__=") + wxT(__VERSION__)
#endif
#ifdef __AVX2__
				+ wxT(" AVX2")
#else
#ifdef __AVX__
				+ wxT(" AVX")
#else
				//+ wxT(" SSE")
#endif
#endif
#ifdef VRUT_CORE_STATIC
				+ wxT("\nStatic build")
#else
				+ wxT("\nModular build")
#endif
#if VRUT_LICENCE_VERSION
				+ wxT("\nLicenced version")
#endif //VRUT_LICENCE_VERSION
#if VRUT_LICENCE_VERSION & 2
				+ wxT("\nLicence valid up to: ") + buildDate.FormatISODate()
#endif //VRUT_LICENCE_VERSION
				);
			aboutInfo.SetDescription(wxT("Virtual Reality Universal Toolkit"));
			aboutInfo.SetCopyright(wxT("(C) 2008-2018"));
			aboutInfo.AddDeveloper(wxString::FromUTF8("Antonín Míšek (antonin.misek@skoda-auto.cz)"));
			aboutInfo.AddDeveloper(wxString::FromUTF8("Jiří Bittner (bittner@fel.cvut.cz)"));
			aboutInfo.AddDeveloper(wxString::FromUTF8("Václav Kyba and others"));

			wxAboutBox(aboutInfo);
		}
		break;
	case wxID_HELP:
		{
			wxString docPath(KERNEL->GetAppPath()+wxT("doc")+wxFileName::GetPathSeparator()+wxT("doc_en.pdf"));
			if (!wxFile::Exists(docPath))
			{
				LOGERROR(wxT("EN documentation not found: ")+docPath);
				docPath=KERNEL->GetAppPath()+wxT("..")+wxFileName::GetPathSeparator()+wxT("documents")+wxFileName::GetPathSeparator()+wxT("doc_en.pdf");
				if (!wxFile::Exists(docPath))
				{
					LOGERROR(wxT("EN development documentation not found: ")+docPath);
					break;
				}
			}
			wxLaunchDefaultApplication(docPath);
		}
		break;
	case ID_MainWin_Help_CZ:
	{
		wxString docPath(KERNEL->GetAppPath()+wxT("doc")+wxFileName::GetPathSeparator()+wxT("doc_cz.pdf"));
		if (!wxFile::Exists(docPath))
		{
			LOGERROR(wxT("CZ documentation not found: ")+docPath);
			docPath=KERNEL->GetAppPath()+wxT("..")+wxFileName::GetPathSeparator()+wxT("documents")+wxFileName::GetPathSeparator()+wxT("doc_cz.pdf");
			if (!wxFile::Exists(docPath))
			{
				LOGERROR(wxT("CZ development documentation not found: ")+docPath);
				break;
			}
		}
		wxLaunchDefaultApplication(docPath);
	}
	break;	default:
		break;
	}
}

void MainWindow::ShowPane(int paneID, bool show)
{
#ifdef GUI_RIBBON_BAR
	if (paneID==ID_MainWin_View_Console)
		DockUnDockConsole(show);
	else if (paneID==ID_MainWin_View_Log)
		DockUnDockLog(show);
	else if (paneID==ID_MainWin_View_RenderNotebook)
		auiMgr.GetPane(RENDER_NOTEBOOK_NAME).Show(show);
	else if (paneID==ID_MainWin_View_Parameters)
		auiMgr.GetPane(PARAMS_NOTEBOOK_NAME).Show(show);
	else
		return;
	auiMgr.Update();
#endif
}

void MainWindow::SetUserPerspective(wxFileConfig *VRUTConfig)
{
	if (!VRUTConfig)
		return;
	wxString auiPerspective;
	if (VRUTConfig->Read(wxT("/MainWindow/aui_perspective"), &auiPerspective))
		GetAUIManager()->LoadPerspective(auiPerspective);

	KERNEL->WinPosSizeFromVRUTConfig(this, wxT("/MainWindow/"), wxPoint(100, 100), wxSize(800, 600));

	bool maximized = false;
	if (VRUTConfig->Read(wxT("/MainWindow/maximized"), &maximized))
		Maximize(maximized);

	if (VRUTConfig->ReadBool(wxT("/MainWindow/LOGundocked"), false))
		DockUnDockLog(true);

	if (VRUTConfig->ReadBool(wxT("/MainWindow/CONSOLEundocked"), false))
		DockUnDockConsole(true);

	GetAUIManager()->Update();
}

void MainWindow::onClose(wxCloseEvent & evt)
{
	if (KERNEL && KERNEL->GetMessageSink())
	{
		((GUIEnvironment*)paramsNotebook)->DockAll();//workaround preventing frozen window
		/*if (KERNEL && KERNEL->generalManager)
			KERNEL->generalManager->ReleaseManagerData();*/

		if (KERNEL->GetMessageSink()->FastExit())
#if defined(_MSC_VER) && (_MSC_VER <= 1800) // 1700 = Visual Studio 2012 - MSVC++ 11.0, 1800 = Visual Studio 2013 - MSVC++ 12.0, 1900 = Visual Studio 2015 - MSVC++ 14.0
			exit(0);
#else
			quick_exit(0); // supported from Visual Studio 2015
#endif
		///This prevents calling process idle from main window
		this->Disconnect(wxID_ANY, wxEVT_IDLE);
	}
	if (KERNEL && KERNEL->renderManager)
		KERNEL->renderManager->ReleaseManagerData();
	//SAFE_RELEASE(KERNEL);

	evt.Skip();
}


void MainWindow::onPaneClose(wxAuiManagerEvent & evt)
{
	if (!evt.pane)
	{
		evt.Skip();
		return;
	}

#ifdef GUI_RIBBON_BAR
	if (evt.pane->name.IsSameAs(CONSOLE_NOTEBOOK_NAME))
		viewToolbar->ToggleTool(ID_MainWin_View_Console, false);
	if (evt.pane->name.IsSameAs(LOG_NOTEBOOK_NAME))
		viewToolbar->ToggleTool(ID_MainWin_View_Log, false);
	if (evt.pane->name.IsSameAs(PARAMS_NOTEBOOK_NAME))
		viewToolbar->ToggleTool(ID_MainWin_View_Parameters, false);
	if (evt.pane->name.IsSameAs(renderNotebook->GetName()))
		viewToolbar->ToggleTool(ID_MainWin_View_RenderNotebook, false);
#endif /* GUI_RIBBON_BAR */

	evt.Skip();
}

void MainWindow::onPaneSelect(wxAuiManagerEvent & evt)
{
	GLWindow *win = (GLWindow *)renderNotebook->GetPage(renderNotebook->GetSelection());
	if (win)
	{
		RenderModule *renderModule = win->GetRenderModule();
		if (renderModule)
			KERNEL->GetMessageSink()->PostEvent(GET_EVT_RENDER_WIN_FOCUSED(((GLWindow *)renderNotebook->GetPage(renderNotebook->GetSelection()))->GetID(), renderModule->GetSceneID()));
	}
	//KERNEL->GetMessageSink()->PostEvent(GET_EVT_RENDER_WIN_FOCUSED(((GLWindow *)renderNotebook->GetPage(renderNotebook->GetSelection()))->GetID()));
	evt.Skip();
}

void MainWindow::onPaneRDown(wxAuiNotebookEvent & evt)
{
	GLWindow *win=(GLWindow *)renderNotebook->GetPage(evt.GetSelection());
	if (win)
	{
		RenderModule *renderModule=win->GetRenderModule();
		if (renderModule)
			KERNEL->GetMessageSink()->PostEvent(GET_EVT_SCENE_CAM_FIT(renderModule->GetSceneID(), renderModule->GetCameraID()));
	}
	evt.Skip();
}

void MainWindow::onKeyEvent(wxKeyEvent & evt)
{
	//Crtl+Alt+Shift+C to activate Console
	if ((evt.GetUnicodeKey()==wxT('C') || evt.GetUnicodeKey()==wxT('c')) && evt.AltDown() && evt.ControlDown() && evt.ShiftDown() && (evt.GetEventType()==wxEVT_KEY_UP))
	{
		//LOG(wxT("MainWindow Console focus"));
		this->SetFocusToConsole();
	}
	evt.Skip();
}

void MainWindow::DockUnDockLog(bool undock)
{
	if (logCtrl->GetParent() == logPanel)
	{
		if (undock)
		{
			wxWindow *frame = new wxFrame(this, wxID_ANY, LOG_NOTEBOOK_NAME);
			KERNEL->WinPosSizeFromVRUTConfig(frame, wxT("/MainWindow/LOG"), wxPoint(0, 0), wxSize(500, 400));
			logCtrl->Reparent(frame);
			frame->Show();
			frame->Connect(frame->GetId(), wxEVT_CLOSE_WINDOW, wxCloseEventHandler(MainWindow::OnUndockedLogClose), (wxObject *)NULL, this);
		}
	}
	else
	{
		if (!undock)
		{
			wxWindow *frame = logCtrl->GetParent();
			KERNEL->WinPosSizeToVRUTConfig(logCtrl->GetParent(), wxT("/MainWindow/LOG"));
			logCtrl->Reparent(logPanel);
			frame->Close();
			delete frame;
		}
	}
}

void MainWindow::DockUnDockConsole(bool undock)
{
	if (console->GetParent() == consolePanel)
	{
		if (undock)
		{
			wxWindow *frame = new wxFrame(this, wxID_ANY, CONSOLE_NOTEBOOK_NAME);
			console->Reparent(frame);
			KERNEL->WinPosSizeFromVRUTConfig(frame, wxT("/MainWindow/CONSOLE"), wxPoint(0, 0), wxSize(500, 60));
			frame->Show();
			frame->Connect(frame->GetId(), wxEVT_CLOSE_WINDOW, wxCloseEventHandler(MainWindow::OnUndockedConsoleClose), (wxObject *)NULL, this);
		}
	}
	else
	{
		if (!undock)
		{
			wxWindow *frame = console->GetParent();
			KERNEL->WinPosSizeToVRUTConfig(console->GetParent(), wxT("/MainWindow/CONSOLE"));
			console->Reparent(consolePanel);
			frame->Close();
			delete frame;
		}
	}
}

void MainWindow::FixLoglevelMenu(int logLevel)
{
	wxMenuItem * levelItem = (wxMenuItem *)NULL;

	int itemID = 0;
	switch (logLevel)
	{
	case 0:
		itemID = ID_MainWin_LogDisable;
		break;
	case 1:
		itemID = ID_MainWin_LogError;
		break;
	case 2:
		itemID = ID_MainWin_LogWarning;
		break;
	case 3:
		itemID = ID_MainWin_LogMessage;
		break;
	case 4:
		itemID = ID_MainWin_LogAll;
		break;
	}
	levelItem = logLevelMenu->FindItem(itemID);

	if (levelItem != NULL)
		levelItem->Check();
}
