#include "fidoterm.h"
#include "mem.h"
#include <ctype.h>

/* 

	ASCII download

*/

down(fn)
char *fn;
{
int crtime,chartime,lasttime;
int f,i,c,echo;
char stopflg,update;
int linelen;
int charmax,charmin,crmin,crmax;		/* upper/lower output limits */

	f= open(fn,OPEN_RO);
	if (f == -1) {
		msg("Can't find file %s",fn);
		return(0);
	}
	linelen= 0;				/* for detecting blank lines */
	stopflg= 0;				/* not aborted (yet) */

	charmin= 1;				/* shortest */
	charmax= 10;				/* longest delay tween chars */
	chartime= charmax;

	crmin= 10;
	crmax= 25;				/* different max. for CRs */
	crtime= crmax;
	update= 1;				/* yes, update screen message */

	while((c= get_snd(f)) && !stopflg) {
		if (update) {
			w_pos(&status,0,0);
			w_printf(&status,"FILE: %-30s ESCape to abort  1 -- 9 set speed limit [ ]",
			    fn,10 - chartime);
			update= 0;		/* screen update complete */
			lasttime= -1;		/* force speed update */
		}
		if (lasttime != chartime) {
			w_pos(&status,0,78);	/* kludge */
			w_printf(&status,"%d",10 - chartime);
			lasttime= chartime;
		}
		switch (c) {
			case TAB:
				++linelen;
				put_modem(c);			/* output the tab */
				while (getecho(&chartime,chartime,chartime) != -1);
				break;

			case CR:
			case CR + 128:
				if (linelen == 0) 		/* no 0 length lines */
					put_modem(' ');
				put_modem(c); 			/* send the character, */
				linelen= 0;			/* start new line */
				while (getecho(&crtime,crmin,crmax) != -1);
				break;

			case LF:
				if (! alfflg) break;
				linelen= -1;			/* decremented ... */
			default:
				++linelen;
				put_modem(c);			/* send the character, */
				getecho(&chartime,charmin,charmax);
				break;
		}
		for (i= 100; --i;) {			/* get any extras */
			if (getecho(&chartime,charmin,charmax) == -1) break;
		}

/* Check for key pressed. Abort if ESCape, and adjust the speed if
a digit 0 - 9. 0 is the same as 10. */

		if (c= keyhit()) {
			if (c == cmdchar) {
				stopflg= ask("Stop sending text?");
				update= 1;
			}
			if (isdigit(c)) {
				c -= '0'; if (c == 0) c= 10;	/* make it 1 - 10 */
				charmax= 10 - c;		/* set max. delay */
				chartime= max(chartime,charmax);/* set upper limit */
			}
		}
	}
	close(f);

	if (stopflg) msg("Aborted"); else msg("Complete");
	return(1);
}

/* Wait for the echoed character, and adjust the delay so that it
just times out. Return -1 if no character was received. If half duplex,
don't wait no matter what we're told. */

getecho(time,mintime,maxtime)
int *time,mintime,maxtime;
{
int c;

	if (hdxflg) {				/* if local echo */
		c= get_modem();			/* flush chars */
		put_console(c);			/* modem --> console */
		return(c);
	}
	c= ascin(*time);			/* get echo, */
	if (c != -1) {				/* try to squeeze delay */
		if (c == DC3) c= xoffw();	/* just short enough */
		--*time;			/* to time out, */

	} else {				/* if it does, get lost char */
		++*time;			/* and increase timer, */
		c= ascin(*time);		/* probably happen fast */
	}
	*time= max(*time,mintime);		/* lower bound, */
	*time= min(*time,maxtime);		/* upper bound, */
	return(c);
}

/* Get a character, wait (n) centiseconds maximum; return the character or
-1. (We assume that n will be 6000 mS max.) */

ascin(n)
int n;
{
int c;

	chr_timer= 0L; 					/* reset timer */
	for (c= -1, n *= 10; (c == -1) && (chr_timer < n); ) {
		put_console(c= get_modem());		/* get/echo char */
	}
	return(c);
}

/* Wait until any character but control-S is detected, and return it. Watch
the keyboard for a break too. */

xoffw() {
int c;
	for (c= -1; (c == -1) || (c == DC3);) {	/* any char except DC3 */
		put_console(c= get_modem());	/* echo chars */
		if (keyhit() == cmdchar)	/* if manual abort */
			c= cmdchar;		/* flag it */
	}
	return(c);				/* return it */
}
/* Return the next character from the buffer, else 0 if error or empty. */

get_snd(f) 
int f;
{

char c;
int r;
	if (! read(f,&c,1)) return(NUL);	/* end of file becomes NUL */
	if (parflg) c &= 0x7f;			/* strip off any parity */
	if (c == SUB) return(NUL);		/* CPM end of file */
	return(c);
}


