// ============================================================================
//   Bounce.c 
//   Based on the "Bouncing Ball Program" published by Charles Petzold.
//   Modified to run on the CE platform.
//		Mark Smith, dataIP Computer Consultants
//
// ============================================================================


#include <windows.h>

// ============================================================================
// Define a couple of macros for later use.

#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))


// ============================================================================
// The main window message handler

LRESULT CALLBACK MainWindProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
	{
	static HANDLE BitmapHandle;
	static short cxClient, cyClient, xCenter, yCenter, cxTotal, cyTotal;
	static short cxRadius, cyRadius, cxMove, cyMove, xPixel, yPixel;
	HDC hdc, hdcMem;

	switch (message)
		{
		case WM_CREATE:
			{
			hdc = GetDC (hwnd);
			xPixel = GetDeviceCaps (hdc, ASPECTX);
			yPixel = GetDeviceCaps (hdc, ASPECTY);
			ReleaseDC (hwnd, hdc);
			return 0;
			}

		// We don't get resize messages from WinCE other than the initial one!
		case WM_SIZE:
			{
			HBRUSH BrushHandle;
			short Scale;

			xCenter = (cxClient = LOWORD (lParam)) / 2;
			yCenter = (cyClient = HIWORD (lParam)) / 2;

			Scale = min (cxClient * xPixel, cyClient * yPixel) / 10;

			cxRadius = Scale / xPixel;
			cyRadius = Scale / yPixel;

			cxMove = max (1, cxRadius / 4);
			cyMove = max (1, cyRadius / 4);

			cxTotal = 2 * (cxRadius + cxMove);
			cyTotal = 2 * (cyRadius + cyMove);

			if (BitmapHandle)
				{
				DeleteObject (BitmapHandle);
				}

			hdc = GetDC (hwnd);
			hdcMem = CreateCompatibleDC (hdc);
			BitmapHandle = CreateCompatibleBitmap (hdc, cxTotal, cyTotal);
			ReleaseDC (hwnd, hdc);

			SelectObject (hdcMem, BitmapHandle);
			Rectangle (hdcMem, -1, -1, cxTotal + 1, cyTotal + 1);

			BrushHandle = CreateSolidBrush RGB(255, 0, 0);
			SelectObject (hdcMem, BrushHandle);
			SetBkColor (hdcMem, RGB (255, 0, 255));
			Ellipse (hdcMem, cxMove, cyMove, cxTotal - cxMove, cyTotal - cyMove);
			DeleteDC (hdcMem);
			DeleteObject (BrushHandle);
			return 0;
			}

		case WM_TIMER:
			{
			if (!BitmapHandle)
				break;

			hdc = GetDC (hwnd);
			hdcMem = CreateCompatibleDC (hdc);
			SelectObject (hdcMem, BitmapHandle);

			BitBlt (hdc, xCenter - cxTotal / 2, yCenter - cyTotal / 2, cxTotal, cyTotal, hdcMem, 0, 0, SRCCOPY);

			ReleaseDC (hwnd, hdc);
			DeleteDC (hdcMem);

			xCenter += cxMove;
			yCenter += cyMove;

			if ((xCenter + cxRadius >= cxClient) || (xCenter - cxRadius <= 0))
				cxMove = -cxMove;

			if ((yCenter + cyRadius >= cyClient) || (yCenter - cyRadius <= 0))
				cyMove = -cyMove;

			return 0 ;
			}

		case WM_DESTROY:
			{
			if (BitmapHandle)
				{
				DeleteObject (BitmapHandle);
				}
			KillTimer (hwnd, 1);
			PostQuitMessage (0);
			return 0;
			}
		}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
	}

// ============================================================================

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpszCmdLine, int nCmdShow)
	{
	HWND hwnd;
	MSG msg;
	WNDCLASS WindowClass;

	if (!hPrevInstance) 
		{
		WindowClass.style         = CS_HREDRAW | CS_VREDRAW;
		WindowClass.lpfnWndProc   = MainWindProc;
		WindowClass.cbClsExtra    = 0;
		WindowClass.cbWndExtra    = 0;
		WindowClass.hInstance     = hInstance;
		WindowClass.hIcon         = NULL;
		WindowClass.hCursor       = NULL;
		WindowClass.hbrBackground = GetStockObject (WHITE_BRUSH);
		WindowClass.lpszMenuName  = NULL;
		WindowClass.lpszClassName = TEXT("Bounce");

		RegisterClass (&WindowClass);
		}

#ifdef _WIN32_WCE
// Use this window definition on CE platforms
     hwnd = CreateWindow (TEXT("Bounce"), TEXT("Bounce - www.dataIP.co.uk"),
			WS_BORDER | WS_CAPTION | WS_SYSMENU,
			CW_USEDEFAULT, CW_USEDEFAULT,
			220, 150,
			NULL, NULL, hInstance, NULL) ;
#else
// Use this window definition on Win32 desktop platforms
     hwnd = CreateWindow (TEXT("Bounce"), TEXT("Bounce - www.dataIP.co.uk"), 
			WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, CW_USEDEFAULT, 
			CW_USEDEFAULT, CW_USEDEFAULT, 
			NULL, NULL, hInstance, NULL);
#endif

	if (!SetTimer (hwnd, 1, 50, NULL))
		{
		MessageBox (hwnd, TEXT("Too many clocks or timers!"), TEXT("Bounce"), MB_ICONEXCLAMATION | MB_OK) ;
		return FALSE;
		}

	ShowWindow (hwnd, nCmdShow);
	UpdateWindow (hwnd);

	while (GetMessage (&msg, NULL, 0, 0))
		{
		TranslateMessage (&msg);
		DispatchMessage (&msg);
		}

	return msg.wParam;
	}


// ============================================================================
