/////////////////////////////////////////////////////////////////////////////////////////////
// CDX example 1 - Fullscreen flipping
// You must link to cdx.lib, ddraw.lib and dxguid
/////////////////////////////////////////////////////////////////////////////////////////////
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include "cdxguimgr.h"


CDXScreen*	Screen;  // The screen object, every program must have one
CDXMap*		Map;
BOOL bActive = TRUE;  // Is the program running?
CDXDlgMgr* DlgMgr;
CDXDlg* OptionsButton;
CDXDlg* SaveButton;
CDXDlg* ExitButton;
CDXDlg*	LoadButton;
FILE* Logfile;
CDXInput* Input;
CDXSurface* Back;
CDXSurface* Cursor;
	HWND hWnd;

#define NAME		"CDXExample1"
#define TITLE		"CDX Example 1"


void fOnMouseOver(CDXDlg* pDlg, CDXInput* Input)
{
}


void fOnDestroy(CDXDlg* pDlg)
{
}


void fOnCreate(CDXDlg* pDlg)
{
}



void fOnMouseDown(CDXDlg* pDlg, CDXInput* Input)
{
	pDlg->BmpButton.Pressed = true;
	pDlg->LMWasPressed = true;
}

void fOnMouseUp(CDXDlg* pDlg, CDXInput* Input)
{
	pDlg->BmpButton.Pressed = false;
	pDlg->LMWasPressed = false;
	PostMessage(hWnd, WM_CLOSE, 0, 0);
}

void fDrawBmpButton(CDXDlg* pDlg, CDXSurface* Surface)
{
	HRESULT status;
	if (pDlg->DlgType == BmpButton)
		{
			if (pDlg->BmpButton.Pressed)
			{
				status = pDlg->BmpButton.DownBmp->DrawBlk(Surface,
					pDlg->ClientRect.left,
					pDlg->ClientRect.top);
			}
			else
			{
				if (pDlg->HasFocus)
				{
				status = pDlg->BmpButton.UpBmp->DrawBlk(Surface,
					pDlg->ClientRect.left,
					pDlg->ClientRect.top);
				}
				else
				{
				status = pDlg->BmpButton.DownBmp->DrawBlk(Surface,
					pDlg->ClientRect.left,
					pDlg->ClientRect.top);
				}
			}
		}

	if (pDlg->DlgType == PrimButton)
		{
		Surface->Lock();
		Surface->Fill(pDlg->BkColor);
		Surface->Rect(	pDlg->ClientRect.left,
						pDlg->ClientRect.top,
						pDlg->ClientRect.right,
						pDlg->ClientRect.bottom,
						pDlg->FgColor);
		Surface->UnLock();
		}
}

void fOnGainFocus(CDXDlg* pDlg)
{
	pDlg->FgColor = 75;
	pDlg->HasFocus = true;
}

void fOnLoseFocus(CDXDlg* pDlg)
{
	pDlg->FgColor = 86;
	pDlg->HasFocus = false;
}


/////////////////////////////////////////////////////////////////////////////////////////////
// FiniApp - Destroy the CDX objects
/////////////////////////////////////////////////////////////////////////////////////////////
void FiniApp(void)
{
	if (DlgMgr)
	{
		DlgMgr->Destroy(OptionsButton);
		DlgMgr->Destroy(SaveButton);
		DlgMgr->Destroy(ExitButton);
		DlgMgr->Destroy(LoadButton);
		delete DlgMgr;
	}
	if (Back)
		delete Back;
	if (Input)
		delete Input;
	if(Screen)
		delete Screen;
	fclose(Logfile);
}



/////////////////////////////////////////////////////////////////////////////////////////////
// WinProc
/////////////////////////////////////////////////////////////////////////////////////////////
long PASCAL WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
		case WM_ACTIVATEAPP:
			bActive = wParam;
			break;

		case WM_KEYDOWN:
			switch(wParam)
			{
				case VK_ESCAPE:
					PostMessage(hWnd, WM_CLOSE, 0, 0);
				break;
			}
		break;

		case WM_DESTROY:
			FiniApp();
			PostQuitMessage(0);
		break;
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}

/////////////////////////////////////////////////////////////////////////////////////////////
// InitApp - Create the window and the CDX objects
/////////////////////////////////////////////////////////////////////////////////////////////
BOOL InitApp(HINSTANCE hInst, int nCmdShow)
{
	WNDCLASS WndClass;

	WndClass.style = CS_HREDRAW | CS_VREDRAW;
	WndClass.lpfnWndProc = WinProc;
	WndClass.cbClsExtra = 0;
	WndClass.cbWndExtra = 0;
	WndClass.hInstance = hInst;
	WndClass.hIcon = LoadIcon(0, IDI_APPLICATION);
	WndClass.hCursor = LoadCursor(0, IDC_ARROW);
	WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	WndClass.lpszMenuName = NAME;
	WndClass.lpszClassName = NAME;
	RegisterClass(&WndClass);

	hWnd = CreateWindowEx(
		WS_EX_TOPMOST,
		NAME,
		TITLE,
		WS_POPUP,
		0,0,
		GetSystemMetrics(SM_CXSCREEN),
		GetSystemMetrics(SM_CYSCREEN),
		NULL,
		NULL,
		hInst,
		NULL);

	if(!hWnd) return FALSE;

	Logfile=fopen("log.txt", "w");

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	fprintf(Logfile, "Creating Screen\n", Input);
	fflush(Logfile);

	Screen = new CDXScreen();
//	if(!Screen->CreateFullScreen(hWnd, 1024, 768, 16))
	if (FAILED(Screen->CreateWindowed(hWnd, 800,600)))
		return FALSE;

	fprintf(Logfile, "Creating Input\n", Input);
	fflush(Logfile);

	Input = new CDXInput();
	if (FAILED(Input->Create(hInst, hWnd)))
		return FALSE;

	fprintf(Logfile, "Input pointer %p\n", Input);
	fflush(Logfile);

	DlgMgr = new CDXDlgMgr(Screen->GetBack(), Input);
	DlgMgr->mhWnd = hWnd;
	DlgMgr->mDefaultRect.top = 0;
	DlgMgr->mDefaultRect.left = 0;
	DlgMgr->mDefaultRect.bottom = 350;
	DlgMgr->mDefaultRect.right = 799;
	DlgMgr->mCheckTriggers = true;

	SaveButton = new CDXDlg();
	SaveButton->DlgRect.left = 680;
	SaveButton->DlgRect.top = 30;
	SaveButton->DlgRect.right = 710;
	SaveButton->DlgRect.bottom = 63;
	SaveButton->ClientRect = SaveButton->DlgRect;
	SaveButton->FgColor = 0;
	SaveButton->BkColor = 0;
	SaveButton->BmpButton.Selected = false;
	SaveButton->pOnRedraw = fDrawBmpButton;
	SaveButton->pOnMouseOver = fOnMouseOver;
	SaveButton->pOnMouseDown = fOnMouseDown;
	SaveButton->pOnMouseUp = fOnMouseUp;
	SaveButton->pOnGainFocus = fOnGainFocus;
	SaveButton->pOnLoseFocus = fOnLoseFocus;
	SaveButton->pOnCreate = fOnCreate;
	SaveButton->pOnCreate = fOnDestroy;
	SaveButton->DlgType = BmpButton;
	SaveButton->HasFocus = false;
	SaveButton->BmpButton.Pressed = false;
	SaveButton->Visible = true;
	SaveButton->LMWasPressed = false;
	SaveButton->BmpButton.UpBmp = new CDXSurface;
	SaveButton->BmpButton.UpBmp->Create(
				Screen,
				"disk2.bmp",
				CDXMEM_SYSTEMONLY);
	SaveButton->BmpButton.DownBmp = new CDXSurface;
	SaveButton->BmpButton.DownBmp->Create(
				Screen,
				"disk1.bmp",
				CDXMEM_SYSTEMONLY);
	DlgMgr->Register(SaveButton);

	ExitButton = new CDXDlg();
	ExitButton->DlgRect.left = 330;
	ExitButton->DlgRect.top = 400;
	ExitButton->DlgRect.right = 430;
	ExitButton->DlgRect.bottom = 450;
	ExitButton->ClientRect = ExitButton->DlgRect;
	ExitButton->FgColor = 0;
	ExitButton->BkColor = 0;
	ExitButton->BmpButton.Selected = false;
	ExitButton->pOnRedraw = fDrawBmpButton;
	ExitButton->pOnMouseOver = fOnMouseOver;
	ExitButton->pOnMouseDown = fOnMouseDown;
	ExitButton->pOnMouseUp = fOnMouseUp;
	ExitButton->pOnGainFocus = fOnGainFocus;
	ExitButton->pOnLoseFocus = fOnLoseFocus;
	ExitButton->pOnCreate = fOnCreate;
	ExitButton->pOnCreate = fOnDestroy;
	ExitButton->DlgType = BmpButton;
	ExitButton->HasFocus = false;
	ExitButton->BmpButton.Pressed = false;
	ExitButton->Visible = true;
	ExitButton->LMWasPressed = false;
	ExitButton->BmpButton.UpBmp = new CDXSurface;
	ExitButton->BmpButton.UpBmp->Create(
				Screen,
				"exit1.bmp",
				CDXMEM_SYSTEMONLY);
	ExitButton->BmpButton.DownBmp = new CDXSurface;
	ExitButton->BmpButton.DownBmp->Create(
				Screen,
				"exit2.bmp",
				CDXMEM_SYSTEMONLY);
	DlgMgr->Register(ExitButton);

	LoadButton = new CDXDlg();
	LoadButton->DlgRect.left = 330;
	LoadButton->DlgRect.top = 200;
	LoadButton->DlgRect.right = 430;
	LoadButton->DlgRect.bottom = 250;
	LoadButton->ClientRect = LoadButton->DlgRect;
	LoadButton->FgColor = 0;
	LoadButton->BkColor = 0;
	LoadButton->BmpButton.Selected = false;
	LoadButton->pOnRedraw = fDrawBmpButton;
	LoadButton->pOnMouseOver = fOnMouseOver;
	LoadButton->pOnMouseDown = fOnMouseDown;
	LoadButton->pOnMouseUp = fOnMouseUp;
	LoadButton->pOnGainFocus = fOnGainFocus;
	LoadButton->pOnLoseFocus = fOnLoseFocus;
	LoadButton->pOnCreate = fOnCreate;
	LoadButton->pOnCreate = fOnDestroy;
	LoadButton->DlgType = BmpButton;
	LoadButton->HasFocus = false;
	LoadButton->BmpButton.Pressed = false;
	LoadButton->Visible = true;
	LoadButton->LMWasPressed = false;
	LoadButton->BmpButton.UpBmp = new CDXSurface;
	LoadButton->BmpButton.UpBmp->Create(
				Screen,
				"load2.bmp",
				CDXMEM_SYSTEMONLY);
	LoadButton->BmpButton.DownBmp = new CDXSurface;
	LoadButton->BmpButton.DownBmp->Create(
				Screen,
				"load1.bmp",
				CDXMEM_SYSTEMONLY);
	DlgMgr->Register(LoadButton);

	OptionsButton = new CDXDlg();
	OptionsButton->DlgRect.left = 330;
	OptionsButton->DlgRect.top = 300;
	OptionsButton->DlgRect.right = 480;
	OptionsButton->DlgRect.bottom = 350;
	OptionsButton->ClientRect = OptionsButton->DlgRect;
	OptionsButton->FgColor = 0;
	OptionsButton->BkColor = 0;
	OptionsButton->BmpButton.Selected = false;
	OptionsButton->pOnRedraw = fDrawBmpButton;
	OptionsButton->pOnMouseOver = fOnMouseOver;
	OptionsButton->pOnMouseDown = fOnMouseDown;
	OptionsButton->pOnMouseUp = fOnMouseUp;
	OptionsButton->pOnGainFocus = fOnGainFocus;
	OptionsButton->pOnLoseFocus = fOnLoseFocus;
	OptionsButton->pOnCreate = fOnCreate;
	OptionsButton->pOnCreate = fOnDestroy;
	OptionsButton->DlgType = BmpButton;
	OptionsButton->HasFocus = false;
	OptionsButton->BmpButton.Pressed = false;
	OptionsButton->Visible = true;
	OptionsButton->LMWasPressed = false;
	OptionsButton->BmpButton.UpBmp = new CDXSurface;
	OptionsButton->BmpButton.UpBmp->Create(
				Screen,
				"options2.bmp",
				CDXMEM_SYSTEMONLY);
	OptionsButton->BmpButton.DownBmp = new CDXSurface;
	OptionsButton->BmpButton.DownBmp->Create(
				Screen,
				"options1.bmp",
				CDXMEM_SYSTEMONLY);
	DlgMgr->Register(OptionsButton);


	Back = new CDXSurface;
	Back->Create(
				Screen,
				"back.bmp",
				CDXMEM_SYSTEMONLY);

	Cursor = new CDXSurface;
	Cursor->Create(Screen, "cursor.bmp", CDXMEM_SYSTEMONLY);

	fprintf(Logfile, "Finished\n");
	fflush(Logfile);
	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////////////////////
// WinMain
/////////////////////////////////////////////////////////////////////////////////////////////
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
	MSG msg;

	if(!InitApp(hInst, nCmdShow)) return FALSE;

	while(1)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
		{
			if(!GetMessage(&msg, NULL, 0, 0 )) return msg.wParam;
			TranslateMessage(&msg); 
			DispatchMessage(&msg);
		}
		else if(bActive)
		{
			
			Back->DrawBlk(	Screen->GetBack(),
							0,
							0);
			if (DlgMgr)
			{
				DlgMgr->Redraw();
				DlgMgr->Trigger();
			}

			DlgMgr->UpdateMouse();
			Cursor->DrawBlk(Screen->GetBack(), DlgMgr->mMouse.x, DlgMgr->mMouse.y);
			Screen->Flip();
		}
		else WaitMessage();


	}
}



