
/******
 * Various include
 ******/

#include "ProgED:sources/include/Ped.h"
#include <stdio.h>
#include <stdlib.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <rexx/errors.h>



/******
 * Prototypes
 ******/

LONG ASM SAVEDS CmdBeep( RG(a0) struct CommandData * );
void OpenOurWindow( void );
void CloseOurWindow( void );
void SendMessageToPED( struct APIMessage * );



/******
 * Global variables
 ******/

struct IntuitionBase	*IntuitionBase;
struct Window		*PEDWindow;
struct Screen		*PEDScreen;
struct MsgPort		*MyPort,
			*PEDPort;

static int tre=3;

struct ArexxExtCmds	MyCmdBeep={
TRUE,			/* TRUE=External commands */
"BEEP",			/* Command's name */
"NUM/N,FLAG/S",		/* Template for ReadArgs */
{&tre,0,},		/* Default array for all arguments (tre is the italian word for 3 :-) */
CmdBeep,		/* Command management function */
NULL			/* Set this to NULL! Thanks. *****/
};

struct APIClient	MyClient={
NULL,					/* This field will be filled later... */
NOTIFY_ON_SHOW_HIDE|NOTIFY_ON_KEY,	/* Let me know when you close or open your screen */
"prova cliente",			/* Client's name (not used, till now) */
NULL					/* Set this to NULL! Thanks */
};



/*****
 *
 * FUNCTION:	void main(void)
 *
 * AIM:		Finds ProgED API port, register us as client and
 *		open a window on ProgED screen. Adds an internal
 *		command BEEP which, is executed (as any internal
 *		command) has the only effect to call the function
 *		DisplayBeep (see function CmdBeep).
 *
 * RESULT: -
 *
 ****/

void main(void)
{
	struct APIMessage	 msg,
				*mess;
	struct IntuiMessage	*imsg;
	UBYTE			 finito;



	/***** Find the ProgED port *****/
	if (!(PEDPort=FindPort("PED_API")))
	{
		printf("Can't find ProgED API Port!\n");
		exit(0);
	}

	/***** Create a port which will be used to receive msgs from ProgED *****/
	if (!(MyPort=CreateMsgPort()))
	{
		printf("Can't create a MsgPort!\n");
		exit(0);
	}

	/***** Fill in the ac_ClientPort field of the structure APIClient which
		will be used for registering *****/
	MyClient.ac_ClientPort=MyPort;

	/***** Open intuition.library :-)) *****/
	if (!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0)))
	{
		DeleteMsgPort(MyPort);
		printf("Can't open intuition.library!\n");
		exit(0);
	}

	/***** Register us as client *****/
	msg.am_MsgType=PED_API_REGISTER;
	msg.am_MsgArg[0]=(ULONG)&MyClient;
	SendMessageToPED(&msg);

	/***** Add an internal command "BEEP" *****/
	msg.am_MsgType=PED_API_ADD_INTERNAL_COMMAND;
	msg.am_MsgArg[0]=(ULONG)&MyCmdBeep;
	SendMessageToPED(&msg);

	/***** Get the ProgED screen address *****/
	msg.am_MsgType=PED_API_GET_SCREEN_ADDRESS;
	SendMessageToPED(&msg);

	/***** If this isn't zero open a window. If it's NULL ProgED is
		actually iconified! In this case it will send us a
		message to let us know as soon as we must open our window *****/
	if (msg.am_RC)	OpenOurWindow();

	/***** Main loop *****/
	finito=FALSE;
	while(!finito)
	{
		WaitPort(MyPort);
		while(mess=(struct APIMessage *)GetMsg(MyPort))
		{
			switch(mess->am_MsgType)
			{
				/***** ProgED is quitting!
					Let's quit, too :-( *****/
				case	PED_API_QUIT:
					finito=TRUE;
				break;

				/***** ProgED is closing its screen.
					Let's close our window,too *****/
				case	PED_API_HIDE:
					CloseOurWindow();
				break;

				/***** ProgED is opening its screen
					Let's open our window,too *****/
				case	PED_API_SHOW:
					OpenOurWindow();
				break;

				/***** User has pressed RETURN key ? *****/
				case	PED_API_KEY:
					imsg=(struct IntuiMessage *)mess->am_MsgArg[0];
					if (imsg->Code==196)	DisplayBeep(0);
				break;
			}

			mess->am_RC=0;

			ReplyMsg((struct Message *)mess);
		}
	}

	/***** Free all and exit *****/
	DeleteMsgPort(MyPort);
	CloseLibrary((struct Library *)IntuitionBase);
	exit(0);
}



/*****
 *
 * FUNCTION:	void OpenOurWindow(void)
 *
 * AIM:		Open a simple window on ProgED screen.
 *
 * RESULT: -
 *
 ****/

void OpenOurWindow(void)
{
	PEDWindow=OpenWindowTags(NULL,
		WA_Width,		100,
		WA_Height,		80,
		WA_Title,		"Let's try !!!!!!!!",
		WA_DepthGadget,		TRUE,
		WA_SizeGadget,		TRUE,
		WA_DragBar,		TRUE,
		WA_SmartRefresh,	TRUE,
		WA_PubScreenName,	"PED_SCREEN",
	TAG_DONE);
}



/*****
 *
 * FUNCTION:	void CloseOurWindow(void)
 *
 * AIM:		Chiude la finestra aperta tramite OpenOurWindow().
 *
 * RESULT: -
 *
 ****/

void CloseOurWindow(void)
{
	if (PEDWindow)	CloseWindow(PEDWindow);
	PEDWindow=NULL;
}



/*****
 *
 * FUNCTION:	LONG CmdBeep(struct CommandData *data)
 *
 * AIM:		This is the management function for BEEP command.
 *		As you can see all arguments are extracted from
 *		data->CommandArg[] array. ProgED has already called
 *		ReadArgs function.
 *
 *		This command does a single beep if the user has
 *		specified th flag "FLAG" or "n" beeps if the
 *		used has specified the syntax: "BEEP NUM <n>".
 *
 * RESULT: -
 *
 ****/

LONG ASM SAVEDS CmdBeep(RG(a0) struct CommandData *data)
{
	long	num=*((LONG *)data->CommandArgs[0]),
		flag=(long)data->CommandArgs[1];
	int	i;

	if (flag)
	{
		for(i=0;i<num;i++)
		{
			DisplayBeep(NULL);
			Delay(50);
		}
	}
	else	DisplayBeep(NULL);

	return(RC_OK);
}



/*****
 *
 * FUNCTION:	void SendMessageToPED(struct APIMessage	*msg)
 *
 * AIM:		This function sends a message to ProgED.
 *
 * RESULT: -
 *
 ****/

void SendMessageToPED(struct APIMessage	*msg)
{
	msg->am_Message.mn_Node.ln_Succ=NULL;
	msg->am_Message.mn_Node.ln_Pred=NULL;
	msg->am_Message.mn_Node.ln_Type=NT_MESSAGE;
	msg->am_Message.mn_Node.ln_Pri=0;
	msg->am_Message.mn_Node.ln_Name=NULL;
	msg->am_Message.mn_ReplyPort=MyPort;
	msg->am_Message.mn_Length=sizeof(struct APIMessage);

	PutMsg(PEDPort,(struct Message *)msg);
	WaitPort(MyPort);
	while(GetMsg(MyPort));
}
