/*
								+---------------------------------+
								|                                 |
								|      ***   OpenGLDrv   ***      |
								|                                 |
								|  Copyright  © -tHE SWINe- 2002  |
								|                                 |
								|           OpenGLDrv.h           |
								|                                 |
								+---------------------------------+
*/

#pragma once
#ifndef __GL_DRIVER_INCLUDED
#define __GL_DRIVER_INCLUDED

/**
 *	@file gl2/OpenGLDrv.h
 *	@author -tHE SWINe-
 *	@date 2002
 *	@brief simple OpenGL driver
 *
 *	@date 2006-05-16
 *
 *	renamed arguments passed to CGLDriver::Init
 *	all integers storing only true or false values were replaced by bool
 *	erased all open-gl init code from CGLDriver::Init, but glDepthFunc(GL_LEQUAL); (default GL_LESS)
 *
 *	@date 2006-10-31
 *
 *	added bool CGLDriver::MakeCurrent()
 *	renamed bool CGLDriver::Terminate() to bool CGLDriver::Shutdown()
 *	propagated comments from .cpp to .h
 *
 *	@date 2006-11-01
 *
 *	added int CGLDriver::n_Width(), int CGLDriver::n_Height() and
 *	void CGLDriver::ResetViewport() functions
 *	parameters int n_depth_bpp and int n_stencil_bpp added to CGLDriver::Init function
 *
 *	@date 2006-11-13
 *
 *	fixed bug in n_depth_bpp and int n_stencil_bpp ussage in CGLDriver::Init function
 *	added CGLDriver::n_PixelFormat() and CGLDriver::t_Pixelormat() functions
 *	fixed function const-corectness
 *
 *	@date 2007-03-06
 *
 *	removed __declspec(dllexport)
 *
 *	@date 2008-03-04
 *
 *	__inline changed to inline
 *	added default value 32 of parameter n_bpp in CGLDriver::Init
 *
 *	@date 2009-10-20
 *
 *	added PFD_SWAP_EXCHANGE flag to pixel format descriptor. this makes SwapBuffers() faster,
 *	because back buffer isn't copied to front buffer, they are just exchanged. on the other hand,
 *	reading back buffer after swap yields unspecified results (previous frame mostly)
 *
 *	fixed some warnings when compiling under VC 2005, implemented "Security
 *	Enhancements in the CRT" for VC 2008. compare against MyProjects_2009-10-19_
 *
 *	@date 2012-06-19
 *
 *	Moved multiple inclusion guard before file documentation comment.
 *
 */

/**
 *	@brief OpenGL driver class
 */
class CGLDriver {
private:
    HDC m_h_dc;
    HGLRC m_h_glrc;
    HWND m_h_wnd;
    bool m_b_fullscreen;

    int m_n_width;
    int m_n_height;

    bool m_b_status;

	PIXELFORMATDESCRIPTOR m_t_pixel_format;
    GLuint m_n_pixel_format_id;

public:
	/**
	 *	@brief default constructor
	 */
    CGLDriver();

	/**
	 *	@brief destructor
	 */
    ~CGLDriver();

	/**
	 *	@brief creates OpenGL context
	 *
	 *	@param[in] h_wnd is window handle (only used to attach OpenGL context,
	 *		window dimensions and type remains unchanged)
	 *	@param[in] n_width is viewport width (may be equal to window width)
	 *	@param[in] n_height is viewport height (may be equal to window height)
	 *	@param[in] n_bpp is color bit depth
	 *	@param[in] n_depth_bpp is depth buffer bit depth (0 means no depth buffer)
	 *	@param[in] n_stencil_bpp is stencil buffer bit depth (0 means no stencil buffer)
	 *	@param[in] b_fullscreen is fullscreen flag; if true, it attempts to set display
	 *		mode with resolution n_width per n_height pixels and bit depth n_bpp and to
	 *		hide cursor
	 *
	 *	@return Returns true on success otherwise false.
	 *
	 *	@note Pops up message box with error description on failure.
	 */
    bool Init(HWND h_wnd, int n_width, int n_height, int n_bpp = 32,
		int n_depth_bpp = 24, int n_stencil_bpp = 0, bool b_fullscreen = false);

	/**
	 *	@brief terminates previously initalized context
	 *
	 *	If fulscreen mode was set, sets default fullscreen mode and shows cursor.
	 *
	 *	@return Returns true if no context was initialized or on succes, otherwise false
	 *
	 *	@note Pops up message box with error description on failure.
	 */
    bool Shutdown();

	/**
	 *	@brief gets driver status
	 *
	 *	@return Returns status of OpenGL (false = not initialized, true = running).
	 */
	bool b_Status() const;

	/**
	 *	@brief makes this OpenGL context current
	 *
	 *	@return Returns true on success, false on failure.
	 */
	bool MakeCurrent();

	/**
	 *	@brief gets original viewport width
	 *
	 *	@return Returns original viewport width.
	 */
	inline int n_Width() const { return m_n_width; }

	/**
	 *	@brief gets original viewport height
	 *
	 *	@return Returns original viewport height.
	 */
	inline int n_Height() const { return m_n_height; }

	/**
	 *	@brief gets pixel format
	 *
	 *	@return Returns pixel format descriptor.
	 */
	inline const PIXELFORMATDESCRIPTOR &t_PixelFormat() const { return m_t_pixel_format; }

	/**
	 *	@brief gets pixel format
	 *
	 *	@return Returns OpenGL pixel format id.
	 */
	inline GLuint n_PixelFormat() const { return m_n_pixel_format_id; }

	/**
	 *	@brief resets viewport to original size
	 *
	 *	Calls glViewport() with window dimensions.
	 */
	void ResetViewport() const;

	/**
	 *	@brief commits page flip (calls glSwapBuffers())
	 *
	 *	@note Doesn't call neither glFlush() nor glFinish().
	 */
    void Blit() const;
};

#endif // !__GL_DRIVER_INCLUDED
