//-------------------------------------------------------------------
//
//	Program:		Simple state machine simulation
//	Filename:		TERMITE.C
//	Description:
//
//		This program uses state machine theory to generate
//		'termites'.  These termites move within the window
//		using their individual state tables.
//
//	Author:			Hans D. Kellner
//	Version:		1.0
//	Notes:			none
//
//-------------------------------------------------------------------

#include "windows.h"
#include "termite.h"
#include "fileopen.h"

#include <string.h>

HANDLE	hInst;

short	xClient, yClient;

char	szFileName[128] = "Default.mit";

char	szProgramName[] = "Termite";


/*-----------------------------------------------------------------*/
/*
/*	Name:			WinMain
/*	Description:
/*
/*-----------------------------------------------------------------*/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
	HANDLE hInstance;
	HANDLE hPrevInstance;
	LPSTR lpCmdLine;
	int nCmdShow;
{
	MSG		msg;
	HWND	hWnd;
	HANDLE	hAcc;
	short	xScreen, yScreen;


	if ( !hPrevInstance )
		if ( !InitApplication( hInstance ) )
			return FALSE;

	hInst = hInstance;			/* Save instance handle */

	// Create a window for the termite to live in.  Make it
	// half the height and width of the screen.

	xScreen = GetSystemMetrics( SM_CXSCREEN );
	yScreen = GetSystemMetrics( SM_CYSCREEN );

	hWnd = CreateWindow(
        "TermiteWClass",
		szProgramName,
        WS_OVERLAPPEDWINDOW,
        xScreen/4, yScreen/4,
        xScreen/2, yScreen/2,
        NULL, NULL, hInstance, NULL
	);

	if ( !hWnd )
		return FALSE;

	ShowWindow( hWnd, nCmdShow );
	UpdateWindow( hWnd );

	// Load the accelerators for this program.

	hAcc = LoadAccelerators( hInstance, "TermiteAcc" );

	// Start main message loop.  Note that the loop uses
	// PeekMessage to check for messages.  If no message
	// is found the termites are updated.  Otherwise,
	// normal message processing occurs...

	while ( TRUE )
	{
		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			if ( msg.message == WM_QUIT )
				break;

			if ( !TranslateAccelerator( hWnd, hAcc, &msg ) )
			{
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
		}
		else
			HandleTermites( hWnd );
	}

	return ( msg.wParam );
}

/*-----------------------------------------------------------------*/
/*
/*	Name:			InitApplication
/*	Description:
/*
/*-----------------------------------------------------------------*/

BOOL InitApplication(hInstance)
	HANDLE hInstance;
{
	WNDCLASS	wc;

	wc.style			= CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc		= MainWndProc;
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hInstance		= hInstance;
	wc.hIcon			= LoadIcon( hInst, szProgramName );
	wc.hCursor			= LoadCursor( NULL, IDC_ARROW );
	wc.hbrBackground	= GetStockObject( BLACK_BRUSH );
	wc.lpszMenuName		= "TermiteMenu";
	wc.lpszClassName	= "TermiteWClass";

	return ( RegisterClass( &wc ) );
}

/*-----------------------------------------------------------------*/
/*
/*	Name:			MainWndProc
/*	Description:
/*
/*-----------------------------------------------------------------*/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
	HWND hWnd;
	unsigned message;
	WORD wParam;
	LONG lParam;
{
	HPEN		hPenLgrey, hPenDgrey, hOldPen;
	FARPROC		lpProcAbout, lpOpenDlg;
	char		szText[128];
	HMENU		hMenu;
	RECT		rect;
	HDC			hDC;
	PAINTSTRUCT ps;


	switch ( message )
	{
		case WM_CREATE:

			GetClientRect( hWnd, &rect );

			xClient = rect.right - rect.left;
			yClient = rect.bottom - rect.top;

			LoadTermiteTables( szFileName );

			if ( LoadTermiteTables( szFileName ) == 0 )
		 		wsprintf( szText, "%s - %s", (LPSTR)szProgramName, (LPSTR)szFileName );
			else
				wsprintf( szText, "%s - <No File>", (LPSTR)szProgramName );

			SetWindowText( hWnd, szText );

			break;

		case WM_SIZE:

			xClient = LOWORD(lParam);
			yClient = HIWORD(lParam);

			ClipTermites();

			InvalidateRect(hWnd,NULL,TRUE);

			break;

		case WM_COMMAND:

			switch ( wParam )
			{
				case IDM_OPEN:

					if ( GetFileName( hInst, hWnd, "*.mit", szText ) )
					{
						strcpy( szFileName, szText );

						InvalidateRect( hWnd, NULL, TRUE );
						SendMessage( hWnd, WM_CREATE, 0, 0L );
					}

					break;

				case IDM_INS:

					InsertTermite();
					break;

				case IDM_DEL:

					DeleteTermite();
					break;

				case IDM_RESTART:

					InvalidateRect( hWnd, NULL, TRUE );
					SendMessage( hWnd, WM_CREATE, 0, 0L );
					break;

				case IDM_PAUSE:

					hMenu = GetMenu( hWnd );

					if ( pauseFlag )
						CheckMenuItem( hMenu, IDM_PAUSE, MF_UNCHECKED );
					else
						CheckMenuItem( hMenu, IDM_PAUSE, MF_CHECKED );

					pauseFlag = !pauseFlag;

					break;

				case IDM_ABOUT:

					lpProcAbout = MakeProcInstance( AboutDlgWndProc, hInst );

					DialogBox( hInst, "AboutBox", hWnd, lpProcAbout );

					FreeProcInstance( lpProcAbout );

					break;

				case IDM_EXIT:

					SendMessage( hWnd, WM_DESTROY, 0, 0L );

					break;
			}

			break;

		case WM_DESTROY:

			PostQuitMessage( 0 );

			break;

		default:

			return DefWindowProc( hWnd, message, wParam, lParam );
	}

	return 0L;
}

/*-----------------------------------------------------------------*/
/*
/*	Name:			AboutDlgWndProc
/*	Description:
/*
/*-----------------------------------------------------------------*/

BOOL FAR PASCAL AboutDlgWndProc(hDlg, message, wParam, lParam)
	HWND hDlg;
	unsigned message;
	WORD wParam;
	LONG lParam;
{
	switch ( message )
	{
		case WM_INITDIALOG:

			return TRUE;

		case WM_COMMAND:

		if ( wParam == IDOK || wParam == IDCANCEL )
		{
			EndDialog( hDlg, TRUE );
			return TRUE;
		}

		break;
	}

	return FALSE;
}

