#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>

//Settings dialog (includes globals)
#include <qapplication.h>
#include "SettingsDialog.h"

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

World* world;

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 config file if applicable
	chdir( getenv( "SystemRoot" ) );
	chdir( "SYSTEM32" );
	mkdir( "Scenesaver" );
 	chdir( "Scenesaver" );
	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, Width, Height );
	world->Load();

	// 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" );
 	chdir( "Scenesaver" );
	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 'z':
		case 'Z':
			chdir( getenv( "SystemRoot" ) );
			chdir( "SYSTEM32" );
 			chdir( "Scenesaver" );
			world->ScreenShot( "Scenesaver.png" );
			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':
		case 'z':
		case 'Z':
			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" );
	mkdir( "Scenesaver" );
 	chdir( "Scenesaver" );
  	loadsettings();

	int argc = 1;
	char* argv[1];
	argv[0] = "SceneSaver";

	QApplication app( argc, argv );
	SettingsDialog diag;
	app.setMainWidget( &diag );
	diag.show();
	return ! (app.exec() == 0);
}

#endif //WIN32
