/*
 *				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[] = "?(0`?(B ";		/* ? becomes escape	*/
static	char	blob52[]  = "?Fh?G ";		/* ? becomes escape	*/

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) {
		blob100[0] = blob100[4] = escape;
		strcpy(&tp[-(sizeof blob100 - 1)], blob100);
		*tp = rec_savec;
		ccpos = -(sizeof blob100 - 1 - 2);
		tp -= (sizeof blob100 - 1);
	    }
	    else {
		blob52[0] = blob52[3] = escape;
		strcpy(&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 (seeall)
		    goto normal;
		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 ((c < 0040 && c != '\t')
		 || (c > 0200 && c < 0240)) {
		    if (cursor <= &textline[sizeof textline - 3]) {
			*cursor++ = '^';
			*cursor++ = (c & 037) + '@';
		    }
		    rmargin = cursor;
		    continue;
		}
		if (cursor < rmargin
		 && (c == ' ' || c == '_'
		  || (isalpha(*cursor) && !isalpha(c))))
		    cursor++;
		else {				
normal:		    *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;

	len = strlen(temptext);
	if (vt100 && len < 39) {
	    sprintf(textline, "%c#6%*s%s", escape,
	    20 - ((len + 1) / 2), "", temptext);	/* Tab over	*/
	}
	else {
	    sprintf(textline, "%*s%s", 40 - ((len + 1) / 2), "", temptext);
	}
}
