/*
				Sample Desk Accessory for SHADOW

		This program was written in Megamax C to show how you
		can access SHADOW with your own program!	The program
		does not implement all the features of SHADOW.	That's
		left up to you to finish. :-)	When you finish, please
		send us your program, we would love to see it!	The SHADOW
		Driver and SHADOW Desk Accessory are copyrighted material
		and may not be copied unless for archival purposes by the
		owner only!	Any distribution of the SHADOW Driver and/or
		SHADOW Desk Accessory without the written permission of ANTIC
		and Double Click Software is strictly prohibited. 

		SHADOW is Copyright (C) 1988 Double Click Software
		Megamax C/Laser C are Copyright (C) 1986,1988 Megamax Inc.

*/

#include	<gemdefs.h>
#include	<osbind.h>
#define 	TRUE	 1
#define 	FALSE	 0

extern int	gl_apid;

int	gl_hchar;
int	gl_wchar;
int	gl_wbox;
int	gl_hbox;	/* system sizes */
int	menu_id ;	/* our menu id */
int handle;		/* physical workstation handle */
int	msgbuff[8];	/* event message buffer */
int	keycode;	/* keycode returned by event-keyboard */
int	mx,my;		/* mouse x and y pos. */
int	butdown;	/* button state tested for, UP/DOWN */
int	ret;		/* dummy return variable */

int	contrl[12];
int	intin[128];
int	ptsin[128];
int	intout[128];
int	ptsout[128];	/* storage wasted for idiotic bindings */

int work_in[11];	/* Input to GSX parameter array */
int work_out[57];	/* Output from GSX parameter array */
int pxyarray[10];	/* input point array */

/*
		Misc. varibles for the program
*/

char path[50],insel[50];
int status,option;
long total_bytes,length,buffer;

/*
				SHADOW Record

	int		block		= current transfer block
			status		= status of transfer
	long	received	= number of bytes received
			send		= number of bytes sent
	int		num_files	= number of files received or sent
	long	b_length	= file size of batch receive or send [32 Max.]
	char	bfile_name	= filename of batch receive or send [32 Max.]
	int		digit		= 0=OFF,1=ON
			bell		= 0=OFF,1=ON
			mode		= current transfer type
			type		= receiving=1 or sending=2
			dial		= dialing flag [0=NO,1=YES]

*/
struct SHADOW_REC	{
			 int block,status;
			 long received,sent;
					int num_files;
					long b_length[32];
					char bfile_name[32][16];
					int digit,bell,mode,type,dial;
			 };
struct SHADOW_REC *shdw_rec;
/*
	 SHADOW Handler TRAP calls

		Get pointer to SHADOW record

*/
shdw_record()
{
asm		{
	  move.w 	 #0,-(A7)
	  trap		  #15
	  addq.l 	 #2,A7
	  move.l 	 D0,shdw_rec(A4)
	  }
}
/*
		Start receiving file
*/
shdw_receive(buffer,length,mode)
long buffer,length;
int mode;
{
asm	{
	move.l	length(A6),-(A7)
	move.l	buffer(A6),-(A7)
	move.w	mode(A6),-(A7)
	move.w	#1,-(A7)
	trap	#15
	adda.l	#12,A7
	}
}
/*
		Start sending file
*/
shdw_send(buffer,length,mode)
long buffer,length;
int mode;
{
asm	{
	move.l	length(A6),-(A7)
	move.l	buffer(A6),-(A7)
	move.w	mode(A6),-(A7)
	move.w	#2,-(A7)
	trap	#15
	adda.l	#12,A7
	}
}
/*
		ABORT transfer!
*/
shdw_abort()
{
asm	{
	move.w	#3,-(A7)
	trap	#15
	addq.l	#2,A7
	}
}

/*
		Set SHADOW preferences
*/

/* option = 4 yes digits, 5 = no digits, 6 = yes bell, 7 = no bell */

shdw_pref(option)
int option;
{
asm		{
		move.w	option(A6),-(A7)
		trap	#15
		addq.l	#2,A7
		}
}
/*
		Get the length and address
		of the transfer buffer.
*/
shdw_start() {
asm {
	move.l	0x42e, A0
	move.l	2(A0), length(A4)
	move.l	16(A0), buffer(A4)
	}
}
/*
		Check if SHADOW is present

		status	= 1 YES
				= 0 NO
*/
shdw_check()
{
asm	{
		move.w	#1,status(A4)
		move.l	0x42e,A0
		move.w	(A0),D0
		cmp.w	#0xdc,D0
		beq		leave
		move.w	#0,status(A4)
leave:
	}
}

/* dial a number
*/

shdw_dial(number, connect, fail1, fail2)
register char *number, *connect;
char *fail1, *fail2;
{
	asm {
		move.l	fail2(A6), -(A7)
		move.l	fail1(A6), -(A7)
		move.l	connect, -(A7)
		move.l	number, -(A7)
		move.w	#9, -(A7)
		trap	#15
		adda.l	#18, A7
	}
}

/*
		Main program
*/
main()
{
	appl_init();
	Supexec(shdw_check);
	if (!status)
		{
		form_alert(1,"[1][ SHADOW Demo | | Handler not installed!][  Opps  ]");
		goto quit;
		}
	Supexec(shdw_start);
	shdw_record();
	handle=graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox);
	menu_id=menu_register(gl_apid,"  SHADOW Demo");
	strcpy(&path,"A:\\*.*");
	status=0;
quit:
	multi();
}


multi()
{
int event,handle,opt;
long total;

	while (TRUE)
		{
		event = evnt_multi(MU_MESAG ,
				1,1,butdown,
				0,0,0,0,0,
				0,0,0,0,0,
				msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret);

		if (event & MU_MESAG)
			switch (msgbuff[0])
				{
				case AC_OPEN:
						if (msgbuff[4] == menu_id)
							{
							strcpy(&path[3],"*.*");
							status=shdw_rec->status;
/*
			NOTE:	Not all the possible options are checked!!!
*/
							switch(status)
								{
								case 0:
									opt=form_alert(3,"[1][ SHADOW Demo - Version 1.0| | written by Paul Lee| (C) Double Click Software 1988][ Send | Receive | Exit ]");
									if (opt==2)
										{
										total_bytes=0;
										opt=form_alert(1,"[2][ SHADOW Demo | | Select transfer type][CRC|Checksum|Ascii]");
										if (opt==3)
											option=3;
										else if (opt==1)
											option=1;
										else
											option=0;
										shdw_receive(buffer,length,option);
										}
									else if (opt==1)
										{
										total=0;
										fsel_input(&path,&insel,&opt);
										if (opt)
											{
											strcpy(&path+strlen(&path)-3,&insel);
											opt=form_alert(1,"[2][ SHADOW Demo| | Select transfer type][CRC|CRC 1K|Ascii]");
											if (opt==1)
												option=1;
											else if (opt==2)
												option=2;
											else
												option=3;
											handle=Fopen(&path,0);
											if (handle>=0)
												{
												total_bytes=Fread(handle,length,buffer);
												shdw_rec->status=7;
												}
											else
												break;
											Fclose(handle);
											}
										}
									break;
								case 1:
	  									opt=form_alert(2,"[2][ SHADOW Demo| | Transfer in progress!][ Abort | OK ]");
	  									if (opt==1)
											shdw_abort();
									break;
								case 2:
	  								opt=form_alert(1,"[1][ SHADOW Demo| | Xmodem Transfer completed!][Save|No Save|Exit]");
									if (opt==1)
										{
save_file:
										fsel_input(&path,&insel,&opt);
										strcpy(&path+strlen(&path)-3,&insel);
										if (opt)
											{
											handle=Fcreate(&path,0);
											if (handle>=0)
												{
												total_bytes=shdw_rec->received;
												total=Fwrite(handle,total_bytes,buffer);
												if (total>=0)
													shdw_rec->status=0;
												else
													form_alert(1,"[2][ SHADOW Demo| | Error in writing file!][  OK	]");
												}
											Fclose(handle);
											}
										}
									else if (opt==2)
										shdw_rec->status=0;
									break;
								case 4:
									form_alert(1,"[2][ SHADOW Demo| | Other end aborted transfer!][	OK	]");
									shdw_rec->status=0;
									break;
								case 5:
									form_alert(1,"[1][ SHADOW Demo| | Send complete!][  OK	]");
									shdw_rec->status=0;
									break;
								case 6:
									form_alert(1,"[2][ SHADOW Demo| | Buffer overflow!][  OK  ]");
									shdw_rec->status=0;
									break;
								case 7:
										opt=form_alert(3,"[2][ SHADOW Demo| | Begin transfer!	][OK|Abort|Exit]");
									if (opt==1)
										shdw_send(buffer,total_bytes,option);
									else if (opt==2)
										shdw_rec->status=0;
									break;
								case 9:
	  								opt=form_alert(2,"[2][ SHADOW Demo| | Save capture buffer?][ Yes | No ]");
	  								if (opt==2)
										shdw_abort();
									else
										goto save_file;
									break;
								case 10:
	  								opt=form_alert(2,"[2][ SHADOW Demo| | Abort sending buffer?][ Yes | No ]");
	  								if (opt==1)
										shdw_abort();
									else
										shdw_rec->status=0;
									break;
								default:
										form_alert(1,"[2][ SHADOW Demo| | Please stand by!	][	OK	]");
									break;
								}
							}
					}
	 	}
}

