/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2008.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: src/drivers/wintel32/graphics/opengl/win32openglgraphics.cpp

*/

#include "sgx/core/core.hpp"
#include "sgx/filesystem/filesystem.hpp"
#include "sgx/graphics/graphics.hpp"

#include "drivers/common/opengl/opengl.hpp"

#include "drivers/wintel32/graphics/opengl/opengl.hpp"


UTCTime CWin32OpenGLEngine::m_PreviousTime;


void
CSGXDriverWintel32OpenGL::create() {
}

CSGXGraphicsEngine *CWin32OpenGLEngine::create(const sgxString &appname, const tUINT32 width, const tUINT32 height)
{
	m_pSingleton = new CWin32OpenGLEngine(appname, width, height);
	if (m_pSingleton) {
		m_pSingleton->initialize();
	}
	return m_pSingleton;
}


CWin32OpenGLEngine::CWin32OpenGLEngine(const sgxString &appname, const tUINT32 width, const tUINT32 height)
: COpenGLEngine(appname, width, height)
{
}

CWin32OpenGLEngine::~CWin32OpenGLEngine()
{
	enterWindowedMode();
}

CWin32OpenGLEngine *CWin32OpenGLEngine::getWin32()
{
	return static_cast<CWin32OpenGLEngine *>(m_pSingleton);
}


void CWin32OpenGLEngine::idleScene()
{
	UTCTime current_time;
	tREAL32 telaps, modifiedTelaps;


	// This will update+draw the frame, using the previous
	// timing information
	COpenGLEngine::idleScene();

	// This sets up the new time data ready for the next frame
	current_time = CSystemClock::getTime();
	telaps = current_time.timeBetween(m_PreviousTime);

	CWin32OpenGLEngine::m_PreviousTime = current_time;
	
	modifiedTelaps = CGameClock::get()->update(telaps);
	
	// Let CPU breath
	tREAL32 sleep = modifiedTelaps - telaps;

	if (sleep > 0) {
		sgxSleep(sleep);
	}
}

void CWin32OpenGLEngine::runEngine(cb_pOpenGLIdleFunction *pFn, const tMEM_SIZE param)
{
	m_PreviousTime = CSystemClock::getTime();

	COpenGLEngine::runEngine(pFn, param);
}

void CWin32OpenGLEngine::fullScreenMode()
{
	// Snippet taken from GameTutorials by Ben Humphrey (DigiBen)

	const tUINT32 SCREEN_WIDTH = 640;
	const tUINT32 SCREEN_HEIGHT = 480;
	DEVMODE dmSettings;									// Device Mode variable

	memset(&dmSettings,0,sizeof(dmSettings));			// Makes Sure Memory's Cleared

	// get current settings -- This function fills our the settings
	// This makes sure NT and Win98 machines change correctly
	if(!EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dmSettings))
	{
		// Display error message if we couldn't get display settings
		MessageBox(NULL, "Could Not Enum Display Settings", "Error", MB_OK);
		return;
	}

	dmSettings.dmPelsWidth	= SCREEN_WIDTH;				// Selected Screen Width
	dmSettings.dmPelsHeight	= SCREEN_HEIGHT;			// Selected Screen Height
	dmSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

	// This function actually changes the screen to full screen
	// CDS_FULLSCREEN Gets Rid Of start Bar.
	// We always want to get a result from this function to check if we failed
	int result = ChangeDisplaySettings(&dmSettings,CDS_FULLSCREEN);	

	// Check if we didn't recieved a good return message From the function
	if(result != DISP_CHANGE_SUCCESSFUL)
	{
		// Display the error message and quit the program
		MessageBox(NULL, "Display Mode Not Compatible", "Error", MB_OK);
		PostQuitMessage(0);
	}
/*
    g_hDC = GetDC(g_hWnd);								// This sets our global HDC
														// We don't free this hdc until the end of our program
    if (!bSetupPixelFormat(g_hDC))						// This sets our pixel format/information
        PostQuitMessage (0);							// If there's an error, quit

    g_hRC = wglCreateContext(g_hDC);					// This creates a rendering context from our hdc
    wglMakeCurrent(g_hDC, g_hRC);						// This makes the rendering context we just created the one we want to use
*/
}

void CWin32OpenGLEngine::enterWindowedMode()
{
	ChangeDisplaySettings(NULL, 0);
}

