#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <exec/types.h>
#include <exec/exec.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* This code was polished by Fredrik Rambris to go through more
strict compilers such as StormC. */

struct DoorMsg {
	struct Message Door_Msg;
	short command;
	short data;
	char string[80];
	short carrier;
	};

struct DoorMsg *doormsg,*garbage;
struct MsgPort *MyPort,*replyport;

struct Task *mytask; /* Pointer to this task so we can name it */

int err;
/*
 * end() -  Notifies Paragon that we are done and ready to continue with
 *		the BBS.  ALWAYS use this to exit from your program, or
 *		the BBS will go to never-never land.
 */

void end( void )
{
	doormsg->command = 20;
	PutMsg(MyPort,(struct Message *)doormsg);
	(void)WaitPort(replyport);
	(void)GetMsg(replyport);
	FreeMem(doormsg,(long)sizeof(*doormsg));
	DeletePort(replyport);
	exit(0);
}

/*
 * getsvar(typ,mstring) - Gets certain string variables from Paragon.
 * "mstring" is a pointer to a string to dump the string into.  "typ" tells
 * it what you want: 1=Name, 2=Password, 3=Address, 4=City, 5=State
 * 6=Postal code, 7=Door pathname, 8=Default BBS pathname.
 */

void getsvar( int typ, char *mstring )
{
	doormsg->data = typ;
	doormsg->command = 14;
	PutMsg(MyPort,(struct Message *)doormsg);
	(void)WaitPort(replyport);
	strcpy(mstring,doormsg->string);
	(void)GetMsg(replyport);
}

/*
 * sendmessage(mstring,nl) - Sends a message to the local window and to
 * the modem (if applicable).  "mstring" is the output string you want to
 * send, "nl" is and integer which is 1 if you want it to send the
 * c/r+l/f combination, or 0 if not.
 */

void sendmessage( char mstring[], int nl )
{
	doormsg->data = nl;
	doormsg->command = 1;
	strcpy(doormsg->string,mstring);
	PutMsg(MyPort,(struct Message *)doormsg);
	(void)WaitPort(replyport);
	(void)GetMsg(replyport);
}

/*
 * hotkey(mstring,ostring) - outputs the string "mstring" and waits
 * for one key which it will place in element [0] of "ostring".
 * "mstring" may be a null string, in which case it will only wait for
 * the key, and not output any prompt.
 */

void hotkey( char mstring[], char *ostring )
{
	strcpy(doormsg->string,mstring);
	doormsg->command = 8;
	PutMsg(MyPort,(struct Message *)doormsg);
	(void)WaitPort(replyport);
	(void)GetMsg(replyport);
	strcpy(ostring,doormsg->string);
}

/*
 * prompt(mstring,ostring,len) - outputs the string "mstring" and inputs
 * a string which is placed in ostring.  'len' is the maximum number of
 * characters which will be accepted.
 */

void prompt( char mstring[], char *ostring, int len )
{
	strcpy(doormsg->string,mstring);
	doormsg->data=len;
	doormsg->command = 6;
	PutMsg(MyPort,(struct Message *)doormsg);
	(void)WaitPort(replyport);
	(void)GetMsg(replyport);
	strcpy(ostring,doormsg->string);
}


/* showfile(mstring) shows the text file which mstring is the path to.
   It handles ^C aborting, and ^S/^Q pausing. */

void showfile( char mstring[] )
{
	strcpy(doormsg->string,mstring);
	doormsg->command = 10;
	PutMsg(MyPort,(struct Message *)doormsg);
	(void)WaitPort(replyport);
	(void)GetMsg(replyport);
}

/****************************************************
	These two functions were added by
	     SWhite. MAX's BBS only!
****************************************************/
/* enter a menu function to execute 1-33 */
void domenu( int menu, int extra, char *filename )
{
	strcpy(doormsg->string,filename);
	doormsg->command = menu+100;
	doormsg->data	 = extra;
	PutMsg(MyPort,(struct Message *)doormsg);
	(void)WaitPort(replyport);
	(void)GetMsg(replyport);
}

/* change user information 1-15 */
void changeuserint( int number, long val )
{
	long *ptr;

	ptr = (long *)&doormsg->string;	/* We need a long value not a ptr */
	*ptr = val;

	doormsg->command = 200;
	doormsg->data    = number;
	PutMsg(MyPort,(struct Message *)doormsg);
	(void)WaitPort(replyport);
	(void)GetMsg(replyport);
}


void main( int argc, char *argv[] )
{
	char buffer[81],buffer2[81],line_number;
	char cportname[12];	/* ReplyPort and Control Port names */
	long value;


	/* Pull out the line number from the argv field to find where we are */

	line_number=argv[1][0];

	mytask=(struct Task *)FindTask(0L);
	mytask->tc_Node.ln_Name = "DoorExample";

	/* Create the Reply port, with the name based on the number... */

	sprintf(buffer,"DoorReply%c",line_number);
	replyport=(struct MsgPort *)CreatePort(buffer,0L);

	doormsg=(struct DoorMsg *)AllocMem((long)sizeof(*doormsg),MEMF_PUBLIC);

	if(doormsg==0)
	{
		puts("Couldn't allocate DoorMsg!");
		return;
	}

	doormsg->Door_Msg.mn_Node.ln_Type = NT_MESSAGE;
	doormsg->Door_Msg.mn_ReplyPort = replyport;
	doormsg->Door_Msg.mn_Length = (UWORD)sizeof(*doormsg);

	/* Locate the correct DoorControl port based on the line number */

	sprintf(cportname,"DoorControl%c",line_number);
   	MyPort=(struct MsgPort *)FindPort(cportname);
   	if(MyPort==0L)
	{
		puts("DoorControl port not located!");
		FreeMem(doormsg,(long)sizeof(*doormsg));
		return;
	}

	sendmessage("\r\nHi there!\r\n",1);
	hotkey("Press any key to continue...",buffer);

	for(;;)
	 {
		prompt("\nEnter some text (CR to Exit) : ",buffer,20);
		if(buffer[0] == NULL) break;
	  	strcpy(buffer2,"\nYou typed : ");
		strcat(buffer2,buffer);
	   	sendmessage(buffer2,1);
	 }

	prompt("\nEnter a filename to print : ",buffer,64);
	showfile(buffer);

	sendmessage("\nHere is some info on you and the bbs...",1);
	getsvar(1,buffer);
	strcpy(buffer2,"Name : ");
	strcat(buffer2,buffer);
	sendmessage(buffer2,1);

	getsvar(2,buffer);
	strcpy(buffer2,"Password : ");
	strcat(buffer2,buffer);
	sendmessage(buffer2,1);

	getsvar(3,buffer);
	strcpy(buffer2,"Address : ");
	strcat(buffer2,buffer);
	sendmessage(buffer2,1);

	getsvar(4,buffer);
	strcpy(buffer2,"City : ");
	strcat(buffer2,buffer);
	sendmessage(buffer2,1);

	getsvar(5,buffer);
	strcpy(buffer2,"State : ");
	strcat(buffer2,buffer);
	sendmessage(buffer2,1);

	getsvar(6,buffer);
	strcpy(buffer2,"Postcode : ");
	strcat(buffer2,buffer);
	sendmessage(buffer2,1);

	getsvar(7,buffer);
	strcpy(buffer2,"Door Path : ");
	strcat(buffer2,buffer);
	sendmessage(buffer2,1);

	getsvar(8,buffer);
	strcpy(buffer2,"Default path : ");
	strcat(buffer2,buffer);
	sendmessage(buffer2,1);


	prompt("\nEnter a user int to change (1-15, CR to skip) : ",buffer,5);
	if(buffer[0] != NULL)
         {
	    prompt("\nEnter new value : ",buffer2,10);
	    changeuserint(atoi(buffer),atol(buffer2));
	 }

	prompt("\nEnter a menu function number : (1-33, CR to skip) : ",buffer,5);
	if(buffer[0] != NULL)
	 {
	    prompt("\nEnter a value for Extra : ",buffer2,5);
	    value = atoi(buffer2);
	    prompt("\nEnter a value for Name/FileName/Dest : ",buffer2,80);
	    domenu(atoi(buffer),value,buffer2);
	 }

	end();
}


