/*
 * $Id: glwindow.h 4578 2017-06-22 20:14:06Z antonin.misek-skoda-auto.cz $
 *
 * Description  : GL canvas class with OpenGL contents.
 * Author       : Vaclav Kyba <mail/Jabber: vaseo1@gmail.com>  <ICQ: 98576293>
 *
 * Purpose      :
 *     GLWindow is associated with certain RenderModule and uses its interface
 *     for rendering.
 */


#ifndef __GLWINDOW__H__
#define __GLWINDOW__H__

#include <stdlib.h>
#if !(defined VRUT_HPC)
#include <GL/glew.h>
#else
#include "OGLconstants.h"
#endif
#include <wx/glcanvas.h>
#include "rendermodule.h"
#include "framerate.h"
#include <wx/image.h>
#include "moddefs.h"

#include "VrutApi.h"

namespace VRUT
{
	class RenderModule;
	class RenderManager;

	///GL window class
	class VRUT_CORE_API GLWindow : public
#if !(defined VRUT_HPC)
		wxGLCanvas
#else
		wxWindow
#endif
	{
	private:
		///Pointer to \c RenderManager
		RenderManager * renderManager;

	protected:
		///Assigned render window ID
		RENDER_WINDOW_ID windowID;
		///Module implementing drawing method
		RenderModule * module;
		///Alternative parent for fullscreen view
		wxWindow * fsWindow;
		///Topmost window used for fullscreen
		wxFrame * fsFrame;
		///Gl context associated with window
#if !(defined VRUT_HPC)
		wxGLContext *glContext;
#else
		wxWindow *glContext;
#endif

		///Framerate counter
		FrameRate frameRate;
		///Page index in render windows notebook - auxiliary for fullscreen
		int nbPageIndex;
		///Prevents GTK bad behaviour when reparenting GLCanvas - auxiliary for fullscreen
		unsigned beingReparented;

		///Class constructor
		GLWindow();
		///On paint event method
		void onPaint(wxPaintEvent & WXUNUSED(evt));
		///On window resize event method
		void onResize(wxSizeEvent & evt);
		///Set window ID and propagate key event to event handler
		void onKeyEvent(wxKeyEvent & evt);
		///Set window ID and propagate mouse event to event handler
		void onMouseEvent(wxMouseEvent & evt);

	public:
		///Class constructor
		GLWindow(wxWindow * parent, RenderModule * _module, RENDER_WINDOW_ID winID, wxPoint position = wxDefaultPosition, wxSize size = wxDefaultSize, int * attribList = (int *)NULL, wxString title = wxT("GLWindow"));
		///Class destructor
		virtual ~GLWindow();

		///Get window ID
		RENDER_WINDOW_ID GetID() const
		{
			return windowID;
		}
		///Deinitialize window and associated module's data on window close
		void Deinitialize(NODE_ID protectedCameraID = -1);
		///Set \c RenderManager pointer - to inform manager when window is destroyed
		void SetRenderManager(RenderManager * _renderManager)
		{
			renderManager = _renderManager;
		}
		///Get associated render module
		RenderModule * GetRenderModule() const
		{
			return module;
		}

#if !(defined VRUT_HPC)
		///Create GL context
#if wxCHECK_VERSION(3, 1, 0)
		bool CreateGLContext(const wxGLContext * sharedContext = nullptr, wxGLContextAttrs* attributes = nullptr);
#else
		bool CreateGLContext(const wxGLContext * sharedContext = nullptr, const int *attributes = nullptr);
#endif

		///Get associated GL context
		wxGLContext * GetGLContext() const
		{
			return glContext;
		}
#endif

		void ShowCursor(bool show)
		{
			if (show)
				SetCursor(wxCursor(wxCURSOR_ARROW));
			else
			{
				wxImage curr(1, 1);
				curr.SetMask();
				curr.SetMaskColour(0,0,0);
				SetCursor(wxCursor(curr));
			}
		}

		void Focus();
		///Enable/disable fullscreen, if windowSetup is null show fullscreen on primary monitor
		void SetFullscreen(int fsMode, const int posX, const int posY, const int sizeX, const int sizeY, const unsigned long colorRGB);
		///Switch to/from fullscreen
		void ToggleFullscreen();

		friend class RenderManager;
	};
}

#endif
