/* handle_return.c */

/*		Copyright © 1989 by Donald T. Meyer, Stormgate Software
 *		All Rights Reserved
 */

/*
 *    Modified:
 *    Andrew C. R. Martin           12.12.91    18:15
 *    SciTech Software
 *
 *    Changed display_message() to call MyAutoRequest() rather than 
 *    AutoRequest(). This looks better under V1.3.
 *
 *    Changed RxilHandleReturn() to take a second parameter which
 *    turns on the indication of a return from a REXX function.
 *    Also now returns 0 if no return value; 1 if there was.
 *
 */


#include "rxil.h"

#include <libraries/dos.h>
#include <intuition/intuitionbase.h>

#include <string.h>
#include <stdio.h>
#include <proto/dos.h>
#include <proto/intuition.h>



static void display_message( char *name, char *line1, char *line2 );



extern struct IntuitionBase *IntuitionBase;



static struct IntuiText itext[4] = {
	{ 2, 0, JAM1, 5, 3, NULL, (UBYTE *)"Okay", NULL },
	{ 2, 0, JAM1, 5, 5, NULL, NULL, &itext[2] },
	{ 2, 0, JAM1, 5, 15, NULL, NULL, &itext[3] },
	{ 3, 0, JAM1, 5, 25, NULL, NULL, NULL }
};




/* NAME
 *		RxilHandleReturn
 *
 * SYNOPSIS
 *		int RxilHandleReturn( rxi, noisy );
 *
 *		struct RxilInvocation *rxi;
 *    int                   noisy;
 *
 * FUNCTION
 *		Take appropriate action (i.e., notify user) for the return
 *		from an ARexx macro program.
 *
 *		The method of notification will be an Intuition Autorequester
 *		if the Intuition library has been opened.
 *		If it is not, the message will be sent to the CLI (if possible)
 *		by opening "*".  If this fails, no action is taken.
 *
 *		Output is via AmigaDOS functions such as Write(), as opposed
 *		to using 'C' standard I/O such as printf().
 *
 * INPUTS
 *		rxi = pointer to a RxilInvocation structure that has been
 *			replyed by the RexxMaster.
 *    noisy = flag to indicate routine should display returned value.
 *       0: no; 1: yes.
 *
 * RESULT
 *		int   0: No return value; 1: There was a return value.
 *
 * SIDES
 *
 * HISTORY
 *		01-Aug-89	Creation.
 *		10-Nov-89	Added Autorequester feature.
 *					Changed to use AmigaDOS I/O rather than 'C' stdio.
 *    12-Dec-91   Added noisy parameter and return value
 *
 * BUGS
 *
 * SEE ALSO
 *
 */

int RxilHandleReturn( struct RxilInvocation *rxi,
                      int                    noisy )
{
	struct RexxMsg *rexxmsg = rxi->RexxMsg;
	struct RexxArg *errmsg;
	char name_buf[60], buf1[60], buf2[60];


	/* There are four possible return states:
	 *	  Result1	Result2				Meaning
	 *	  ------	--------		----------------
	 *		0			0		Normal execution, no result requested.
	 *		0		   !=0		Normal execution, with result string.
	 *	   !=0			0		Error.  Result1 is code from EXIT n.
	 *	   !=0		   !=0		Error.  Result2 is Arexx error code.
	*/

	if(  ( rexxmsg->rm_Result1 == 0 ) && ( rexxmsg->rm_Result2 == 0 )  )
	{
		/* Everything was normal */
		return(0);
	}


	/* This will identify all text */
	sprintf( name_buf, "Macro: %.31s", ARG0(rexxmsg) );


	/* See if there was a result string (and no error) */
	if(  ( rexxmsg->rm_Result1 == 0 ) && ( rexxmsg->rm_Result2 != 0 )  )
	{
		/* There is a result string.  Not sure why a macro would return
		 * a result string to the application, and if it did there
		 * should be application-specific code to handle it, not this
		 * general-purpose routine.
		 * Oh, well, display it.
		 */

      if(noisy)
      {
   		if( strlen((char *)(rexxmsg->rm_Result2)) > 36 )
	   	{
		   	sprintf( buf2, "%.33s...", (char *)(rexxmsg->rm_Result2) );
   		}
	   	else
		   {
			   strcpy( buf2, (char *)(rexxmsg->rm_Result2) );
   		}

   		display_message( name_buf, "Returned this string:", buf2 );
      }

		return(1);
	}


	/* Need to deal with failure returns */
	if(  ( rexxmsg->rm_Result1 != 0 ) && ( rexxmsg->rm_Result2 == 0 )  )
	{
		/* There was a return code set */

		sprintf( buf1, "Returned with a %ld", rexxmsg->rm_Result1 );

		display_message( name_buf, buf1, NULL );

		return(0);
	}


	if(  ( rexxmsg->rm_Result1 != 0 ) && ( rexxmsg->rm_Result2 != 0 )  )
	{
		/* An errorcode was returned */

		sprintf( buf1, "Returned with error level %ld",
			rexxmsg->rm_Result1 );

		if( ErrorMsg( rexxmsg->rm_Result2, &errmsg ) )
		{
			/* A valid error code */
			sprintf( buf2, "%.38s", errmsg->ra_Buff );
		}
		else
		{
			sprintf( buf2,
				"(The Error Code itself [%ld] is Invalid!)",
				rexxmsg->rm_Result2 );
		}

		display_message( name_buf, buf1, buf2 );
	}
}



static void display_message( char *name, char *line1, char *line2 )
{
	ULONG height;
	BPTR fh;



	/* See if we can use an autorequester */

	if(  ( IntuitionBase == NULL ) ||
		FlagIsSet( global_rdef->Flags, RXIL_NO_REQ )  )
	{
		/* Send to the CLI. */

		if(  ( fh = Open( "*", MODE_READWRITE ) ) == NULL  )
		{
			/* Can't send to the CLI.  Don't do anything apparently. */
			return;
		}

		Write( fh, name, strlen(name) );
		Write( fh, "\n", 1 );
		Write( fh, line1, strlen(line1) );
		Write( fh, "\n", 1 );

		if( line2 != NULL )
		{
			Write( fh, line2, strlen(line2) );
			Write( fh, "\n", 1 );
		}

		Close( fh );
	}
	else
	{
		/* Intuition has been opened.  Let's post a requester. */

		itext[1].IText = name;
		itext[2].IText = line1;

		if( line2 == NULL )
		{
			height = 64;
			itext[3].IText = "";
		}
		else
		{
			height = 74;
			itext[3].IText = line2;
		}

/* ACRM+ Chenged to MyAutoRequest()
*/
		MyAutoRequest( global_rdef->CancelWindow,
			&itext[1], &itext[0], &itext[0],
			NULL, NULL, 320, height );
/* ACRM- */
	}
}

