/* Print V1.5a
	(C) HooverSoft 1990
	Let's see if we can somehow tell the printer what we
	really want...
*/

/* Includes that we need...*/

#include <stdio.h>
#include <time.h>
#include <exec/types.h>




#define  ESC			0x1B	/* escape sequence introducer */
#define  NUL			0x00	/* Null character */
#define  CEND			0xff  /* End of control sequence */
#define  FS				0x1c  /* Another weird control char */

#define LINE6HEIGHT	4L   /* "Height" of line in mm  */
#define LINE8HEIGHT  3L
#define SILENT		1L
#define NOISY		0L
#define  USA 		0L
#define  GERMAN	2L
#define  PLAIN		1L

#define PRINTERNAME (UBYTE *) "PAR:"

#define FILE_NOT_FOUND 1L
#define  MAXFILES 20L
#define  MAXCOMMANDS 15L

#define ULLAFANFOLD 12L

static char *cnames[MAXCOMMANDS] =
{
	"set8lpi",
	"underline",
	"quiet",
	"tencpi",
	"twelvecpi",
	"fiftcpi",
	"lperpage",
	"setquality",
	"setdraft",
	"neglinefeed",
	"loud",
	"resetprinter",
	"changecharusa",
	"changecharother",
	"set6lpi"
};

/* Define Offsets for command table */
#define SET8LPI			0L
#define UNDERLINE   1L
#define QUIET				2L
#define TENCPI				3L
#define TWELVECPI			4L
#define FIFTCPI			5L
#define LPERPAGE   		6L
#define SETQUALITY 		7L
#define SETDRAFT 			8L
#define NEGLINEFEED  	9L
#define LOUDNESS			10L
#define RESETPRINTER		11L
#define CHANGECHARUSA	12L
#define CHANGECHAROTHER 13L
#define SET6LPI			14L

#define NOARG 0xff

struct FILE  *infile, *printer, *cfile;


static UBYTE	ctable[MAXCOMMANDS][5] =
{
	ESC, '0',  CEND, NULL, NULL, /* set 8lpi mode */		
  	ESC, '-', CEND, NULL, NULL, /* set underine */		
	ESC, 's', SILENT,CEND, NULL, /* quiet print mode */
	ESC, 'P', CEND, NULL,NULL,	  /* 10 CPI */
	ESC, 'M', CEND, NULL, NULL,  /* 12 CPI */
	ESC, 'g', CEND, NULL, NULL,  /* 15 CPI */
	ESC, 'C',  CEND, NULL,NULL,  /* lines per page */
	ESC, 'x', CEND,NULL, NULL,	  /* near letter printing quality */
	ESC, 'x', NULL, CEND, NULL,  /* Print mode high speed draft */	
	FS, 'R', CEND, NULL, NULL,   /* Negative form feed at end of printing */						 
	ESC, 's', NOISY, CEND, NULL,  /* quiet print mode */
	ESC, '@', CEND, NULL, NULL,  /* Full printer reset */	
	ESC, 'R',  NULL, CEND, NULL, /* change national char set to USA */
	ESC, 'R', CEND, NULL, NULL,    /* change nation char set to n */
	ESC, '2', CEND, NULL, NULL   /* set 6lpi mode */
};

long i, indent = 8,  tabsize = 3, plength = 72, charset = 2;
char	files[MAXFILES][80L]; 	/* Field to hold filenames */
long howmany = 0; 			/* No. of Files to spool */
long  verbose = 0;		   /* verbose option */ 
long offset = 0;

long BIGFONT, SMALLFONT, MEDFONT, FILENAMES, PAGENUMBERING;
long LQ = 1L, LOUD=1L;
long NOTUSA = 0L; 
long FROM_WB = 0L;
long HAVE_PRINTED_ONE = 0L, RESET = 1L, JAMMED_LINES = 0L;
long OFFSET = 0L; 			/* Offset at printing of first file */
long DONT_TRANSFORM = 0L;	/* char transformation */
long pageno = 1L; /* number of current page being printed */


/*
	scan_file()
	This is an attempt to write a parsing function that is able to
	read commands into the UBYTE[][] array.
	HooverSoft 1990
	written Nov 5 1990 by hoover
*/

long scan_file(filename)
UBYTE *filename;
{

	long val0, val1, val2, val3, val4;

	register long i;

	char cword[20];					/* place to keep lines of the file */	


	cfile = (struct FILE *) fopen((UBYTE *) filename, "r");
	if(!cfile)
		{
		SimpleRequest("OI, could not open command file!");
		return(FILE_NOT_FOUND);
		}

	while( (fscanf(cfile,"%x %x %x %x %x %s", \
				&val0,&val1,&val2,&val3,&val4,&cword) ) != EOF)
		{


	for(i=0; i<MAXCOMMANDS; i++)
			{
			if(strcmp(cword,cnames[i]) != 0)
 				continue;

			else
				{
				ctable[i][0] = (UBYTE) val0;
				ctable[i][1] = (UBYTE) val1;
				ctable[i][2] = (UBYTE) val2;
				ctable[i][3] = (UBYTE) val3;
				ctable[i][4] = (UBYTE) val4;
				break;
				}
			}			
		}
	fclose(cfile);
	return(0);
	}

void PutCommand(which, what)
long which;
long what;

{
	long i = 0;
	while( ctable[which][i] != CEND) /* Check for end of command */
		{
		fputc(ctable[which][i], printer); /* write sequence to file */
		i++;										/* and increment counter */
		}
/* Now put the parameter into output file */
	if(what != NOARG)
		fputc(what, printer);
	return;
}


void init_printer()
{
/* Let's init the printer anyway */

	printer = (struct FILE *)fopen(PRINTERNAME, "w");
	if(!printer)
		close_all("Could not open par:",1L);		

	PutCommand( RESETPRINTER, NOARG);

	if( plength == 72L || FROM_WB) /* plength not set or from wb */ 
		{
		if(JAMMED_LINES)
			{
			plength = ULLAFANFOLD * 8L;
			PutCommand(SET8LPI, NOARG);
			}

			if(!JAMMED_LINES)
			{
			plength = ULLAFANFOLD * 6L;
			PutCommand( SET6LPI, NOARG);
			}
		}


		if(BIGFONT)
			PutCommand(printer , TENCPI  , NOARG);

		if(SMALLFONT)
			PutCommand( FIFTCPI, NOARG);

		if(MEDFONT)
			PutCommand( TWELVECPI, NOARG);


		if(!MEDFONT && !SMALLFONT && !BIGFONT )
			PutCommand( TWELVECPI, NOARG);

		if(LQ)
			PutCommand( SETQUALITY, 1);
		else
			PutCommand( SETDRAFT, NOARG);	

		if(!LOUD)
			PutCommand( QUIET, NOARG);
		else
			PutCommand( LOUDNESS, NOARG);

		if(NOTUSA)		/* USA not the the default char set? */
			PutCommand( CHANGECHARUSA, 0);

	return;
	}

void clean_printer()
{

/* Let's clean up a bit */
	PutCommand( NEGLINEFEED, 0L);
	fputc('\n',printer); 
	
	if(NOTUSA)	/* did we change the national char set? */
		PutCommand( CHANGECHAROTHER, charset);

	if(RESET)
		PutCommand( RESETPRINTER, NOARG);

	return;
	}

/* makefootline coded oct 19th, 1990 by hoover
	print out current pagenumber at bottom of page
*/
	
void makefootline()
{

	
	fputc('\n', printer); /* skip one line */
	fprintf(printer, "                                   -- %ld --\n", pageno);
	pageno++;
	return;
}

/* endpage coded on Oct 19th, 1990 by hoover
	used to set up end of page according to
	user specs
*/

void endpage()
{
	long i;

	if(PAGENUMBERING) 
		{
		makefootline();

/* makefootline prints two cr's, so we're at line 70 when finished.
	print four more two get to the bottom of the page, then two
	more to leave a bit of space at top of page...
	Remember to set pageno to 2 on return!
*/
		fprintf(printer,"\n\n\n\n");
		return;
		}
	else
		{
/*	if we want no pagenumbering, we're at line 68 when this is
	called. All we've got to do is to print out 6 cr's to get
	to the next page...
*/
		fprintf(printer,"\n\n\n\n\n\n");
		return;
		}
	}

/* coded 2 Nov 1990
	indents line  by indent amount for printing
	written by hoover
*/
void indent_line(indent)
long indent;	/* number of spaces to indent */
{
	long count;

	for(count=0; count <indent; count++)
		fputc(' ', printer);		

	return;
}

/* stolen from HooverSoft's Tarif program...
	Let's hope that it works as advertised!
	coded god knows when by hoover
*/

UBYTE *get_time()
{
   long  mytime = 0L ;
   long  *store; 

   mytime = time(store);
	return  ( (UBYTE *)ctime(store) );

}

extern void inprint();

void print_file(name)
UBYTE *name;
{
	register long c; 
	long count, lineno;

	lineno = (HAVE_PRINTED_ONE) ? 2 : 1;


	if(!HAVE_PRINTED_ONE && OFFSET) /* first file and offset specified */
		{
		if(JAMMED_LINES)
			lineno = (ULONG) (offset / LINE8HEIGHT) ;
		else
			lineno = (ULONG) (offset / LINE6HEIGHT);

		}			

	infile = (struct FILE *)fopen(name, "r");
	if(!infile)
		{
		SimpleRequest("Can't open print file!");
		goto bye;
		}
		HAVE_PRINTED_ONE = 1;
/* We've printed a file, so let's tell the program so it will
	will be able to figure out on which lineno it is.
*/


/* Indent first line printed */

	indent_line(indent);

	if(FILENAMES)
		{
		lineno++;
		PutCommand( UNDERLINE, 1L);
		fprintf(printer, "Filename: %s  printed on %s\n",\
		name, get_time());
		PutCommand( UNDERLINE, 0L);
		indent_line(indent);
		}



	while( ( c = fgetc(infile) ) != EOF)
		{
		if(verbose)
			putchar(c);

		if(c == '\n')
			{
			fputc(c, printer);
			lineno++;
			if(lineno ==  plength-4 )
				{
				endpage();
				lineno =   2; /* endpage will get to line #2 of new page */
				}

			indent_line(indent);
			continue;
			}
/* convert tabs */

		if(c == '\t')
			{
			for(count = 0; count < tabsize; count++)
				fputc(' ',printer);
			continue; 
			}

		if(!DONT_TRANSFORM)
			switch(c)
				{
				case 0xe4:	c=0x84; /* an ae */
							break;
				case 0xf6:	c=0x94; /* an oe */
							break;
				case 0xfc:  c=0x81; /* an ue */
							break;
				case 0xdf:	c=0xe1; /* an sz */
							break;
				case 0xc4:  c=0x8e;  /* an Ae */
							break;
				case 0xd6:	c=0x99; /* an Oe */
							break;
				case 0xdc:	c=0x9a; /* an Ue */
							break;
            case 0xbd:  c=0xab; /* 1/2 */
  	                     break;
				case 0xa9:	c=0xe9;	/* sorry, no (C) in IBM font */
												/* currently mapped to \Theta */
								break;

				case 0xb2:	c=0xfd;	/* superscript 2 */
								break;


				case 0xa2:  c=0x9b;   /* cent */
								break;
				case 0xc5:	c=0x8f;   /* A(degree) */
									break;
	
				case 0xb0:	c=0xf8;   /* degree */
								break;

				case 0xc:	c=' '; /* Kill form feeds */
									break;
				}	/* end switch */
			fputc(c, printer);
		}	/* end while */ 		
/* Printing of file finished */
#ifdef DEBUG1.5
		printf("Closing input file.\n");
#endif
		fclose(infile);

/* Now we've got to 'emit' cr's till we're at the bottom of the
	page. After endpage has been called, we'll be at line two of
	the new page.
*/

		for( ; lineno < plength-4; lineno++)
			fputc('\n', printer);

		endpage();
		pageno = 1;						/* Reset current page counter */
bye:
	fclose(printer);

	return;
	}/* end print_file */

void main(argc, argv)
long argc;
char *argv[];

{
	
	BIGFONT =  SMALLFONT  = FILENAMES = PAGENUMBERING = 0;
	MEDFONT = 1L;
	
	open_all();


	if(argc == 1 || argc <= 0)  /* test for workbench launch */
		{
		FROM_WB = 1L;
		inprint(); 					 /* if so, call IntuiInterface */
		}

	printf("         ******************************************************\n");
	printf("                    Print V1.5A (c) HooverSoft 1990\n");
	printf("                     \033[33mfor the NEC PinWriter Series \033[0m\n");
	printf("         Freely distributable for non-commercial purposes only.\n");
	printf("                       type 'print h' for help.\n");
	printf("         ******************************************************\n");

/* test to see if user needs our help */

	if(argc == 2 && *argv[1] == 'h')
		help();

	for(i=1; i< argc; i++)
		{


		if( (char) argv[i][0] == '-')	     /* is it option qualifier? */
			switch( argv[i][1]  ) 		/* then scan character after it */
				{
				long error = 0L;

				case 't':	tabsize = atoi(argv[i+1]);
								tabsize = (tabsize < 1 || tabsize > 16) ? 3 : tabsize;
								i++;
								break;

				case 'u':	NOTUSA = 1;
								charset = atoi(argv[i+1]);
								charset = (charset < 0 || charset > 14) ? 2 : charset;
								i++;
								break;

				case 'i':	indent  = atoi(argv[i+1]);
								indent  = (indent < 1 || indent > 30) ? 8 : indent; 
								i++;
								break;

				case 'l':	plength = atoi(argv[i+1]);
								plength = (plength < 1 || plength > 100)  ? 72 : plength; 
								i++;
 								break;

				case 'f':   error = scan_file( (UBYTE *) argv[i+1]);
								if(error == FILE_NOT_FOUND)
									close_all("",0);
								if(error)
									close_all("Error in Command File!",1L);
								i++;
								break;

				case 'o':	offset = atoi(argv[i+1]);
								OFFSET = 1L;
								offset = (offset < 1 || offset > 300)  ? 60L : offset; 
								i++;
								break;

				case 'V':	verbose = 1L;
								break;

				case 'B':	BIGFONT = 1L;
								break;
	
				case 'M':	MEDFONT = 1L;
								break;

				case 'P':	PAGENUMBERING = 1L;
								break;

				case 'S':	SMALLFONT = 1L;
								break;

				case 'T':	DONT_TRANSFORM = 1L;
								break;

				case 'F':   FILENAMES = 1L;
								break;

				case 'Q':	LQ = 1;
								break;
	
				case 'R':	RESET = 0;
								break;

				case 'D':	LQ = 0;
								break;

				case 'N':	LOUD = 0L;
								break;

				case '8':	JAMMED_LINES = 1L;
								break;

				case default :	printf("Unknown option -%c\n", argv[i][1]);
									i++;
									break; 
  
				} 	/* end switch */
		else									/* no qualifier? Then regard as file */
			{
			strcpy(files[howmany], (UBYTE *) argv[i]);
			howmany++;
			}
		}			/* end for */


	if(howmany > MAXFILES)
		close_all("Too many files!",1L);


	init_printer();

	for(i = 0; i < howmany; i++)
		print_file(files[i]);

	clean_printer();			/* end for () */

	close_all("",0L);
	}				/* end main() */
