/*
* $Id: mainwindow.h 4853 2018-02-16 13:30:36Z antonin.misek-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.
*/


#ifndef __MAIN_WINDOW__
#define __MAIN_WINDOW__

//the value 0 - unlicenced, 1 - standard licence, 2 - time expiration, 3 - licence with time expiration
//#define VRUT_LICENCE_VERSION 0
//#define GUI_STATUS_BAR
#define GUI_RIBBON_BAR

#ifdef GUI_RIBBON_BAR

#include <wx/ribbon/toolbar.h>
#include "moddefs.h"
#include <wx/mstream.h>
#endif /* GUI_RIBBON_BAR */

#include <wx/frame.h>
#include <wx/aui/aui.h>
#include "console.h"
//#include "common.h"
#include <wx/textfile.h>
#include <wx/fileconf.h>
#include <wx/wfstream.h>
#include "basedefs.h"
#include "shortcuts.h"

const wxString PARAMS_NOTEBOOK_NAME = wxT("Parameters");
const wxString RENDER_NOTEBOOK_NAME = wxT("Render");
const wxString CONSOLE_NOTEBOOK_NAME = wxT("Console");
const wxString LOG_NOTEBOOK_NAME = wxT("Log");


namespace VRUT
{
	class Module;
	class ShortCutManager;

	typedef std::pair<Module *, MODULE_INSTANCE_ID> ModulePair;
	typedef std::vector<ModulePair> ModuleList;

	///Main window class
	class MainWindow: public wxFrame
	{
	private:
		///Log level popup menu
		wxMenu * logLevelMenu;
		wxMenu * moduleMenu;

	protected:
		///AUI manager
		wxAuiManager auiMgr;
		///Notebook for render windows
		wxAuiNotebook * renderNotebook;
		Console* console;

		///Shortcut manager
		ShortCutManager* shortCutManager;

		wxRibbonPanel *consolePanel;
		wxRibbonPanel *logPanel;
		wxTextCtrl * logCtrl;

#ifdef GUI_RIBBON_BAR
		///Notebook for parameters windows
		wxAuiNotebook *paramsNotebook;

		///Parent window for console, log, and parameters and render notebooks
		wxPanel* panel;

		///View toolbar
		wxRibbonToolBar *viewToolbar;
		///Modules toolbars
		wxRibbonToolBar *ioModulesToolbar;
		wxRibbonToolBar *renderModulesToolbar;
		wxRibbonToolBar *manipModulesToolbar;
		wxRibbonToolBar *generalModulesToolbar;
		///Main ribbon toolbar
		wxRibbonBar* ribbonBar;

		typedef struct _ModuleToolUserData {
			wxString moduleName;
			SERVER_ID managerType;
			int toolID;
			_ModuleToolUserData(const wxString &moduleName, const SERVER_ID managerType, const int toolID) : moduleName(moduleName), managerType(managerType),toolID(toolID) {}
		} ModuleToolUserData;

		typedef std::vector<ModuleToolUserData *> ModuleToolList;

		ModuleToolList moduleToolsList;
		ModuleList moduleInstancesList;

		WX_DECLARE_STRING_HASH_MAP(wxImage, IconsHashMap);
		IconsHashMap iconsHashMap;
		void addIconToMap(const unsigned char *icon, size_t length, const wxString &iconName)
		{
			wxMemoryInputStream istream(icon, length);
			iconsHashMap[iconName]=wxImage(istream, wxBITMAP_TYPE_PNG);
		}
		void initializeIcons();
		wxImage GetModuleIcon(const wxString &moduleName, bool instancesEmpty);
		wxBitmap GetIcon(const wxString &iconName, int scaleTo=-1);//scaleTo - -1 automatic scaling
		void OnLogLevelDropdown(wxRibbonToolBarEvent& evt);
		void OnModuleDropdown(wxRibbonToolBarEvent& evt);
		void onModule(wxCommandEvent & evt);
		void onModuleInstance(wxCommandEvent & evt);
#endif /* GUI_RIBBON_BAR */

		///On file menu event
		void onFileMenu(wxCommandEvent & evt);
		///On view menu event
		void onViewMenu(wxCommandEvent & evt);
		///On log level change event
		void onLogMenu(wxCommandEvent & evt);
		///On help menu event
		void onHelpMenu(wxCommandEvent & evt);
		///On window close event method
		void onClose(wxCloseEvent & evt);
		///On pane close event method
		void onPaneClose(wxAuiManagerEvent & evt);
		///On pane select event method
		void onPaneSelect(wxAuiManagerEvent & evt);
		void onPaneRDown(wxAuiNotebookEvent & evt);
		void onKeyEvent(wxKeyEvent & evt);
		void OnUndockedLogClose(wxCloseEvent & evt)
		{
			DockUnDockLog(false);
			viewToolbar->ToggleTool(ID_MainWin_View_Log, false);
			evt.Veto();
		}
		void DockUnDockLog(bool undock);

		void OnUndockedConsoleClose(wxCloseEvent & evt)
		{
			DockUnDockConsole(false);
			viewToolbar->ToggleTool(ID_MainWin_View_Console, false);
			evt.Veto();
		}
		void DockUnDockConsole(bool undock);

	public:

		///Class constructor
		MainWindow(const wxString& title, const wxPoint& pos, const wxSize& size, const wxString &appPath);
		///Class destructor
		virtual ~MainWindow();

		ShortCutManager* GetShortCutManager(void)
		{
			return shortCutManager;
		}

		/// Handle shortcut given by key code and modifiers
		bool HandleShortCut(int modifiers, int keyCode);

		static void ApplyVariantState(ShortCutManager::ShortCutOwnerID scID, ShortCutManager::ShortCutUserData* userData);

		void RegisterVariantShortCut(ShortCut& sc, SCENE_ID sID, VARIANT_ID vID, size_t stateID)
		{
			if (!shortCutManager)
				return;

			// register new shortcut
			if (!shortCutManager->IsShortCutRegistered(sc))
			{
				ShortCutManager::ShortCutUserData *userData = new ShortCutManager::ShortCutUserData();

				userData->data.variantData.sceneID = sID;
				userData->data.variantData.variantID = vID;
				userData->data.variantData.stateID = stateID;

				wxString descriptionStr = wxString::Format("VariantSet [sceneID: %lu, variantID: %lu, stateID: %lu]", (unsigned long)userData->data.variantData.sceneID, (unsigned long)userData->data.variantData.variantID, (unsigned long)userData->data.variantData.stateID);
				shortCutManager->RegisterShortCut(sc, ShortCutManager::SHORTCUT_OWNER_VARIANTS, NULL, userData, wxT("Variants"), descriptionStr);
			}
		}

		void UnregisterVariantShortCut(ShortCut& sc, SCENE_ID sID, VARIANT_ID vID, size_t stateID)
		{
			if (!shortCutManager)
				return;

			// unregister shortcut
			if (shortCutManager->IsShortCutRegistered(sc))
			{
				ShortCutManager::ShortCutOwnerID scID;
				ShortCutManager::ShortCutCallback scCallback;
				ShortCutManager::ShortCutUserData *userData;

				shortCutManager->GetShortCutUserData(sc, scID, scCallback, userData);

				if ((scID == ShortCutManager::SHORTCUT_OWNER_VARIANTS) && (userData != NULL))
					if ((userData->data.variantData.sceneID == sID) && (userData->data.variantData.variantID == vID) && (userData->data.variantData.stateID == stateID))
					{
						shortCutManager->UnregisterShortCut(sc, scID);
					}
			}
		}

		///Fix loglevel menu item
		///Checks menu item according to current loglevel when changed in other way than menu selection
		void FixLoglevelMenu(int logLevel);
		///Get window's AUI manager
		wxAuiManager * GetAUIManager()
		{
			return &auiMgr;
		}
		///Get notebook with render windows
		wxAuiNotebook * GetRenderNotebook()
		{
			return renderNotebook;
		}
		///Get parent window for console, log, and parametrs and render notebooks
		wxWindow * GetSubWindowParent()
		{
#ifdef GUI_RIBBON_BAR
			return panel;
#else
			return this;
#endif /* GUI_RIBBON_BAR */
		}
#ifdef GUI_RIBBON_BAR
		void InitModulesToolbar(wxAuiNotebook *paramsNotebook=NULL);
		///On module start/release event
		void ModuleToolbarUpdate(MODULE_ID moduleID);
		int iconsSize;
		void ResizeIcons(int iconsSize=-1);
#endif /* GUI_RIBBON_BAR */
		wxAuiNotebook *GetParamsNotebook()
		{
			return paramsNotebook;
		}
		void SetFocusToConsole()
		{
			if (console)
				console->SetFocus();
		}

		void ShowPane(int paneID, bool show);

		void SetUserPerspective(wxFileConfig *VRUTConfig);
	};
}


#endif
