#include <windows.h>
#include <ascii.h>
#include <fcntl.h>	/* for open() etc */
#include <sys\types.h>	/* for open() etc */
#include <sys\stat.h>	/* for open() etc */

void cdecl _spr();

/*
	Tom Jennings
	new:	21 Jun 90
	mru:	 5 Oct 92

NOTE: Compiled using PASCAL parameter passing convention.

Display output and formatting.

NOTE: All of these functions (except w_fill ...) are safe to call on
in-active windows -- this is used to advantage in worklist():NEWBATCH.C


void w_fill(w,s)
WINDOW *w;
char *s;
	Initializes a window (if necessary), then clears and writes 
	a string, as above. Mainly for simple "fill in" windows such as
	the Fkey windows.

void w_pos(w,l,c)
WINDOW *w;
short l,c;
	Set the "cursor" to specified line and column. 

void cdecl w_printf(f)
	Printf() to the specified window. Uses w_string() for output.

void w_string(w,s)
WINDOW *w;
char *s;
	Write a string into a window. Performs word wrap, handles
	CR and LF. SOH is interpreted as "space-fill" -- lines
	are assumed to be terminated with a CR or NUL and enough 
	spaces are added to make each line right-justified.

	Special formatting codes:

		'\001'	space-fill
		'\002'	blink on
		'\003'	blink off
		'\004'	reverse on
		'\005'	reverse off
		'\006'	dim on
		'\013'	dim off
		'\014'	next character literally
		'\016'	reverse vid entire window

void w_fieldtext(w,s,n)
	Displays N characters of string S in the window.

void wrap_char(w,c)
WINDOW *w;
char c;
	Output characters to the given window, wrapping words to fit. 
	ASCII control characters are processed. Any pending text is
	output when a NUL is given.

void p_windowset(w)
WINDOW *w;
	Sets the window to use for the p_ functions, below.

void cdecl p_printf(f)
void p_char(c)			in WINDOW3.C
void p_chara(c,a)		in WINDOW3.C
void p_pos(l,c)	
void p_string(s)
void p_fill(s)
void pwrap_char(c)
void p_fieldtext(s,n)
void p_scrolldn(top,bot)	in WINDOW3.C
void p_scrollup(top,bot)	in WINDOW3.C
void p_clreol()
void p_cursor()
	Same as the w_ functions, except uses the window structure
	set by p_windowset(). 

*/

static WINDOW *p_window;	/* WINDOW ptr for the p_ functions */

/* Set the window to use for the p_ functions. */

void p_windowset(w)
WINDOW *w;
{
	p_window= w;
}

/* Set writing position. */

void p_pos(l,c)
short l,c;
{
	if (!(p_window-> bits & W_ACTIVE)) return;

	p_window-> line= l;
	p_window-> col= c;
}

/* Write a character and attribute. */

void p_chara(c,a)
char c,a;
{
	w_chara(p_window,c,a);
}

/* Write a character. */

void p_char(c)
char c;
{
	w_char(p_window,c);
}

/* Initialize (if necessary), clear and display a string. */

void p_fill(s)
char *s;
{
	init_window(p_window);		/* init/clear it */
	w_string(p_window,s);		/* display string */
}

void p_cursor() {

	w_cursor(p_window);
}

void p_clreol() {

	w_clreol(p_window);
}

void p_scrollup(top,bot)
int top,bot;
{
	w_scrollup(p_window,top,bot);
}

void p_scrolldn(top,bot)
int top,bot;
{
	w_scrolldn(p_window,top,bot);
}

/* Formatted window output. */

void cdecl p_printf(f)
char *f;
{
char buff[200];

	_spr(buff,&f);
	p_string(buff);
}

/* Write a string in a window. */

void p_string(s)
char *s;
{
	w_string(p_window,s);
}

/* Write N string. */

void p_fieldtext(s,n)
char *s;
int n;
{
	w_fieldtext(p_window,s,n);
}

/* Output characters to the given window, word-wrapping as necessary. */

void pwrap_char(c)
char c;
{
	wrap_char(p_window,c);
}

/* Set writing position. */

void w_pos(w,l,c)
WINDOW *w;
short l,c;
{
	if (!(w-> bits & W_ACTIVE)) return;

	w-> line= l;
	w-> col= c;
}

/* Initialize (if necessary), clear and display a string. */

void w_fill(w,s)
WINDOW *w;
char *s;
{
	init_window(w);			/* init/clear it */
	w_string(w,s);			/* display string */
}


/* Write N characters at S to the window. */

void w_fieldtext(w,s,n)
WINDOW *w;
char *s;
int n;
{
	while (n--) w_char(w,*s++);
}

/* Formatted window output. */

void cdecl w_printf(w,f)
WINDOW *w;
char *f;
{
char buff[200];

	_spr(buff,&f);
	w_string(w,buff);
}

/* Write a string in a window. */

void w_string(w,s)
WINDOW *w;
char *s;
{
char reverse_window,c,*cp,buff[COLUMNS];
int l;

	if (!(w-> bits & W_ACTIVE)) return;

	reverse_window= 0;			/* assume normal */

	while (c= *s++) {
		switch (c) {

		case '\001':			/* space-fill */
			wrap_char(w,NUL);	/* flush what we've done (update col) */

/* Determine the nuimber of fill blanks -- count printable characters
until a CR (end of line) or NUL (end of string), then do spaces til the
line == line length. */

			for (l= 0, cp= s; *cp; ++cp) {
				if (*cp == CR) break;
				else if (*cp >= ' ') ++l;
			}
			l= w-> cols - w-> col - l - 1;
			while (l-- > 0)		/* l == chars here til CR */
				w_char(w,' ');	/* fill with spaces */
			break;

		case '\002':			/* blink on */
			wrap_char(w,NUL);	/* flush what we've done */
			w-> attribute |= A_BLINK; /* add blink bit */
			break;

		case '\003': 			/* blink off */
			wrap_char(w,NUL);	/* flush so far */
			w-> attribute &= ~A_BLINK; /* un-blink */
			break;

		case '\004':			/* reverse on */
			wrap_char(w,NUL);	/* flush so far */
			w-> attribute= w-> def_attribute ^ (A_BBG | A_WBG);
			break;

		case '\005':			/* reverse off */
			wrap_char(w,NUL);	/* flush so far */
			w-> attribute= 
			    w-> attribute & ~(A_BBG | A_WBG) |
			    w-> def_attribute & (A_BBG | A_WBG);
			break;

		case '\006':			/* dim on */
			wrap_char(w,NUL);
			w-> attribute= A_BRIGHT;
			break;

		case '\013':			/* dim off */
			wrap_char(w,NUL);
			w-> attribute= w-> def_attribute;
			break;

		case '\014':			/* literal */
			wrap_char(w,NUL);	/* flush */
			w_charal(w,*s++,w-> attribute);
			break;

		case '\016':
			reverse_window= 1;	/* just remember it */
			break;

		default:
			wrap_char(w,c);
			break;
		}
	}
	wrap_char(w,NUL);			/* flush pending */
	if (reverse_window) w_reverse(w);
}

/* Output characters to the given window, word-wrapping as necessary. 'words'
are built in a static buffer; they are output to the window when a
whitespace character is given. If outputting the word would exceed the window 
boundary, the word output on the next line. */

void wrap_char(w,c)
WINDOW *w;
char c;
{
static char word[COLUMNS];		/* buff of max. width (obviously) */
static int i = 0;			/* index into above */
static char lastc = 0;			/* for detecting soft-CRs */
register n;

	if (!(w-> bits & W_ACTIVE)) return;

	if (c == CR + 128) {		/* special-case soft-CRs */
		if (lastc == C_BLANK) return; /* ignore after a space */
		c= C_BLANK;		/* else convert to space */

	} else if (c == LF) return;	/* ignore LFs */
	if (c) lastc= c;		/* remember as last character */

	if (c > ' ') {			/* if a printable character */
		word[i++]= c;		/* save it, */
		c= NUL;			/* mark 'c' as "used" */
		if (i < sizeof(word)) return;
	}
	if (w-> col + i > w-> cols) {
		w_char(w,CR);		/* do a CR/LF */
		w_char(w,LF);
	}
	for (n= 0; n < i; n++) {
		w_char(w,word[n]);	/* output the word, if any */
	}
	i= 0;				/* word has been used */

	if (c == CR) {			/* if a CR, */
		w_char(w,CR);		/* do a CR/LF */
		w_char(w,LF);

	} else switch (c) {		/* else the character */
		case NUL: break;

		case ' ':		/* no space if about to autowrap */
			if (w-> col >= w-> cols) break;
		default:
			w_char(w,c);
			break;
	}
}
