/*----------------------------------------------------------------------------
 *
 *  main.c
 *  ------
 *
 *  Purpose: Provide the startup processing for VisualAge Smalltalk Enterprise
 *
 *  Commandline switches:
 *     -nosplash  Do not display the splash screen
 *     -singleinstance  Allow multiple copies of the executable to run at the
 *                same time
 *
 *  Licensed Materials - Property of IBM
 *
 *  (C) Copyright International Business Machines Corp., 1999
 *  All rights reserved
 *
 *  US Government Users Restricted Rights -
 *  Use, duplication, or disclosure restricted
 *  by GSA ADP Schedule Contract with IBM Corp.
 *
 *  Modifications:
 *     5.0.1.0 24Jan00(jok) Update to 5.0.1
 *                          Update parse.c for tenureFailedGCCount option
 *
 *----------------------------------------------------------------------------*/

#define PRODUCT_NAME    "VisualAge Smalltalk Enterprise"
#define PRODUCT_VERSION "Version 5.0.1"
#define PRODUCT_STATUS  ""
#define PRODUCT_EDITION "01/24/2000"
#define PRODUCT_COPYR   "(C) Copyright International Business Machines Corporation  1994, 2000.\nAll Rights Reserved."

#define	INCL_WIN
#define INCL_DOSPROCESS
#define INCL_DOSERRORS
#define INCL_DOSSEMAPHORES
#define INCL_ERRORS
#define INCL_GPIBITMAPS

#include <os2.h>
#include <string.h>
#include "esrc.h"
#include "esuser.h"

/*--------------------------------------------------------------------------*/
/*      DEBUG support							                                  */
/*--------------------------------------------------------------------------*/

#ifdef DEBUG01
#define dbg_printf( x ) { printf x ; fflush( stdout ); }
#else
#define dbg_printf( x )
#endif


PFNWP StaticProc;
HBITMAP hBitmap;

extern EsPrimitiveTable filePrimitiveTable;
extern EsPrimitiveTable WindowProcPrimitiveTable;
extern EsSplashShutDown (EsGlobalInfo *);

BOOLEAN EsParseCommandLineOptions(int argc, char *argv[], char *envp[], EsGlobalInfo * info);

static BOOLEAN runningPM();


EsDefinePrimitiveTable(EsExePrimitiveTable)
	EsSubTable(WindowProcPrimitiveTable)
	EsSubTable(filePrimitiveTable)
EsEndPrimitiveTable




MRESULT EXPENTRY DrawBitmapProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{				
	RECTL rect;
	HPS hPS;

	switch(msg) {
		case WM_PAINT: {
			WinQueryWindowRect (hwnd, &rect);
			hPS = WinBeginPaint (hwnd, (HPS)NULL, (PRECTL) NULL);
			WinDrawBitmap (hPS, hBitmap, NULL, (PPOINTL) &rect, 0, 0, DBM_STRETCH | DBM_IMAGEATTRS);

			WinEndPaint (hPS);
			return (MRESULT) 0;
		}
	}

	return (MRESULT) StaticProc(hwnd, msg, mp1, mp2);
}



static void _System splashDialogThread(EsGlobalInfo *globalInfo)
{
	HWND hwndDlg, hwndStatic;
	HAB hab;
	HMQ hmq;
	QMSG qmsg;
	int displayWidth, displayHeight;
	HPS hPS;
	BITMAPINFOHEADER info;
	int nWidth, nHeight, nX, nY, insetX, insetY;

	hab = WinInitialize( 0 );
	hmq = WinCreateMsgQueue( hab, 0 );

	displayWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
	displayHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
	hwndDlg = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP,
		(PFNWP)WinDefDlgProc, (HMODULE)NULL, IDD_SPLASHDIALOG,
		(PVOID)NULL );
	hwndStatic = WinWindowFromID(hwndDlg, ID_STATICAREA);
	StaticProc = WinSubclassWindow(hwndStatic, DrawBitmapProc);

	hPS = WinGetPS(hwndDlg);
	hBitmap = GpiLoadBitmap (hPS, (HMODULE) NULL, ID_BMPRESOURCE, 0, 0);
	GpiQueryBitmapParameters(hBitmap, &info);
	WinReleasePS(hPS);

	insetX = WinQuerySysValue(HWND_DESKTOP, SV_CXDLGFRAME);
	insetY = WinQuerySysValue(HWND_DESKTOP, SV_CYDLGFRAME);
	nWidth = info.cx + (insetX * 2);
	nHeight = info.cy + (insetY * 2);
	
	nX = max((displayWidth - nWidth) / 2, 0);
	nY = max((displayHeight - nHeight) / 2, 0);
	WinSetWindowPos(hwndStatic, (HWND)NULL, insetX, insetY, info.cx, info.cy, SWP_MOVE | SWP_SIZE);
	WinSetWindowPos(hwndDlg, HWND_TOP, nX, nY, nWidth, nHeight, SWP_MOVE | SWP_SIZE | SWP_SHOW);
	WinUpdateWindow(hwndDlg);

	/* remember the handles for use in the VM */
	globalInfo->splashDialogHandle = (void *) hwndDlg;
	globalInfo->splashStatusLineHandle = NULL; /* (void *) WinWindowFromID(hwndDlg, IDS_STATUS); */

	while (WinGetMsg( (HAB)hab, &qmsg, (HWND)NULL, 0L, 0L ))
		WinDispatchMsg( (HAB)hab, &qmsg );

	globalInfo->splashDialogHandle = (void *) NULL;
	globalInfo->splashStatusLineHandle = (void *) NULL;
	
	if (hBitmap) GpiDeleteBitmap (hBitmap);
	WinDestroyMsgQueue( hmq );
	WinTerminate( hab );
}



/* Answer true if we are running as a Presentation Manager application, false otherwise (VIO mode). */
static BOOLEAN runningPM( void )
{
	PTIB ptib = NULL;
	PPIB ppib = NULL;
	APIRET rc = NO_ERROR;

	rc = DosGetInfoBlocks(&ptib, &ppib);
	if (rc != NO_ERROR) return FALSE;

	/* type 3 is PM */
	return (ppib->pib_ultype == 3);
}



main(int argc, char ** argv, char ** envp)
{
	BOOLEAN splashEnabled=TRUE;
	BOOLEAN mutexEnabled=FALSE;
	I_32 rc,i;
	EsGlobalInfo *globalInfo;
	TID		tid;
	HMTX startupMutex;
	char mutexNameBuffer[1024] = "\\SEM32\\";
	char *exeName, *exeExtension, *ptr;

	/* Walk the command line looking VA specific command line options */
	dbg_printf( ("Entering main, %d commandline arguments\n", argc) );
	for(i=1; i < argc; i++) {
		dbg_printf( ("\t%s\n", argv[i]) );
		if(strcmp(argv[i],"-nosplash") == 0) {
			splashEnabled = FALSE;
		}
		if(strcmp(argv[i],"-singleinstance") == 0) {
			mutexEnabled = TRUE;
		}
	}
	dbg_printf( ("splashEnabled: %d\n", splashEnabled) );
	dbg_printf( ("mutexEnabled: %d\n", mutexEnabled) );

	if (mutexEnabled) {
		/* strip the path and extension from the program name */
		exeName = strrchr(argv[0], '\\');
		if(exeName)
			exeName++;
		else
			exeName = argv[0];

		strcat(mutexNameBuffer, exeName);
		/* uppercase everything */
		for (ptr = mutexNameBuffer; *ptr; ptr++)
			*ptr = toupper(*ptr);
		exeExtension = strrchr(mutexNameBuffer, '.');
		if (exeExtension && 0 == strcmp(exeExtension, ".EXE"))
			*exeExtension = '\0';
		strcat(mutexNameBuffer, "SINGLE_START_MUTEX");

		rc = DosCreateMutexSem(mutexNameBuffer, &startupMutex, 0L, FALSE);
		if(NO_ERROR != rc)
			return 0;	/* not first instance, go away. */
	}

	/* Do not call any Presentation Manager functions if running VIO. */

	globalInfo = EsInitializeImage();
	if (globalInfo == NULL) {
		EsReportError(EsPrimErrNotEnoughMemory, globalInfo);
		DosCloseMutexSem(startupMutex);
		return EsPrimErrNotEnoughMemory;
	}
	globalInfo->imagePrimitives = (U_32) EsExePrimitiveTable;

	if (runningPM() && splashEnabled) {
		/* fork off the thread to keep splash screen alive */
		DosCreateThread(&tid,(PFNTHREAD) splashDialogThread,(ULONG) globalInfo,0,8192);
	}

	if ((rc = EsInitializeTargetInterface(argc, argv, envp, globalInfo)) != EsPrimErrNoError) {
		EsSplashShutDown(globalInfo);
		EsReportError(rc, globalInfo);
		EsShutdownImage(globalInfo);
		if (mutexEnabled) DosCloseMutexSem(startupMutex);
		return rc;
	}

	EsPrintf ("\n%s, %s %s - %s\nVM Timestamp: %s\n%s\n%s\n",
			PRODUCT_NAME,PRODUCT_VERSION,PRODUCT_STATUS,PRODUCT_EDITION,
			EsVMVersionString(),
			PRODUCT_COPYR,
			0,0,0,0);

	globalInfo->messageLevel = ESVM_MSG_LEVEL_NONE;

	if(!EsParseCommandLineOptions(argc, argv, envp, globalInfo)) {
		EsSplashShutDown(globalInfo);
		EsReportError(EsPrimErrImageFileOpenError, globalInfo);
		EsShutdownImage(globalInfo);
		if (mutexEnabled) DosCloseMutexSem(startupMutex);
		return EsPrimErrImageFileOpenError;
	}

	rc = EsLoadFileImage(argc, argv, envp, globalInfo);
	if (rc != EsPrimErrNoError) {
		EsSplashShutDown(globalInfo);
		EsReportError (rc, globalInfo);
	}

	if (rc == EsPrimErrNoError) {
		rc = EsExecuteImage(globalInfo);
		if (rc != EsPrimErrNoError) {
			if (rc < 9000 || (rc > 9100))
				EsReportError (rc, globalInfo);
		}
	}

	EsShutDownTargetInterface (globalInfo);
	EsShutdownImage(globalInfo);
	if (mutexEnabled) DosCloseMutexSem(startupMutex);
	return rc;
}

