#pragma once

#include "PixelFormat.h"

#include "GlInclude.h"


namespace lib_gl
{


//! windows GUI 用OpenGLレンダリングコンテキスト管理クラス
class CHglrc
{
public:
	CHglrc(void)
		: m_hdc(NULL)
		, m_hglrc(NULL)
	{}

	~CHglrc(void)
	{
		Release();
	}

	//! 初期化。pfdを指定しない場合はよく利用されるような標準設定で初期化する.
	bool Init(HDC i_hdc);
	bool Init(HDC i_hdc, const PIXELFORMATDESCRIPTOR& i_pfd);

	//! ファイナライズ.
	bool Release(void);

	//! 初期化済みか確認する.
	bool IsInitialized(void) const;

	//! Init_GLのpfd無し版で使用するpfdを返す.
	const PIXELFORMATDESCRIPTOR& GetStandardPFD(void) const;

	//! 現在のレンダリングコンテキストをアクティブにする.
	void BeginDraw(void) const;
	//! レンダリングコンテキストを非アクティブにする.
	void EndDraw(void) const;

	//! ダブルバッファリング時のプライマリバッファ更新.
	void SwapBuffers(void) const;
	void Refresh(void) const;

	HDC   GetHDC(void)   const { return m_hdc;   }
	HGLRC GetHGLRC(void) const { return m_hglrc; }

	bool HasHDC(void)   const { return m_hdc   != NULL ; }
	bool HasHGLRC(void) const { return m_hglrc != NULL ; }

private:
	CHglrc(const CHglrc&) {}
	void operator=(const CHglrc&) {}

protected:
	HDC   m_hdc;
	HGLRC m_hglrc;
};



inline
bool CHglrc::Init(HDC i_hdc)
{
	return Init( i_hdc , GetStandardPFD() );
}

inline
bool CHglrc::Init(HDC i_hdc, const PIXELFORMATDESCRIPTOR& i_pfd)
{
	if( m_hdc != NULL || m_hglrc != NULL )
		return false;

	if( !CPixelFormat::SetPFD( i_hdc , i_pfd ) )
		return false;

	m_hglrc = wglCreateContext( i_hdc );

	if( m_hglrc == NULL )
		return false;

	m_hdc = i_hdc;
	
	return true;
}

inline
bool CHglrc::Release(void)
{
	if( m_hglrc == NULL )
		return false;

	wglMakeCurrent( NULL , NULL );
	if( wglDeleteContext( m_hglrc ) == FALSE )
		return false;

	m_hdc   = NULL ;
	m_hglrc = NULL ;
	return true;
}

inline
bool CHglrc::IsInitialized(void) const
{
	return ( m_hdc != NULL );
}


inline
const PIXELFORMATDESCRIPTOR& CHglrc::GetStandardPFD(void) const
{
	return CPixelFormat::GetStandardPFD();
}

inline
void CHglrc::BeginDraw(void) const
{
	wglMakeCurrent( m_hdc , m_hglrc );
}

inline
void CHglrc::EndDraw(void) const
{
	wglMakeCurrent( m_hdc , 0 );
}

inline
void CHglrc::SwapBuffers(void) const
{
	::SwapBuffers( m_hdc );
}

// TODO : 旧仕様
inline
void CHglrc::Refresh(void) const
{
	SwapBuffers();
}


}
