// Compile with:  Sc Link NoDebug TestDoor.c

#include <exec/types.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <proto/exec.h>
#include <proto/dos.h>

#define RLIB_MACRO
#include <Reccoon/Recclib.h>
#include <Reccoon/All.h>
#include <Reccoon/DoorMacro.h>

extern struct DosLibrary *DOSBase;

unsigned char		*Program_ID 	= "\0$VER: My_Door 0.57.0 (28.08.93)\n\r\0\0";

struct CtrlMessage 	ctrlmsg;
struct control *	ctrl		= 0;
struct MsgPort *	ctrlport	= 0;
struct MsgPort *	ctrlreplyport	= 0;
struct Library *	RecclibBase	= 0;

void *			doordata=0;
struct DoorCallback *	dcb;
struct InternalData *	id;
struct ReccNode *	rn;

UBYTE 			outbuff[100];

int Sluta( int );
int CXBRK(void);

#define puts(x) Write(Output(),x,sizeof(x))

void main(UWORD argc, UBYTE *argv[])
{
UWORD line;

/* The line number is passed as an argument to the program */

	if(argc!=2||argv[1][0]<'0'||argv[1][0]>'9'){
		puts("This is a Rcn door program, and should not be run from the CLI.\n");
		exit(20);
	}
	line=atoi(argv[1]);

	RecclibBase=OpenLibrary("reccoon.library",0);
	if(!RecclibBase) exit(20);

/* Open ReccControl. Always use line number -1 for doors and utilities */

	ctrl=OpenRCtrl(0,65535,&ctrlmsg,&ctrlport,&ctrlreplyport);
	if(!ctrl){
		CloseLibrary(RecclibBase);
		exit(10);
	}

/* Set an exit trap so the program never exits without cleanup */

	onexit((void *)Sluta);

/* Find this line's ReccNode structure */

	for(rn=ctrl->reccnodes;rn && rn->line!=line;rn=rn->next);
	if(!rn || !rn->flags.running) exit(10);

/*
** Here we got all callback functions and internal data for this
** Reccoon line.
*/

	dcb = rn->doorcallback;
	id  = rn->internaldata;

/* Reccoon need to allocate some memory etc for your door. */

	doordata = OpenDoor();
	if(!doordata) exit(20);

/* Send a string to the user */

	SendString("Testing...\n\r",0);

/*
** Let the BBS continue. Note that you still can send door commands
** to Reccoon.
*/

	ContinueBBS();

/* Five seconds delay */

	Delay(50*5);

/* Now send a new string to the user */

	SendString("5 secs later..\n\r",0);

/* Simple example of how to access the internal data */

	sprintf(outbuff,"You are at menupage %d.\n\r",id->menupage);
	SendString(outbuff,0);

/* How to send async commands: */

	{
	UBYTE signal;
	UWORD result;

		signal=AllocSignal(-1);			// Rcn will signal this bit
							// when the command is executed

		AsyncMode(FindTask(0L),1L<<signal);	// ASync mode ON
							// If you don't want Rcn to signal when
							// the command is executed, simply use
							// AsyncMode(0,0);
		SendString("\n\rEnter something: ",0);
		puts("SendString\n");
		GetString(outbuff,40,0);		// Rcn will wait for SendString()
							// to finish before it execute
							// the GetString() command.

		while(!(SetSignal(0L,0L) & (1L<<signal))){// Until Rcn signals
			Write(Output(),"Hello\n",6);
			Delay(25);			// 0.5 sec delay
		}

		result=(UWORD)GetAsyncRes();		// Get result from last command

		SyncMode();				// Async mode OFF
		FreeSignal(signal);			// Free our signal

		SendString("\n\rYou wrote ",0);		// Display result
		SendString(outbuff,0);
		sprintf(outbuff," and GetString() returned %d.\n\r",result);
		SendString(outbuff,0);
	}

	exit(0);

}

/*
** Cleanup routine. This routine is always executed when
** this program exits. 
*/

int Sluta(int e)
{


/* Deallocate the memory Reccoon allocated at startup */

	if(doordata) CloseDoor();
	doordata=0;

/* Close ReccControl and reccoon.library */

	if(RecclibBase){
		CloseRCtrl(ctrlport,ctrlreplyport,&ctrlmsg);
		CloseLibrary(RecclibBase);
		RecclibBase=0;
	}


	return(e);
}

int CXBRK(void) { return(0); }

