/////////////////////////////////////////////////////////////////////////////////////////////
// CDX Map Demo  - Windowed scrolling
// You must link to winmm.lib, ddraw.lib and cdx.lib
/////////////////////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#define CDXINCLUDEALL
#include <CDX.h>

#define NAME		"MapDemo"
#define TITLE		"Map Demo Example"

CDXScreen* Screen;  // The screen object, every program must have one
CDXTile* Tiles;     // The background tiles
CDXSurface* WorkSurface;
CDXSprite* Sprite1;
CDXInput* Input;
CDXMap* Map;
RGBFORMAT rgbData;

BOOL bActive = TRUE;  // Is the program running?

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

		case WM_SETCURSOR:
			SetCursor(NULL);    // disable the cursor
			return TRUE;

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

		case WM_DESTROY:
			bActive = FALSE;
			delete Sprite1;
			delete WorkSurface;
			delete Input;
			delete Tiles;
			delete Screen;

			PostQuitMessage(0);
		break;
	}

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

/////////////////////////////////////////////////////////////////////////////////////////////
// InitApp - Create the window and the CDX objects
/////////////////////////////////////////////////////////////////////////////////////////////
BOOL InitApp(HINSTANCE hInst, int nCmdShow)
{
	HWND hWnd;
	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);

    // create a window which covers the whole screen
    // this is needed for fullscreen CDX apps
	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;

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

	// Create the CDXSreen object
	Screen = new CDXScreen;
	Screen->CreateFullScreen(hWnd, 640, 480, 16);

	// Load the tiles
	Tiles = new CDXTile;
	Tiles->Create(Screen, "track01.BMP", 32, 32, 125, 1);

	// Create and load the map
	Map = new CDXMap(Tiles, Screen);
	Map->Load("tracktest.map");	
	Map->MoveTo(200,200);

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

	// Load bitmap into surface
	WorkSurface = new CDXSurface;
	WorkSurface->Create(Screen,640,480,1);     

	// Create the Tile Surface
	Sprite1 = new CDXSprite;
	Sprite1->Create(Screen,"htlogo.bmp", 320, 240, 1, 1);
	Sprite1->SetFrame(1);
	Sprite1->SetPos(1830,1550);
	Sprite1->SetColorKey(65535);
	Sprite1->SetAlphaValue(100);
	Sprite1->SetShadowValue(200);
	Sprite1->SetShadowOffset(0,0);

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////////////////////
// WinMain
/////////////////////////////////////////////////////////////////////////////////////////////
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
	MSG msg;
	char str[100];
	int sx,sy;
	RECT clipRect;
	DWORD color;
	HRESULT hretval;
	LONG moveX, moveY;
	WORD bltType;
	LONG dwSIMDType;

	clipRect.top    = 0;
	clipRect.left   = 0;
	clipRect.bottom = 438;
	clipRect.right  = 480;
	sx              = 160;
	sy              = 120;
	moveX           = 200;
	moveY           = 100;
	color           = 250;
	bltType         = CDXBLT_TRANS;
	
	if(!InitApp(hInst, nCmdShow)) return FALSE;	

	Screen->GetBack()->ChangeFont("Times New Roman", 5,14,300);

	dwSIMDType = Screen->GetBack()->GetSIMDType();

	WorkSurface->SetClipRect(&clipRect);

	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)
		{
			Map->Draw(WorkSurface);
			Sprite1->Draw(WorkSurface,Map->GetPosX(), Map->GetPosY(), bltType);

			Screen->GetBack()->Fill(0);
	
			hretval = WorkSurface->DrawBlk(Screen->GetBack(), clipRect.left, clipRect.top);//,clipRect);

			Screen->GetBack()->Lock();
			Screen->GetBack()->Rect(0,440,480,479,color);
			Screen->GetBack()->Rect(1,441,479,478,color);
			Screen->GetBack()->Rect(482,0,639,479,color);
			Screen->GetBack()->Rect(483,1,638,478,color);
			Screen->GetBack()->UnLock();

			// Draw some text to the back buffer
			Screen->GetBack()->GetDC();

			// Core drawing done here
			{
				Screen->GetBack()->SetFont();

				sprintf(str,"Frame Rate: %d fps",Screen->GetFPS());
				Screen->GetBack()->TextXY(490,20,0x0000FF00,str);
				
				sprintf(str,"Surface bpp = %d",Screen->GetBPP());
				Screen->GetBack()->TextXY(490,50,0x0000FF00,str);

				if (dwSIMDType) 
					sprintf(str,"MMX Capable: TRUE");
				else
					sprintf(str,"MMX Capable: FALSE");

				Screen->GetBack()->TextXY(490,80,0x0000FF00,str);

				sprintf(str,"Map X,Y = %d, %d",Map->GetPosX(), Map->GetPosY());
				Screen->GetBack()->TextXY(490,110,0x0000FF00,str);

				sprintf(str,"A - TRANS");
				Screen->GetBack()->TextXY(490,160,0x0000FF00,str);

				sprintf(str,"S - TRANSALPHA");
				Screen->GetBack()->TextXY(490,180,0x0000FF00,str);

				sprintf(str,"D - TRANSALPHAFAST");
				Screen->GetBack()->TextXY(490,200,0x0000FF00,str);

				sprintf(str,"F - TRANSSHADOW");
				Screen->GetBack()->TextXY(490,220,0x0000FF00,str);

				sprintf(str,"G - TRANSSHADOWFAST");
				Screen->GetBack()->TextXY(490,240,0x0000FF00,str);

				sprintf(str,"H - TRANSVFLIP");
				Screen->GetBack()->TextXY(490,260,0x0000FF00,str);

				sprintf(str,"J - TRANSHFLIP");
				Screen->GetBack()->TextXY(490,280,0x0000FF00,str);

				sprintf(str,"- : Decrease Size");
				Screen->GetBack()->TextXY(490,330,0x0000FF00,str);

				sprintf(str,"+ : Increase Size");
				Screen->GetBack()->TextXY(490,350,0x0000FF00,str);

				sprintf(str,"Find the bitmap in order to play with the BLT types.  ( Hint, 1830,1550 )");
				Screen->GetBack()->TextXY(10,460,0x0000FF00,str);
			}

			Screen->GetBack()->ReleaseDC();

			Screen->Flip();  // Then display it
			
			Input->Update();  // Refresh the input devices

			if(Input->GetKeyState(CDXKEY_UPARROW))
			{
				sy -= 4;
				//Sprite1->SetPos(sx,sy);
				moveY--;
				Map->ScrollUp(4);
			}
	
			if(Input->GetKeyState(CDXKEY_DOWNARROW))
			{
				sy += 4;
				//Sprite1->SetPos(sx,sy);	
				moveY++;
				Map->ScrollDown(4);

			}
			if(Input->GetKeyState(CDXKEY_LEFTARROW))
			{
				sx -= 4;
				//Sprite1->SetPos(sx,sy);
				moveX--;
				Map->ScrollLeft(4);
			}
			if(Input->GetKeyState(CDXKEY_RIGHTARROW))
			{
				sx += 4;
				//Sprite1->SetPos(sx,sy);
				moveX++;
				Map->ScrollRight(4);
			}
			if(Input->GetKeyState(CDXKEY_NUMMINUS))
			{
				if (clipRect.top < 50)
				{
					clipRect.top    += 10;
					clipRect.left   += 10;
					clipRect.bottom -= 10;
					clipRect.right  -= 10;
					
					WorkSurface->SetClipRect(&clipRect);
				}
			}
			if(Input->GetKeyState(CDXKEY_EQUALS))
			{
				if (clipRect.top > 0)
				{
					clipRect.top    -= 10;
					clipRect.left   -= 10;
					clipRect.bottom += 10;
					clipRect.right  += 10;
					
					WorkSurface->SetClipRect(&clipRect);
				}
			}
			if(Input->GetKeyState(CDXKEY_A))
			{
				bltType = CDXBLT_TRANS;
			}
			if(Input->GetKeyState(CDXKEY_S))
			{
				bltType = CDXBLT_TRANSALPHA;
			}
			if(Input->GetKeyState(CDXKEY_D))
			{
				bltType = CDXBLT_TRANSALPHAFAST;
			}
			if(Input->GetKeyState(CDXKEY_F))
			{
				bltType = CDXBLT_TRANSSHADOW;
			}
			if(Input->GetKeyState(CDXKEY_G))
			{
				bltType = CDXBLT_TRANSSHADOWFAST;
			}
			if(Input->GetKeyState(CDXKEY_H))
			{
				bltType = CDXBLT_TRANSVFLIP;
			}
			if(Input->GetKeyState(CDXKEY_J))
			{
				bltType = CDXBLT_TRANSHFLIP;
			}

		}
		else WaitMessage();
	}
}
