/******************************************************************************
 testjx.cc

	This provides a way to test the JX library and provides sample source
	code for everyone to study.

	Written by John Lindal.

 ******************************************************************************/

#include "TestDirector.h"
#include "TestApp.h"
#include "TestMDIServer.h"
#include <JXDisplay.h>
#include <JXColormap.h>
#include <JXLibVersion.h>
#include <JCoreLibVersion.h>
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <jAssert.h>

// Prototypes

void ParseTextOptions(int* argc, char* argv[], JBoolean* wantMDI);
void ParseXOptions(const int argc, char* argv[],
				   JBoolean* startIconic, JBoolean* bufferTestWidget,
				   JBoolean* testWidgetIsImage, JBoolean* useStaticColors,
				   JBoolean* allocDynamicColors, JBoolean* preApproxColors,
				   JBoolean* snoopWindow);
void PrintHelp();
void PrintVersion();

/******************************************************************************
 main

 ******************************************************************************/

int
main
	(
	int		argc,
	char*	argv[]
	)
{
	JBoolean wantMDI;
	ParseTextOptions(&argc, argv, &wantMDI);

	if (wantMDI &&
		!TestMDIServer::WillBeMDIServer(TestApp::kAppSignature, argc, argv))
		{
		return 0;
		}

	TestApp* app = new TestApp(&argc, argv, wantMDI);
	assert( app != NULL );

	JBoolean startIconic, bufferTestWidget, testWidgetIsImage;
	JBoolean useStaticColors, allocDynamicColors, preApproxColors;
	JBoolean snoopWindow;
	ParseXOptions(argc, argv, &startIconic, &bufferTestWidget,
				  &testWidgetIsImage, &useStaticColors, &allocDynamicColors,
				  &preApproxColors, &snoopWindow);

	TestDirector* mainDir =
		new TestDirector(app, kTrue, startIconic, bufferTestWidget,
						 testWidgetIsImage, useStaticColors, allocDynamicColors,
						 snoopWindow);
	assert( mainDir != NULL );

	app->SetMainDirector(mainDir);

	((mainDir->GetDisplay())->GetColormap())->
		ShouldPreemptivelyApproximateColors(preApproxColors);

	mainDir->Activate();
	app->Run();
	return 0;
}

/******************************************************************************
 ParseTextOptions

	Handle the command line options that don't require opening an X display.

	Options that don't call exit() should use JXApplication::RemoveCmdLineOption()
	so ParseXOptions won't gag.

 ******************************************************************************/

void
ParseTextOptions
	(
	int*		argc,
	char*		argv[],
	JBoolean*	wantMDI
	)
{
	*wantMDI = kFalse;

	long index = 1;
	while (index < *argc)
		{
		if (strcmp(argv[index], "-h") == 0 ||
			strcmp(argv[index], "--help") == 0)
			{
			PrintHelp();
			exit(0);
			}
		else if (strcmp(argv[index], "-v") == 0 ||
				 strcmp(argv[index], "--version") == 0)
			{
			PrintVersion();
			exit(0);
			}
		else if (strcmp(argv[index], "-MDI") == 0)
			{
			*wantMDI = kTrue;
			JXApplication::RemoveCmdLineOption(argc, argv, index, 1);
			index--;
			}
		index++;
		}
}

/******************************************************************************
 ParseXOptions

	Modify the defaults based on the command line options.

	Since JXApplication has already removed all of its options, we can
	safely assume that whatever we don't understand is an error.

 ******************************************************************************/

void
ParseXOptions
	(
	const int	argc,
	char*		argv[],
	JBoolean*	startIconic,
	JBoolean*	bufferTestWidget,
	JBoolean*	testWidgetIsImage,
	JBoolean*	useStaticColors,
	JBoolean*	allocDynamicColors,
	JBoolean*	preApproxColors,
	JBoolean*	snoopWindow
	)
{
	*startIconic        = kFalse;
	*bufferTestWidget   = kTrue;
	*testWidgetIsImage  = kFalse;
	*useStaticColors    = kFalse;
	*allocDynamicColors = kTrue;
	*preApproxColors    = kFalse;
	*snoopWindow        = kFalse;

	long index = 1;
	while (index < argc)
		{
		if (strcmp(argv[index], "-iconic") == 0)
			{
			*startIconic = kTrue;
			}
		else if (strcmp(argv[index], "-nobuffer") == 0)
			{
			*bufferTestWidget = kFalse;
			}
		else if (strcmp(argv[index], "-imagebuffer") == 0)
			{
			*testWidgetIsImage = kTrue;
			}
		else if (strcmp(argv[index], "-staticcolor") == 0)
			{
			*useStaticColors = kTrue;
			}
		else if (strcmp(argv[index], "-nodyncolor") == 0)
			{
			*allocDynamicColors = kFalse;
			}
		else if (strcmp(argv[index], "-preappcolor") == 0)
			{
			*preApproxColors = kTrue;
			}
		else if (strcmp(argv[index], "-snoopwindow") == 0)
			{
			*snoopWindow = kTrue;
			}
		else
			{
			cerr << argv[0] << ": unknown option " << argv[index] << endl;
			}
		index++;
		}
}

/******************************************************************************
 PrintHelp

 ******************************************************************************/

void
PrintHelp()
{
	cout << endl;
	cout << "This X application demonstrates the capabilities of the JX" << endl;
	cout << "C++ application framework and GUI class library." << endl;
	cout << endl;
	cout << "Usage:  <options>" << endl;
	cout << endl;
	cout << "-h            prints help" << endl;
	cout << "-v            prints version information" << endl;
	cout << "-iconic       start with the main window iconified" << endl;
	cout << "-nobuffer     turn off buffered drawing in main window" << endl;
	cout << "              (for bragging about optimized redrawing code)" << endl;
	cout << "-imagebuffer  buffer drawing in main window by using JXImage" << endl;
	cout << "              (bad idea in general because it hogs memory)" << endl;
	cout << "-staticcolor  don't switch colormaps if default is TrueColor" << endl;
	cout << "-nodyncolor   don't allocate any dynamic colors" << endl;
	cout << "-preappcolor  use preemptive color approximation" << endl;
	cout << "-snoopwindow  print message whenever main window is (de)iconified" << endl;
	cout << endl;
	cout << "-MDI          activate Multiple Document Interface" << endl;
	cout << "              When an MDI testjx process is already running" << endl;
	cout << "              and you use this option, none of the other options" << endl;
	cout << "              are valid, but you can specify an arbitrary" << endl;
	cout << "              number of files to open." << endl;
	cout << endl;
}

/******************************************************************************
 PrintVersion

 ******************************************************************************/

void
PrintVersion()
{
	cout << endl;
	cout << "JCore version " << kCurrentJCoreLibVersionStr << endl;
	cout << "JX    version " << kCurrentJXLibVersionStr << endl;
	cout << endl;
}
