// Skeletal rat engine

// INCLUDES ///////////////////////////////////////////////

#define WIN32_LEAN_AND_MEAN  // just say no to MFC

#include <winsock2.h>
#include <windows.h>   // include important windows stuff
#include <windowsx.h> 
#include <mmsystem.h>
#include <iostream.h> // include important C/C++ stuff
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h> 
#include <math.h>
#include <io.h>
#include <fcntl.h>

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>

#include "stringc.h"
#include "Assert.h"
#include "CGraphicSystem.h"
#include "CD3DManager.h"

// DEFINES ////////////////////////////////////////////////

// defines for windows 
#define WINDOW_CLASS_NAME "WINCLASS1"


// TYPES //////////////////////////////////////////////////////

// basic unsigned types
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char  UCHAR;
typedef unsigned char  BYTE;

// MACROS /////////////////////////////////////////////////

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// initializes a direct draw struct
#define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

// GLOBALS ////////////////////////////////////////////////
HWND      main_window_handle = NULL; // globally track main window
HINSTANCE hinstance_app      = NULL; // globally track hinstance



//DIRDRAW GLOBALS/////////////////////////////



// FUNCTION PROTOTYPES /////////////////////////////////////

void GameInit();
void GameMain();
void GameShutDown();

// directdraw stuff


// FUNCTIONS //////////////////////////////////////////////

// WINMAIN ////////////////////////////////////////////////

int WINAPI WinMain(	HINSTANCE hinstance, HINSTANCE hprevinstance,LPSTR lpcmdline,int ncmdshow)
{

	 int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
	 tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
	 _CrtSetDbgFlag(tmpFlag);

	// save hinstance in global
	hinstance_app = hinstance;

	CD3DManager* D3D = new CD3DManager();
	D3D->Create(hinstance);

	

	// return to Windows like this
	return D3D->Run(); ///(msg.wParam);

} // end WinMain

///////////////////////////////////////////////////////////


//////////////////////////




/**********************
*
* This little baby test an expression. If it fails it brings up a dialog box. You can ignore it
* (ignore), continue (retry), or abort (abort). It then copies the error to the clipboard.
*
***********************/
bool CustomAssertFunction(bool exp, char* desc, int line, char* file, bool* ignoreAlways)
{

	//return true to halt the program
	
	if(!exp)
	{
		char * msg = new char[256];		
		sprintf(msg, "Desc: %s \nFile: %s \nLine: %i \n \nThis information has been copied to your clipboard. Please paste it, and email ASAP.", desc, file, line);		


		//copies it to clipboard

		if( OpenClipboard(NULL))
		{
			HGLOBAL hMem;
			char szAssert[256];
			char *pMem;

			
			hMem = GlobalAlloc( GHND|GMEM_DDESHARE, strlen( msg)+1);
			if(hMem)
			{
				pMem=(char *)GlobalLock(hMem);
				strcpy(pMem,msg);
				GlobalUnlock(hMem);
				EmptyClipboard();
				SetClipboardData(CF_TEXT,hMem);
			}

			CloseClipboard();

		}


				
		//SendMessage(main_window_handle,WM_CLOSE,0,0);
		
		switch (MessageBox(main_window_handle, msg, "Assertion Fail", MB_ABORTRETRYIGNORE ))
		{	

			case IDABORT://quit program
				SendMessage(main_window_handle,WM_CLOSE,0,0);
				return true;
			
			break;
			
			case IDRETRY://press-on			
				//return false;

			break;
		

			case IDIGNORE: //don't even tell me about this assert again
				*ignoreAlways=true;
			break;		
			
			default://damn, even the assert is messed 
				//	up_asm{int 3};
			break;
		}

		

	}


	return false;
}



/////////////////////////////////


#ifdef MM_DEBUG
BOOL WINAPI DDEnumCallbackEx(GUID FAR* lpGUID,
 										LPSTR lpDriverDescription,
 										LPSTR lpDriverName,
 										LPVOID lpContext,
										HMONITOR hm)
{
	 	// check the HMONITOR
	 	// if it's NULL then the device is the primary device
	 	// so if it's not NULL then it's the monitor we're looking for
		// so save the GUID
	 	if(hm != NULL)
 			monitorGUID = *lpGUID;
	 	// return success
	 	return TRUE;
 } // end DDEnumCallbackEx

 #endif

  
////////////////////////////////////
/*

GUID monitorGUID;

<Qoy> 	// enumerate the display devices
<Qoy> 	if(DirectDrawEnumerateEx(DDEnumCallbackEx,NULL,DDENUM_ATTACHEDSECONDARYDEVICES)!= DD_OK)
<Qoy> 	{
<Qoy> 		DebugOut("-InitDirectDraw: Enumeration of display devices failed\n");
<Qoy> 		return false;
<Qoy> 	}
<Qoy> #endif

<Qoy> you're calling the func to enumerate all the monitors
<Qoy> assuming that goes OK, monitorGUID now is the second monitor
<Qoy> so there's a param to DirectDrawCreate that takes a GUID to the device
<Qoy> pass monitorGUID to that and the DDraw object will use your second monitor
<Qoy> (by the way this is DX7, it's prolly different for 8)


  */