/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:txt3812.c 12.0$ */
/* $ACIS:txt3812.c 12.0$ */
/* $Source: /ibm/acis/usr/src/ibm/lpfilter/txt3812/RCS/txt3812.c,v $ */

#ifndef lint
static char *rcsid = "$Header:txt3812.c 12.0$";
#endif

#include <stdio.h>
#include <ctype.h>
#include <utils.h>
#include <pmp/pmp.h>
#include <hash.h>
#include <environ.h>
#include "line.h"
#include "setup_txt3812.h"


/***===================================================================***/

#define UNDEFINED -1

extern FILE *popen();

	int p3_debug=		0;	/* debugging flag		*/
	int p3_bail=		FALSE;	/* drop whatever you're doing	*/

static	int p3_pg_lines=	0;	/* height of page in lines	*/
static	int p3_pg_cols=  	0;	/* width of page in characters	*/
static	int p3_pg_indent=	0;	/* indent from left in chars	*/

static	int p3_pg_width=	0;	/* height of page in pels	*/
static	int p3_pg_height=	0;	/* width  of page in pels	*/

static	int p3_left_adjust=	TRUE;	/* can we adjust margins, or	*/
static	int p3_right_adjust=	TRUE;	/* have they been explicitly	*/
static	int p3_top_adjust=	TRUE;	/* set.				*/
static	int p3_bottom_adjust=	TRUE;

static	int p3_left_offset=	0;	/* pel offset from left margin	*/
static	int p3_right_offset=	0;	/* pel offset from right margin	*/
static	int p3_top_offset=	0;	/* pel offset from top of page	*/
static	int p3_bottom_offset=	0;	/* pel offset from bottom 	*/

static int 	p3_line;		/* current line			*/

static char	*p3_font_name=	NULL;	/* name of current font		*/
static pmp_font	*p3_font=	NULL;	/* current font			*/

static int p3_lnspacing=	0;	/* interline spacing in pels	*/
static int p3_chwidth=		0;	/* character width in pels	*/

static int p3_copies=		1;	/* # of copies to be printed	*/
static int p3_pageknt=		0;	/* number of pages printed	*/

/***===================================================================***/

static int   p3_ln_wrap;		/* wrap long lines?		*/
static int   p3_two_up;			/* two logical pages/physical?	*/
static int   p3_pg_border;		/* print page borders?		*/
static int   p3_pg_rules;		/* print page rules?		*/

#define PORTRAIT  10
#define LANDSCAPE 20

static int   p3_pg_orient= PORTRAIT;	/* portrait or landscape?	*/
static int   p3_pg_rotate;		/* left/right or upright/inverted? */

/***===================================================================***/

static FILE *infil;			/* input stream			*/
static FILE *outfil;			/* output stream		*/

/***===================================================================***/

p3_Reorient()
{
register1 int tmp;

    D_ENTRY(p3_debug,"p3_Reorient()\n");
    tmp=		p3_pg_width;
    p3_pg_width=	p3_pg_height;
    p3_pg_height=	tmp;
    
    if (p3_top_adjust) 
	p3_top_offset=		(p3_top_offset*p3_pg_height)/p3_pg_width;
    if (p3_bottom_adjust) 
	p3_bottom_offset=	(p3_bottom_offset*p3_pg_height)/p3_pg_width;
    if (p3_left_adjust) 
	p3_left_offset=		(p3_left_offset*p3_pg_width)/p3_pg_height;
    if (p3_right_adjust)
	p3_right_offset=	(p3_right_offset*p3_pg_width)/p3_pg_height;
    RETURN(TRUE);
}

/***============================================================***/

static int
p3_ParseFontName(name,face,size,cpage)
register3 char	 *name;
register4 char	**face;
register5 int	 *size;
register6 char	**cpage;
{
register1 char	 *tmp;
register2 char	 *dot;

    D_ENTRY4(p3_debug,"p3_ParseFontName(%s,0x%x,0x%x,0x%x)\n",name,face,size,
								cpage);
    tmp= StrDup(name);
    *face=  tmp;
    *size=  0;
    *cpage= DFL_CPAGE;
    dot= index(tmp,'.');
    while (dot) {
	if (isdigit(dot[1])) {
	    *dot='\0';
	    sscanf(&dot[1],"%d",size);
	    dot= index(&dot[1],'.');
	    if (dot) {
		*dot= '\0';
		*cpage= &dot[1];
	    }
	    dot= NULL;
	}
	else
	    dot= index(&dot[1],'.');
    }
    RETURN(TRUE);
}

/***===================================================================***/

p3_SetupFont()
{
char off_name[60];
register1 int	 tmp;
	  int	 size;
	  char	*face;
	  char	*cpage;

   D_ENTRY(p3_debug,"p3_SetupFont()\n");
   if (p3_lnspacing==0) 
       p3_lnspacing=	(p3_pg_height-p3_top_offset-p3_bottom_offset)/
								p3_pg_lines;
   if (!p3_font_name) {
       if	(p3_lnspacing<=25) 	p3_font_name= DFL_FONT0;
       else if	(p3_lnspacing<=30) 	p3_font_name= DFL_FONT1;
       else				p3_font_name= DFL_FONT2;
   }

   p3_ParseFontName(p3_font_name,&face,&size,&cpage);

   if (p3_chwidth==0) {
       if (size==0) {
	   tmp= p3_lnspacing; 
	   if		(tmp<20)	size= 4;
	   else if	(tmp<30)	size= 5;
	   else if	(tmp<40)	size= 9;
	   else				size= 10;
       }
       tmp= size;
       if	(tmp<=4)	p3_chwidth= 9;
       else if	(tmp<=5)	p3_chwidth= 12;
       else if	(tmp<=8)	p3_chwidth= 16;
       else if	(tmp<=9)	p3_chwidth= 20;
       else if	(tmp<=10)	p3_chwidth= 24;
       else			p3_chwidth= 28;
   }
   sprintf(off_name,"%s.%d.%s",face,size,cpage);
   p3_font= p_fnt_open(off_name,P_ACIS_FONT);
   if (p3_font)
	p_fnt_activate(p3_font);
   else {
       fatal1("Can't open font %s\n",off_name);
   }
   RETURN(TRUE);
}

/***===================================================================***/

static
p3_CenterOffsets()
{
register1 int	offset;
register2 int	margin_space;

    D_ENTRY(p3_debug,"p3_CenterOffsets()\n");
    margin_space=	p3_pg_height-(p3_pg_lines*p3_lnspacing);
    if (p3_top_adjust&&p3_bottom_adjust) {
	p3_bottom_offset= p3_top_offset= 	margin_space/2;
	offset= 				p3_lnspacing/2;
	if (p3_top_offset > offset) {
	    p3_bottom_offset+=	offset;
	    p3_top_offset-=	offset;
	}
	else 
	{
	    warning3("page too long (%d lines x %d line space > %d)\n",
		      p3_pg_lines, p3_lnspacing, p3_pg_height);
	    action("setting top offset to 0\n");
	    p3_top_offset= 0;
	}
    }
    else if (p3_top_adjust) 
	p3_top_offset=		margin_space-p3_bottom_offset;
    else if (p3_bottom_adjust) 
	p3_bottom_offset=	margin_space-p3_top_offset;

    margin_space= p3_pg_width-(p3_pg_cols*p3_chwidth);
    if (p3_left_adjust&&p3_right_adjust) {
	p3_left_offset=p3_right_offset=		margin_space/2;
	offset=					p3_chwidth/2;
	if (p3_left_offset > offset) {
	    p3_right_offset+=	offset;
	    p3_left_offset-=	offset;
	}
	else
	{
	    warning3("page too wide (%d cols x %d col width > %d)\n",
		      p3_pg_cols, p3_chwidth, p3_pg_width);
	    action("setting left offset to 0\n");
	    p3_left_offset= 0;
	}
    }
    else if (p3_left_adjust) 
	p3_left_offset=		margin_space-p3_right_offset;
    else if (p3_right_adjust) 
	p3_right_offset=	margin_space-p3_left_offset;
    RETURN(TRUE);
}

/***===================================================================***/

static env_enum
            orient[]= {
		{"portrait",		P_PORTRAIT},
		{"right_landscape",	P_RIGHT_LANDSCAPE},
		{"left_landscape",	P_LEFT_LANDSCAPE},
		{"inverted",		P_INVERTED},
		{NULL, 0}
	    },
	    up[]= {
		{"two_up", 	TRUE}, 	{"one_up", 	FALSE},	{NULL, 0}
	    },
	    wrap[]= {
		{"wrap_line",	TRUE},	{"trunc_line",	FALSE},	{NULL, 0}
	    },
	    tray[]= {
		{"main_tray",	P_MAIN_TRAY},
		{"alt_tray",	P_ALTERNATE_TRAY},
		{NULL, 0}
	    };

static
p3_Setup(env)
register1 environ *env;
{

    D_ENTRY1(p3_debug,"p3_Setup()\n",env);
    p3_pg_cols=		env_Int(env,	"text_columns",	DFL_COLS);
    p3_pg_lines=	env_Int(env,	"text_lines",	DFL_LINES);
    p3_pg_indent=	env_Int(env,	"text_indent",	DFL_INDENT);
    p3_pg_rules=	env_Int(env,	"page_rules",	DFL_RULES);
    p3_pg_border=	env_Int(env,	"page_border",	DFL_BORDER);
    p3_pg_height=	env_Int(env,	"pel_height",	DFL_HEIGHT);
    p3_pg_width=	env_Int(env,	"pel_width",	DFL_WIDTH);

    p3_left_offset=	env_Int(env,	"left_offset",	DFL_LFT_OFFSET);
    p3_right_offset=	env_Int(env,	"right_offset",	DFL_RT_OFFSET);
    p3_top_offset=	env_Int(env,	"top_offset",	DFL_TOP_OFFSET);
    p3_bottom_offset=	env_Int(env,	"bottom_offset",DFL_BTM_OFFSET);

    p3_left_adjust=	env_IsDefault(env,	"left_offset");
    p3_right_adjust=	env_IsDefault(env,	"right_offset");
    p3_top_adjust=	env_IsDefault(env,	"top_offset");
    p3_bottom_adjust=	env_IsDefault(env,	"bottom_offset");

    p3_lnspacing=	env_Int(env,	"line_spacing",	0);
    p3_chwidth=		env_Int(env,	"char_width",	0);
    p3_copies=		env_Int(env,	"copies",	1);

    p3_font_name=	env_String(env,	"text_font",	(char *)NULL);

    p3_pg_rotate=	env_SetVal(env,	orient,	DFL_ORIENT);
    p3_two_up=		env_SetVal(env,	up,	DFL_TWOUP);
    p3_ln_wrap=		env_SetVal(env,	wrap,	DFL_WRAP);
    (void) env_SetVal(env,	tray,	DFL_TRAY);

    if ((p3_pg_rotate==P_RIGHT_LANDSCAPE)||(p3_pg_rotate==P_LEFT_LANDSCAPE))
		p3_pg_orient= LANDSCAPE;
    else 	p3_pg_orient= PORTRAIT;
    RETURN(TRUE);
}

/***===================================================================***/

p3_TwoUpInit()
{

    D_ENTRY(p3_debug,"p3_TwoUpInit()\n");
    if (p3_pg_orient==LANDSCAPE) {
        p3_pg_height/=2;
	if (p3_top_adjust)
	   p3_top_offset/=	2;
	if (p3_bottom_adjust)
	   p3_bottom_offset/=	2;
    }
    else {
	p3_Reorient();
	p3_pg_width/=2;
	if (p3_left_adjust) 
	    p3_left_offset/=	2;
	if (p3_right_adjust)
	    p3_right_offset/=	2;
	if (p3_pg_rotate==P_PORTRAIT)
	    p_rotate(P_RIGHT_LANDSCAPE);
	else
	    p_rotate(P_LEFT_LANDSCAPE);
    }
    RETURN(TRUE);
}

/***===================================================================***/

p3_Init(env)
register1 environ	*env;
{
#ifdef DEBUG_UTILS
register2 char		*pmp_debug;
#endif /* DEBUG_UTILS */

    D_ENTRY(p3_debug,"p3_Init()\n");
    p3_Setup(env);
#ifdef DEBUG_UTILS
    pmp_debug= env_String(env,"pmp_debug",NULL);
    if (pmp_debug) 
	p_set_debug(pmp_debug);
#endif /* DEBUG_UTILS */
    p_open(outfil);
    p_add_dir(FONT_DIR);
    p_set_copies(p3_copies);
    if (p3_two_up) {
	p3_TwoUpInit();
    }
    else if (p3_pg_orient==LANDSCAPE) {
	p3_Reorient();
	p_rotate(p3_pg_rotate);
    }
    p3_SetupFont();
    p3_CenterOffsets();
    RETURN(TRUE);
}

/***===================================================================***/

p3_SetupPage(pagenum)
register1 int	pagenum;
{
    D_ENTRY1(p3_debug,"p3_SetupPage(%d)\n",pagenum);
    p3_line=	1;
    p_mv_absolute(p3_left_offset + (p3_chwidth*p3_pg_indent), 
		  p3_top_offset  +  p3_lnspacing);
    p_set_display(pagenum);
    RETURN(TRUE);
}

/***===================================================================***/

/* ARGSUSED */
p3_PrintPage(pagenum)
register3 int pagenum;
{
register1 int ch;
register2 int done= FALSE;
static line *ln= NULL;

    D_ENTRY1(p3_debug,"p3_PrintPage(%d)\n",pagenum);
    if (!ln)
       ln= ln_New(p3_pg_cols-p3_pg_indent);
    while (!done) {
	ch=		ln_Scan(infil,ln);
	(void) ln_Print(ln);
	switch (ch) {
	    when '\f':
	    or   EOF:	done= TRUE;
	    otherwise:	if ((ch!='\n')&&(!p3_ln_wrap)) {
			   while (((ch=getc(infil))!='\n')&&(ch!=EOF))
			      /* do nothing -- conditional does work */;
	                }
	    		p3_line++;
			p_mv_v_relative(p3_lnspacing);
			p_mv_h_absolute(p3_left_offset+p3_chwidth*p3_pg_indent);
	}
	if ((p3_line>p3_pg_lines)||p3_bail)
	    done= TRUE;
    }
    if (p3_bail) {
	if (p3_line >= p3_pg_lines) /* no room to print cancel message */
		RETURN(TRUE);
	/* else, skip a line and print a message indicating 
	 * that the printing of this document was cancelled 
	 */
	p_mv_v_relative(p3_lnspacing);
	p_mv_h_absolute(p3_left_offset+p3_chwidth*p3_pg_indent);
	p_putstring("** Document cancelled **");
	RETURN(TRUE);
    }
    RETURN(ch==EOF);
}

/***===================================================================***/

p3_TwoUpEject(pagenum)
register1 int	pagenum;
{
register2 int	odd= (pagenum%2);

    D_ENTRY1(p3_debug,"p3_TwoUpEject(%d)\n",pagenum);
    if (p3_pg_orient==PORTRAIT) {
	if (odd) {
	    p3_left_offset+=	p3_pg_width;
	    p3_pg_width*=	2;
	}
	else {
	    p3_pg_width/=	2;
	    p3_left_offset-=	p3_pg_width;
	}
    }
    else if (p3_pg_orient==LANDSCAPE) {
	if (odd) {
	    p3_top_offset+=	p3_pg_height;
	    p3_pg_height*=	2;
	}
	else {
	    p3_pg_height/=	2;
	    p3_top_offset-=	p3_pg_height;
	}
    }
    if (!odd||p3_bail) {
	p_eject(TRUE);
	RETURN(TRUE);
    }
    RETURN(FALSE);
}

/***===================================================================***/

p3_EjectPage(pagenum,done)
register1 int	pagenum;
register3 int	done;
{
register2 int	page_out;

   D_ENTRY2(p3_debug,"p3_EjectPage(%d,%d)\n",pagenum,done);
   if ((!done)||(p_marked())) {
	if (p3_pg_border) {
	    p_vec_nofill();
	    p_vec_set_width(p3_pg_border);
	    p_mv_absolute(p3_left_offset,p3_top_offset);
	    p_vec_h_relative(p3_pg_width-p3_left_offset-p3_right_offset);
	    p_vec_v_relative(p3_pg_lines*p3_lnspacing);
	    p_vec_h_relative((p3_left_offset+p3_right_offset)-p3_pg_width);
	    p_vec_v_relative(-p3_pg_lines*p3_lnspacing);
	}
	if (p3_pg_rules) {
	    register3	int knt;
	    register4	int width= p3_pg_width-p3_left_offset-p3_right_offset;

	    p_vec_nofill();
	    p_vec_set_width(1);
	    p_mv_absolute(p3_left_offset,p3_top_offset);
	    for (knt=0;knt<p3_pg_lines;knt+=p3_pg_rules) {
		p_vec_h_relative(width);
		p_mv_v_relative(p3_pg_rules*p3_lnspacing);
		width= -width;
	    }
	}
   }

   if (done) {
	if (p_marked()||p3_bail) {
	    p_eject(TRUE);
	    page_out= TRUE;
	}
	p_close();
   }
   else {
       if (p3_two_up) 
	   page_out=	p3_TwoUpEject(pagenum);
       else {
	   p_eject(TRUE);
	   page_out=	TRUE;
       }
   }
   if ((!done)&&page_out) {
       p3_pageknt+=	p3_copies;
   }
   RETURN(TRUE);
}

/***===================================================================***/

p3_Print()
{
register1 int	pagenum=1;
register2 int	done= FALSE;

   D_ENTRY(p3_debug,"p3_Print()\n");
   while (!done) {
       p3_SetupPage(pagenum);
       done= p3_PrintPage(pagenum);
       p3_EjectPage(pagenum++,done);
   }
   RETURN(TRUE);
}

/***===================================================================***/

p3812(env,in,out)
register1 environ *env;
register2 FILE    *in;
register3 FILE    *out;
{

    D_ENTRY3(p3_debug,"p3812(0x%x,0x%x,0x%x)\n",env,in,out);
    infil=	in;
    outfil=	out;
    p3_Init(env);
    p3_Print();
    RETURN(p3_pageknt);
}
