/******************************************************************************

	WrPage()

	This function handles all TECOC's file output, except for the E%q
command.  The commands that can cause output are:

	P	write out edit buffer,  with a form feed depending on AddFF
	PW	write out edit buffer,  with a form feed
	m,nPW	write out characters between m and n,  without form feed
	HPW	write out edit buffer,  without a form feed

	This function is passed the index of the file's data block in array
OFiles,  the beginning and ending addresses in the edit buffer of the text
to be output,  and a form feed flag indicating whether a form feed is to be
appended to the output or not.
	The addresses of the text in the edit buffer might specify an area
that spans the edit buffer gap.  In order to avoid writing the edit buffer
gap to the file,  this function temporarily "shuffles" the second half of
the edit buffer,  appending it to the first half to produce a contiguous
buffer for output.  After the text is output,  the text is shuffled back.
	If a form feed is to be appended to the text,  then the character
following the last character of the text area is temporarily overwritten
with a form feed character.  After the text is output,  the character that
was overwritten is restored.
*****************************************************************************/

#include "ZPort.h"		/* define portability identifiers */
#include "DefTeco.h"		/* define general identifiers */
#include "DefChars.h"		/* define identifiers for characters */
#include "DefError.h"		/* define identifiers for error messages */

DEFAULT	WrBufr();		/* write a buffer */
VOID	ZCpyBl();		/* copy a block of memory */

EXTERN	char	*GapBeg;	/* edit buffer gap beginning */
EXTERN	char	*GapEnd;	/* edit buffer gap end */
EXTERN	BOOLEAN	IsOpnO[];


DEFAULT WrPage(OfIndx, OBfBeg, OBfEnd, AddFF)
DEFAULT	OfIndx;			/* index into OFiles array */
char *OBfBeg;			/* address of output buffer beginning */
char *OBfEnd;			/* address of output buffer end */
LONG AddFF;			/* -1L means add form feed, 0L means don't */
{
	char	SavChr;		/* saved char overwritten with form feed */
	LONG	Shuffl;		/* size of shuffled area */
	DEFAULT	status;

#if DEBUGGING
DbgInd+=2;if(DbgLvl>=2){DbgMsg();DbgDBf("WrPage: called");
DbgDBf(", OBfBeg = ");MakDBf(OBfBeg, 10);ZDspBf(DBfBeg, DBfPtr-DBfBeg);
DbgDBf(", OBfEnd = ");MakDBf(OBfEnd, 10);ZDspBf(DBfBeg, DBfPtr-DBfBeg);
DbgDBf(", AddFF = ");MakDBf(AddFF, 10);ZDspBf(DBfBeg, DBfPtr-DBfBeg);
DbgDBf("\015\012");DbgMsg();DbgDBf("WrPage: line 2:");
DbgDBf(", GapBeg = ");MakDBf(GapBeg, 10);ZDspBf(DBfBeg, DBfPtr-DBfBeg);
DbgDBf(", GapEnd = ");MakDBf(GapEnd, 10);ZDspBf(DBfBeg, DBfPtr-DBfBeg);
DbgDBf("\015\012");DbgROf();}
#endif

	if (!IsOpnO[OfIndx])			/* if no output file */
		{
		ErrMsg(ERR_NFO);		/* "no file for output" */
#if DEBUGGING
if(DbgLvl>=2)
{DbgMsg();DbgDBf("WrPage: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
		}
/*
  If the text area spans the edit buffer gap,  then "shuffle",  which
  means temporarily copying the second half of the edit buffer to the first
  half.  Later,  the reverse opertion will be done.
*/
	if ((OBfBeg < GapBeg) && (OBfEnd > GapEnd))	/* shuffle? */
		{
		Shuffl = OBfEnd - GapEnd;
		ZCpyBl(Shuffl, GapEnd+1L, GapBeg);
		OBfEnd = GapBeg + Shuffl;
		OBfEnd--;
		}
	else
		{
		Shuffl = 0L;			/* 0L indicates no shuffle */
		if (OBfBeg == GapBeg)		/* if there's no first half */
			{
			OBfBeg = GapEnd;
			OBfBeg++;
			}
		if (OBfEnd == GapEnd)		/* if there's no second half */
			{
			OBfEnd = GapBeg;
			OBfEnd--;
			}
		if (OBfBeg > OBfEnd)		/* if both halves are empty */
			{
			OBfBeg = OBfEnd;	/* make it a zero... */
			OBfBeg++;		/* ... length text area */
			}
		}
/*
  If we need to append a form feed,  then save the character being
  overwritten  and overwrite it with a form feed.
*/
	if (AddFF)
		{
		++OBfEnd;
		SavChr = *OBfEnd;
		*OBfEnd = FORMFD;
		}
/*
  Write the buffer.
*/
	if (OBfBeg <= OBfEnd)
		status = WrBufr(OfIndx, OBfBeg, OBfEnd);
/*
  If we overwrote with a form feed,  restore the overwritten character.
*/
	if (AddFF)
		*OBfEnd = SavChr;
/*
  If we previously shuffled the edit buffer,  then shuffle it back
*/
	if (Shuffl)
		ZCpyBl(Shuffl, GapBeg, GapEnd+1L);
#if DEBUGGING
if(DbgLvl>=2)
{DbgMsg();DbgDBf("WrPage: returning.\015\012");DbgROf();}DbgInd-=2;
#endif
	return(status);
}
