/*
BEGIN DOCUMENTATION

Name: TCMREFORM.C				Created: 04/13/84  DTS
					    Last Update: 05/15/84
Title: Text collection management paragraph reformat function.

Index:

Abstract: Routine that reformats paragraphs by word wraping to sides
	  of current text window.

Usage:	  outchrptr = reform(inchrptr);		* Interactive paragraph wrap *
	  rc = paraform(linptr,linnum,maxlin,width);	* Wrap paragraph in buffer only *

Parameters: charpointer outchrptr;	* Pointer to 1st char after paragraph *
	    charpointer inchrptr;	* Pointer into current line is ignored *

	    charpointer	*linptr;	* Pointer to current line pointer, changed *
	    int		*linnum;	* Current line number, increased *
	    int		maxlin;		* Last line in text buffer, decreased if wrap *
	    short int	width;		* Line length used to wrap paragraph *
	    short int	rc;		* Return code *

Environment: DECUS C, RSX11M V4.0

See Also: TCMEDIT.C, TCMSCRN.C, TCMCREATE.C, TCM.DOC

Description: Reformats current paragraph to window margins by filling text to
	     right margin and wrapping whole words to next line.  A blank line
	     marks the end of the paragraph.  The reformating starts with the
	     current line of text.

Example(s):

Uses:

Internal:

Update History:

END DOCUMENTATION
*/

#include <clang.c>
#include <stdio.h>
#include <cx.h>
#include "tcmdefs.h"
#include "tcmerr.h"
#include "tcmpublic.h"

/* External Procedures */

extern movedn();

/* #define debug 0 */

/***	PARAFORM: Reformat paragraph in text buffer    ***/

int
paraform(linptr,linnum,maxlin,txtend,width)
    charpointer *linptr;	/* In/Output - Returned pointing to 1st blank line */
    pointer	linnum;		/* In/Output - Returned incremented by number of lines advanced */
    pointer	maxlin;		/* In/Output - Returned decremented by number of lines deleted */
    charpointer	*txtend;	/* Input & Output - end of text */
    int		width;		/* Input only */
{
    register int llen;
    register charpointer otchr;	/* Output to buffer pointer, spaces compressed */
    register charpointer inchr;	/* Character input from buffer */
    register charpointer spptr;	/* Last space on line */
    boolean inpar;		/* In Paragraph flag (not end) */
    int	rc;
#ifdef debug
    int ln;
	ln = 0;
#endif

	rc = TS_SUC;
	llen = 0;
	inpar = true;
	inchr =  *linptr;
	while(*inchr++ == ' ')		/* Keep leading spaces on 1st line */
	    llen++;
	inchr--;
	for(otchr = inchr; (inpar) and (inchr < *txtend); (*linnum)++)
	{	/* Repeat until Null line in buffer */
	    spptr = NULL;
	    while((llen++ <= width) and (inchr < *txtend) and inpar)	/* In line */
	    {
		iff *inchr == eos then
		{
		    *inchr = ' ';			/* Fill from next line */
		    (*maxlin)--;
		    iff *(inchr+1) == eos then
			inpar = false;			/* Exit while loop flag */
		}
		iff (*otchr++ = *inchr++) == ' ' then	/* Assumes no enhancements */
		{
		    spptr = otchr - 1;			/* Mark last space */
		    iff (*(spptr - 1) == '.') and (*inchr == ' ') then
		        { *otchr++ = ' '; spptr++; llen++; }	/* Extra space after period kept */
		    while(*inchr == ' ')		/* Skip extra spaces between words */
			inchr++;
		}
	    }
	    iff spptr != NULL then
	    {
		(*maxlin)++;				/* Add to line count */
		*spptr = eos;				/* Change last space */
		llen = (otchr - spptr) - 1;		/* Ignores enhancements */
		*linptr = spptr + 1;			/* Start of next line */
	    }
	    else iff inchr < *txtend then
		{ rc = TS_WTL; break; }		/* Abort if no spaces on line */
	    else *inchr = eos;
	}
/*	movedn(inchr,otchr,*txtend - inchr)	* Adjust buffer, delete spaces *
	*txtend -= (int) (inchr - otchr)
*/
	while (otchr < inchr)			/* Instead of above */
	    *otchr++ = ' ';			/* Change to spaces */
	return(rc);
} /* end paraform */



/***	REFORM: Reformat paragraph & display results    ***/

charpointer
reform(chr)
    register charpointer chr;
{
    register int rc,ln;		/* retcode, Temp var */
    charpointer txtend;

	iff rdonly then
	{
	    tcmerr(TS_IKY);		/* Ignore keypress - do nothing */
	    return(chr);
	}
	while((lin[0].len <= 1) and (bufline < curwin->botline))
	    chr = csdown(chr);		/* Skip past null lines */
	iff ret.cd == TS_SUC then
	{
	    savlin(curwin);
#ifdef debug
	    ln = bufline;		/* Start of paragraph reformat */
	    scout(vtlin-1,1,curwin->edline);
#endif
	    txtend = curwin->bufstart + curwin->curmax;
	    rc = paraform(&(curwin->edline),&bufline,&(curwin->botline),&txtend,curwin->width);	/* Do formating in buffer */
	    curwin->curmax = txtend - curwin->bufstart;
	    iff rc != TS_SUC then
		{ tcmerr(rc); bufcol = curwin->width; }	/* Word too long */
	    else iff bufline >= curwin->botline then
	    {
		bufline = curwin->botline;
		curwin->edline = fndlast(curwin->edline,curwin->bufstart);
		curwin->column = bufcol = virlen(curwin->edline) + 1;
	    }
	    else curwin->column = bufcol = 1;
#ifdef debug
	    sprintf(temp,"%s' oldline = %d, newline = %d",curwin->edline,ln,bufline);
	    scout(vtlin,1,temp);
	    scout(curline,curcol,NULL);
	    lin[vtlin].fircol = tempmsg;
#endif
	    iff curwin->topline + curwin->height > bufline then	/* Current line on screen */
	    {
		for(ln = curline; ln <= bot; ln++)
		{
		    lin[ln].fircol = newlin;		/* Mark as not displayed */
		}
		lin[curline].start = NULL;		/* Refresh first always */
	    }
	    else
	    {
		curwin->topline = (bufline - curwin->height) + 1;	/* Cursor to bottom of window */
		curline = bot;
	    }
	    setout(curwin);			/* Refresh entire window */
	    chr = getlin(curwin->edline);
	    iff lin[0].len > 1 then
	    {
		savlin(curwin);			/* Strip spaces from end */
		chr = getlin(curwin->edline);
	    }
	}
	return(chr);
} /* end reform */
