/*	smalldemo.c		*/


/* A small, compilable without my personal librarys, test demo
 * program for the Rxil library.
 *
 * This must be run from the CLI only.
 *
 * This DOES depend on precompiler header files!
 */

/*		Copyright © 1989 by Donald T. Meyer, Stormgate Software
 *		All Rights Reserved
 *
 *		This source code may be compiled and used in any software
 *		product.
 *		No portion of this source code is to be re-distributed or
 *		sold for profit.
 *
 *		Donald T. Meyer
 *		Stormgate Software
 *		P.O. Box 383
 *		St. Peters, MO  63376
 *
 *		BIX:	donmeyer		(usually daily)
 *		GEnie:	D.MEYER			(weekly)
 *		PLINK:	Stormgate		(weekly)
 */


#include "rxil.h"




/*--------------------------------------------------------------------*/

void openlibrarys( void );
void closelibrarys( void );
void cleanup( void );
void bailout( char *message, int rc );

void eventloop( void );



void cmd_status( struct RexxMsg *rexxmsg );
void cmd_quit( struct RexxMsg *rexxmsg );
void cmd_launch_cmd( struct RexxMsg *rexxmsg );
void cmd_launch_func( struct RexxMsg *rexxmsg );
void cmd_ptest( struct RexxMsg *rexxmsg );
void cmd_dump( struct RexxMsg *rexxmsg );



/*--------------------------------------------------------------------*/

struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;


BOOL finished = FALSE;



/************************************
 *									*
 *    Defined for Rexx Interface	*
 *									*
 ************************************/

struct RxilDef *global_rdef = NULL;


struct RxilFunction rexx_cmd_table[] = {
	{ "lock", &RxilCmdLock, 0, FALSE, RXIL_PUBLIC },
	{ "unlock", &RxilCmdUnlock, 0, FALSE, RXIL_SECRET },

	{ "status", &cmd_status, 1, FALSE, RXIL_PUBLIC },
	{ "quit", &cmd_quit, 0, FALSE, RXIL_PUBLIC },
	{ "dump", &cmd_dump, 0, FALSE, RXIL_PUBLIC },
	{ "lcmd", &cmd_launch_cmd, 0, FALSE, RXIL_PUBLIC },
	{ "lfunc", &cmd_launch_func, 0, FALSE, RXIL_PUBLIC },
	{ "ptest", &cmd_ptest, 0, FALSE, RXIL_SECRET },

	/* Mark end-of-table */
	{ NULL, NULL, 0, FALSE, 0 }
};


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



struct RxilInvocation *rxi_cmd;
struct RxilInvocation *rxi_func;



/*--------------------------------------------------------------------*/


void main( int argc, char *argv[] )
{
	openlibrarys();


	/* =+=+=+=+=+=+=+=+=+  ARexx Interface Note +=+=+=+=+=+=+=+=+=+=+
	 * This will open the rexx library, and the desired ports.
	 * If all we want to do is recieve commands, we probably
	 * would not open the secret port, although we might. 
	 */
	global_rdef = RxilInit( RXIL_PUBLIC | RXIL_SECRET, "MYREXX_TEST" );
	if( global_rdef == NULL )
	{
		bailout( "Unable to init rexx", 0 );
	}


	/* =+=+=+=+=+=+=+=+=+  ARexx Interface Note +=+=+=+=+=+=+=+=+=+=+
	 * Init the members in the RxilDef structure which customize
	 * the way things work.
	 */

	global_rdef->Console = "CON:10/10/400/150/RexxCon";
		/* All commands or functions launched by this program will open
		 * a console window of this specification.  Set this to NULL to
		 * default to no window.
		 */

	global_rdef->Extension = "rexx";
		/* this normally would be an application
		 * specific macro filename extension.
		 */

	global_rdef->HostPort = "REXX";
		/* If this is AREXX, launches will default
		 * to async (as opposed to synchronous).
		 */

	global_rdef->CommandTable = &rexx_cmd_table[0];





	/* =+=+=+=+=+=+=+=+=+  ARexx Interface Note +=+=+=+=+=+=+=+=+=+=+
	 * Pre-allocate some invocation structures.  These could
	 * also be allocated and de-allocated on-the-fly if desired.
	 * One possible philosophy would be to allocate one structure
	 * for each possible macro command.  This would speed macro
	 * invocations by a slight amount.
	 */
	rxi_cmd = RxilCreateRxi( NULL, RXCOMM );
	if( rxi_cmd == NULL )
	{
		bailout( "Unable to allocate command_rxi", RETURN_FAIL );
	}

	rxi_func = RxilCreateRxi( NULL, RXFUNC );
	if( rxi_func == NULL )
	{
		bailout( "Unable to allocate function_rxi", RETURN_FAIL );
	}

	eventloop();

	cleanup();
}



/*-----------------------------------------------------------------*/


void eventloop( void )
{
	struct RxilInvocation *rxi;
	ULONG flags;

#if 0
	/* define some variables to store Intuition Message data in */
	struct IntuiMessage *message;
	ULONG class;
	USHORT code, qualifier;
	SHORT mouseX, mouseY;
	void *address;	/* void since this can point to Screens,
					 * Gadgets, etc. */
#endif

	while( !finished )	/* loop until closewindow causes a return() */
	{
		/* =+=+=+=+=+=+=+=+=+  ARexx Interface Note +=+=+=+=+=+=+=+=+=+=+
		 * Note that we include the rexx port signal bit(s) in the wait().
		 */
		flags = Wait( /* (1L<<win->UserPort->mp_SigBit) | */
			RXIL_WAITFLAG );


		/* =+=+=+=+=+=+=+=+=+  ARexx Interface Note +=+=+=+=+=+=+=+=+=+=+
		 * Now do the ARexx port stuff.
		 */
		if(  FlagIsSet( flags, RXIL_WAITFLAG )  )
		{
			RxilCheckPort();
		}

		printf( "---Event---\n" );
		printf( "rxi_cmd state: %d\n", (int)rxi_cmd->State );
		printf( "rxi_func state: %d\n", (int)rxi_func->State );

		while( rxi = RxilGetReturn() )
		{
			if( rxi->Type == RXCOMM )
			{
				printf( "Command Invocation completed\n" );

				RxilHandleReturn( rxi );

				RxilCleanupReturn( rxi );
			}
			else
			{
				printf( "Function Invocation completed\n" );

				RxilHandleReturn( rxi );

				RxilCleanupReturn( rxi );
			}
		}


#if 0
		while( message = (struct IntuiMessage *)
			GetMsg(win->UserPort) )
		{
			class = message->Class;
			code = message->Code;
			address = message->IAddress;
			mouseX = message->MouseX;
			mouseY = message->MouseY;
			qualifier = message->Qualifier;

			ReplyMsg( (struct Message *)message );

			switch( class )
			{
				BOOL bdown = FALSE;

				case MOUSEBUTTONS:
					if( code == SELECTUP )
						bdown = FALSE;
	
					if( code == SELECTDOWN )
						bdown = TRUE;

					break;

				case INTUITICKS:
					break;

				case VANILLAKEY:
					switch( code )
					{
						case 'E':
						case 'e':
							printf("Enter text: ");
							gets(buf);
							PrintScrollText( stext, buf );
							break;

						case 'd':
							break;

						case 'l':
							break;

						case 'r':
							break;
					}
					break;

				case GADGETUP:
				case GADGETDOWN:
					HandleScrollText( stext,
						((struct Gadget *)address), class );
					break;
	
				case CLOSEWINDOW:
					finished = TRUE;
					break;
			}
		}
#endif
	}
}




void cmd_status( struct RexxMsg *rexxmsg )
{
	printf( "Cmd status\n" );
	printf( "The FromRexx variable is %d\n", RXIL_FROM_REXX );

	switch( *RXIL_ARGV(1) )
	{
		case 'L':
		case 'l':
			RxilSetResult( rexxmsg, "Hi there!" );
			break;

		case 'B':
		case 'b':
			RxilSetResult( rexxmsg, "I'm NOT Fine!" );
			break;

		case 'X':
			rexxmsg->rm_Result1 = 20;
			break;

		case 'Y':
			rexxmsg->rm_Result1 = 100;
			break;

		case 'Z':
			rexxmsg->rm_Result1 = 200;
			break;

		default:
			rexxmsg->rm_Result1 = RXERR_BAD_VARIABLE;
	}
}



/* This will only succeed if the command comes in at the private port.
 */

void cmd_ptest( struct RexxMsg *rexxmsg )
{
	printf( "Cmd privlege test\n" );

	RxilSetResult( rexxmsg, "You are privleged indeed!" );
}



/* Cause the demo program to exit. */

void cmd_quit( struct RexxMsg *rexxmsg )
{
	printf( "Cmd quit\n" );

	finished = TRUE;
}



void cmd_dump( struct RexxMsg *rexxmsg )
{
	RxilDumpRdef( global_rdef );
}



void cmd_launch_cmd( struct RexxMsg *rexxmsg )
{
	char buf[100];
	LONG rc;


	printf( "Cmd launch command:" );
	gets( buf );

	rxi_cmd->Name = buf;
	rc = RxilLaunch( rxi_cmd );
	printf( "Launch returned %d\n", rc );
}



static char buf[16][100];


void cmd_launch_func( struct RexxMsg *rexxmsg )
{
	LONG rc;
	int i;


	printf( "Cmd launch function:" );
	gets( &buf[0][0] );

	for( i=1; i<16; i++ )
	{
		printf( "Enter arg %d: ", i );
		gets( &buf[i][0] );
		if( strlen(&buf[i][0]) > 0 )
		{
			rxi_func->FuncArg[i] = &buf[i][0];
		}
		else
		{
			rxi_func->FuncArg[i] = NULL;
			break;
		}
	}

	rxi_func->Name = &buf[0][0];
	rc = RxilLaunch( rxi_func );

	printf( "Launch returned %d\n", rc );
}



/*-----------------------------------------------------------------*/




void openlibrarys( void )
{
	/*   Intuition   */
	if(  ! ( IntuitionBase = (struct IntuitionBase *)
		OpenLibrary("intuition.library", 33 ) )  )
	{
		bailout( "Unable to open the Intuition Library", RETURN_FAIL );
	}

	/*   Graphics   */
	if(  ! ( GfxBase = (struct GfxBase *)
		OpenLibrary("graphics.library", 33 ) )  )
	{
		bailout("Unable to open the Graphics Library", RETURN_FAIL );
	}
}



void closelibrarys( void )
{
	if( IntuitionBase )   CloseLibrary( (struct Library *)IntuitionBase );
	if( GfxBase )   CloseLibrary( (struct Library *)GfxBase );
}



void cleanup( void )
{
	/* =+=+=+=+=+=+=+=+=+  ARexx Interface Note +=+=+=+=+=+=+=+=+=+=+
	 * This will handle ALL the cleanup details.  If we wished to make
	 * sure that there were no macro program invocations running before
	 * we call this routine (and it waits, which may distress the user)
	 * we should test our ability to terminate by calling RxilPending().
	 */
	RxilCleanup( global_rdef );
	global_rdef = NULL;

	closelibrarys();
}



void bailout( char *message, int rc )
{
	printf( "%s/n", message );
	cleanup();
	exit( rc );
}

