/*
 *				T 4
 *
 * Read a text line (with wraparound) from the user file.
 * Includes eof magic and a little routine to center text.
 */

#include	<stdio.h>
#ifdef	vms
#include	<ctype.h>
#define	FALSE	0
#define	TRUE	1
#endif
#include	"t.h"

static	char	blob100[] = "\233(0`\233(B ";
static	char	blob52[]  = "\233Fh\233G ";

char *
getline(row)
int		row;		/* Needed for eofmsg hack		*/
/*
 * Read one printable (80 byte) line from infd, return line start.
 */
{
	register char	*tp;		/* Text start			*/
	register char	*ep;		/* Text end			*/
	register int	ccpos;		/* Line width in columns	*/
	extern char	*bigline();

	ccpos = 0;				/* Good place to start	*/
	if (rec_savec == EOS) {
		if ((tp = bigline(row)) == NULL || columnsperline == 0) {
			rec_txt = tp;		/* Good place to start	*/
			return (tp);		/* Endfile or no width	*/
		}
	}
	else {
		/*
		 * Restore flag and saved character from a long line
		 */
		tp = rec_txt;
		/*
		 * Prepend the blob string and setup ccpos so it
		 * counts the arrow and space that are printed.
		 */
		if (vt100) {
			cpystr(&tp[-(sizeof blob100 - 1)], blob100);
			*tp = rec_savec;
			ccpos = -(sizeof blob100 - 1 - 2);
			tp -= (sizeof blob100 - 1);
		}
		else {
			cpystr(&tp[-(sizeof blob52 - 1)], blob52);
			*tp = rec_savec;
			ccpos = -(sizeof blob52 - 1 - 2);
			tp -= (sizeof blob52 - 1);
		}
	}
	/*
	 * tp .. EOS is what's (left) to print.  Find out how wide it is.
	 */
	ep = tp;
	while (*ep != EOS && ccpos < columnsperline) {
		if (*ep++ == '\t')
			ccpos = (ccpos + 8) & ~7;
		else	ccpos++;
	}
	if (ccpos < columnsperline) {
		rec_savec = EOS;		/* No wrap next time	*/
	}
	else {
		rec_savec = *ep;		/* Char to wrap with	*/
		*ep = EOS;			/* Terminate this piece	*/
	}
	rec_txt = ep;				/* Start for next time	*/
	return (tp);
}

char *
bigline(row)
int		row;		/* Needed for end of file processing	*/
/*
 * Read the next logical text line from infd, return buffer start
 * (in textline[]).
 * The line may be of any (reasonable) width.
 */
{
	register char	*cursor;		/* Line position	*/
	register char	*rmargin;		/* High water mark	*/
	register char	c;			/* Current character	*/
	extern char	*eofmsg();		/* Does end file hack	*/

	cursor = rmargin = textline;		/* Start of record	*/
	ff_flag = FALSE;			/* No form feeds yet	*/
	for (;;) {
		/*
		 * For each byte in the record ...
		 */
		switch (c = getbyte()) {

		case EOS:
			/*
			 * end of file from getbyte()
			 */
			if (rmargin == textline)
				return (eofmsg(row));

		case '\n':
			goto endline;

		case '\r':
			/*
			 * Carriage return -- VMS overstrike if <LF>
			 * doesn't follow.
			 */
			cursor = textline;
			continue;

		case '\f':
			ff_flag = TRUE;		/* Saveplace() needs it	*/
			if (rmargin == textline)
				*rmargin++ = '\f';
			else {
				/*
				 * Formfeed in the middle of a line,
				 * read it at the start of the next line.
				 */
				rec_bor--;
			}
			goto endline;

		case '\b':
			if (cursor > textline) {
				cursor--;
			}
			continue;

		case '\033':
			/*
			 * Stuff a visible escape into the line buffer
			 */
			if (cursor <= &textline[sizeof textline - 6]) {
				*cursor++ = '<';
				*cursor++ = 'E';
				*cursor++ = 'S';
				*cursor++ = 'C';
				*cursor++ = '>';
			}
			rmargin = cursor;
			continue;

		case '\t':
			cursor = rmargin;	/* Undo backspace	*/

		default:
			if (cursor < rmargin
			 && (c == ' ' || c == '_'
			   || (isalpha(*cursor) && !isalpha(c))))
				cursor++;
			else {				
				*cursor++ = c;
				/*
				 * Make sure textline[] doesn't fill.
				 */
				while (cursor >= &textline[sizeof textline - 2])
					cursor--;
			}
			if (rmargin < cursor)
				rmargin = cursor;
		}
	}
endline:
	/*
	 * Squish trailing blanks
	 */
	while (rmargin > textline &&
			(rmargin[-1] == ' ' || rmargin[-1] == '\t'))
		rmargin--;
	*rmargin = EOS;
	return (textline);
}

char *
eofmsg(row)
int		row;		/* True end if row == linesperscreen	*/
/*
 * End of file hackery.  Return a blank line until we're at the bottom
 * of the screen.  Then, return the eof signal message, then return NULL.
 */
{
	register int		len;		/* message length	*/
	register int		mid;		/* Line midpoint	*/

	switch (iseof) {

	case 0:				/* First time here		*/
		textline[0] = EOS;	/* Always a blank line		*/
		iseof = 1;		/* Onward			*/
		break;

	case 1:				/* Blank lines 'till bottom	*/
		if (row < linesperscreen) {
			textline[0] = ' ';
			textline[1] = EOS;
		}
		else {
			concat(temptext,
				"<** End of \"", file_name, "\" **>", NULL);
			midmsg();		/* Setup textline	*/
			iseof = 2;
		}		
		break;

	default:
		return (NULL);
	}
	return (textline);
}


midmsg()
/*
 * Centers temptext.  Output is in textline.
 */
{
	register int	len;
	register int	mid;

	len = strlen(temptext);
	mid = (vt100 && len < 39) ? 20 : 40;
	sprintf(textline, "%s%*s%s",
		(mid == 20) ? "\233#6" : "",		/* VT100 wide	*/
		mid - ((len + 1) / 2), "", temptext);	/* Tab over	*/
}
