#ifdef WIN32
//Windows screensaver code borrowed from Rachel Grey
// http://www.cityintherain.com/howtoscr.html

#include <direct.h>
#include <windows.h>
#include <scrnsave.h>
#include <GL/gl.h>

//Includes from main.cpp
#include "globals.h"
#include "dna.h"
#include "world.h"

World* world;

int config();
void timer( int );
void kdone( unsigned char, int, int );
void mdone( int, int );
void load();
void loadsettings();
void savesettings();
void loadimages( int*, char*** );
int save();

extern Settings settings;
//^Includes from main.cpp^

//globals used by the function below to hold the screen size
int Width;	
int Height;

//define a Windows timer 
#define TIMER 1 


static void InitGL(HWND hWnd, HDC & hDC, HGLRC & hRC)
{
  PIXELFORMATDESCRIPTOR pfd;
  ZeroMemory( &pfd, sizeof pfd );
  pfd.nSize = sizeof pfd;
  pfd.nVersion = 1;
  pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
  pfd.iPixelType = PFD_TYPE_RGBA;
  pfd.cColorBits = 24;
  
  hDC = GetDC( hWnd );
  
  int i = ChoosePixelFormat( hDC, &pfd );  
  SetPixelFormat( hDC, i, &pfd );

  hRC = wglCreateContext( hDC );
  wglMakeCurrent( hDC, hRC );

}
 
static void CloseGL(HWND hWnd, HDC hDC, HGLRC hRC)
{
  wglMakeCurrent( NULL, NULL );
  wglDeleteContext( hRC );
  ReleaseDC( hWnd, hDC );
}

// Screen Saver Procedure
LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT message, 
                               WPARAM wParam, LPARAM lParam)
{
  static HDC hDC;
  static HGLRC hRC;
  static RECT rect;

  int argc = 0; 
  char** argv = 0;

  switch ( message ) {

  case WM_CREATE: 
    // get window dimensions
    GetClientRect( hWnd, &rect );
    Width = rect.right;		
    Height = rect.bottom;
    
    //get configuration from registry if applicable
	chdir( getenv( "SystemRoot" ) );
 	chdir( "system32" );
	loadsettings();

    //set up OpenGL
    InitGL( hWnd, hDC, hRC );

    //Initialize perspective, viewpoint, and
    //any objects you wish to animate
	loadimages( &argc, &argv );
	world = new World( argc, argv );
	world->Resize( Width, Height );

	// Thanks to Adrian for making this work!
	// And thanks to Matt for helping me test the problem that
	// manifested only on his machine and noplace else.
	glEnable( GL_BLEND );
	glEnable( GL_POLYGON_SMOOTH );
	glEnable( GL_LINE_SMOOTH );
	glBlendFunc (GL_SRC_ALPHA, GL_ONE);
	glHint( GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE );
	glShadeModel( GL_SMOOTH );

    //create a timer that ticks every 10 milliseconds
    SetTimer( hWnd, TIMER, 10, NULL ); 
    return 0;
 
  case WM_DESTROY:
    KillTimer( hWnd, TIMER );
    
    //delete any objects created during animation
    //and close down OpenGL nicely
	chdir( getenv( "SystemRoot" ) );
 	chdir( "system32" );
	world->Save();
	delete world;

    CloseGL( hWnd, hDC, hRC );
    return 0;

  case WM_TIMER:
    //call some function to advance your animation
    world->Step();
	world->Display();
	SwapBuffers( hDC );
	glFlush();
    return 0;

  //handle special keypresses
  case WM_KEYDOWN:
	  	switch ( wParam )
		{
		case 'c':
		case 'C':
			world->CycleCameraMode();
			return 0;
		case 'b':
		case 'B':
			world->CycleDisplayBuffer();
			return 0;
		case 'v':
		case 'V':
			world->CycleChaseCam();
			return 0;
		case 'n':
		case 'N':
			world->CycleImage();
			return 0;
		case 'x':
		case 'X':
			world->CycleDrawCreatures();
			return 0;
		}
  case WM_KEYUP:
	  switch ( wParam )
	  {
		case 'c':
		case 'C':
		case 'b':
		case 'B':
		case 'V':
		case 'v':
		case 'n':
		case 'N':
		case 'x':
		case 'X':
			return 0;
	  }
  //let the screensaver library take care of any
  //other messages
  }
  return DefScreenSaverProc( 
    hWnd, message, wParam, lParam );
}

BOOL WINAPI
ScreenSaverConfigureDialog(HWND hDlg, UINT message, 
                           WPARAM wParam, LPARAM lParam)
{
	return true;
}

// needed for SCRNSAVE.LIB
BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
	chdir( getenv( "SystemRoot" ) );
 	chdir( "system32" );
  	loadsettings();
	savesettings();

	STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
	GetStartupInfo( &si );
	si.dwFlags |= STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_SHOWNORMAL;

    ZeroMemory( &pi, sizeof(pi) );

    // Start the child process. 
    if( !CreateProcess( NULL, // No module name (use command line). 
        "notepad Scenesaver.cfg", // Command line. 
        NULL,             // Process handle not inheritable. 
        NULL,             // Thread handle not inheritable. 
        FALSE,            // Set handle inheritance to FALSE. 
        0,                // No creation flags. 
        NULL,             // Use parent's environment block. 
        NULL,             // Use parent's starting directory. 
        &si,              // Pointer to STARTUPINFO structure.
        &pi )             // Pointer to PROCESS_INFORMATION structure.
    ) 
    {
        return false;
    }

    // Wait until child process exits.
    WaitForSingleObject( pi.hProcess, INFINITE );

    // Close process and thread handles. 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );

	return true;
}

#endif //WIN32