/* FormatPrint 2.1 -- B Zupke, Amazing Amiga, mai 1990, p. 84 /M. Laliberté 
		cc print.c
		ln print -lc
*/

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

#define Esc			""
#define LPP_DEF		66
#define TAB_DEF		3
#define COL_DEF		79
#define NBR_DEF		FALSE
#define OUT_DEF		"PRT:"
#define LST_DEF		FALSE
#define HEADER		5
#define TRAILER		3
#define COL_MAX		256
#define COL_MIN		10
#define LPP_MIN		5
#define MAXCHAR		500
#define MAXFILE		255
#define TAB_MAX		20
#define TAB_MIN		2
#define	SPACE		0x20
#define TAB			0x09
#define L_ARW_TEXT	"->"
#define L_ARW_SIZE	2
#define R_ARW_TEXT	"<-\n"
#define R_ARW_SIZE	2
#define LINEFORMAT	"%4.4d "
#define LINESPACE	5
#define NOTMFORMAT 	"                    page  %3.3d\n"
#define TIMEFORMAT	"%2.2d %4.5s19%2.2d  page %-3.3d\n"
#define TIMESIZE	29


int		StartPage = 1;
int		EndPage   = 9999;
int		Columns;
int		CurrentPage;
int		LinesPerPage;
BOOL	ShowNumber = FALSE;
BOOL    Head       = FALSE;
BOOL    NoHead     = FALSE;
BOOL    BeHead     = FALSE;
BOOL	Init       = FALSE;
BOOL    SkipPage   = FALSE;
int		TABSize;
char	ansistr[63] ;
char	tempstr[63] ;
char	tem2str[63] ;
FILE 		*printer;
int 		PrintLines;

main(argc, argv)

int argc;
char *argv[];
{
	char 		*fgets();
	char 		FileName[MAXFILE];	
	FILE 		*fopen();
	char 		*lineptr;
	BOOL 		ListFile;
	char 		NewLine[MAXCHAR];
	int 		NextArg;
	char 		Output[MAXFILE];
	char 		SourceLine[MAXCHAR];
	char 		*strcpy();
	char 		*Text;

	
	LinesPerPage =	LPP_DEF;
	TABSize		=	TAB_DEF;
	Columns 	=	COL_DEF;
	ShowNumber 	=	NBR_DEF;
	lineptr 	=	strcpy(Output, OUT_DEF);
	ListFile 	=	LST_DEF;
	CurrentPage =	0;

	if (argc<2 || argv[1][0] == '?')
	{
		printf("\f\n[1mFormatPrint v2.1 - B. Zupke / M. Laliberté, May 1990[0m\n\n");
		printf("[33mUSAGE:[31m %s <-option...> file <file...>\n\n", argv[0]);
		printf("[33mOptions:                                    Defaults:[31m\n");
		printf("   -cxxx  : Set number of columns.            (%d)\n",Columns);
		printf("   -lxxx  : Set lines per page.               (%d)\n",LinesPerPage);
		printf("   -txx   : Convert TABs to xx spaces.        (%d)\n",TABSize);
		printf("   -sxxx  : Set start page.                   (%d)\n",StartPage);
		printf("   -exxx  : Set end page.                     (%d)\n",EndPage);
		printf("   -n     : Show line numbers.                (%s)\n","no");
		printf("   -h0    : Skip headers, paging and final LF.(%s)\n","no");
		printf("   -dcom  : Execute DOS command 'com'.        (%s)\n","no");
		printf("   -oout  : Send output to 'out'.             (%s)\n",Output);
		printf("   -ifile : Use 'file' for input.             (%s)\n","none");
		printf("   -astr  : Send ANSI string 'str' to printer.(%s)\n","none");
		printf("      (f)ormfd (s)uperscr (r)eset  (v)ert. spac. (e)lite (b)old\n");
		printf("      (l)inefd enlar(g)ed (m)argin (d)ouble str. (c)ond. (n)lq\n\n"); 
	}
	else
	{
		for (NextArg=1; NextArg <argc; NextArg++)
		{
			if (*argv[NextArg] == '-')		
			{
				ProcessOptions(argv[NextArg],Output,&ListFile);
			}
			else
			{
				printer = fopen(Output,"a");
				if (printer == 0)
				{
					printf("Can't open %s for output!\n",Output);
				}
				else
				{
					PrintLines = LinesPerPage - (HEADER+TRAILER);
					PrintFile(printer,argv[NextArg],PrintLines);
				}
				fclose(printer);
			} 
		}  /* end-for */
	} 
}

/*     Process Options     */

ProcessOptions(Option, Output, ListFile)

char Option[];
char Output[];
BOOL *ListFile;
{	
	int			succes = 0;
	short		t = 0;
	BOOL 		skip = TRUE;
	char		initstr[63];
	char		*lineptr;
	char		*strcpy();
	char		FileName[MAXFILE];
	FILE 		*list;
	long 		_stack = 2000, _priority = 0, _BackGroundIO = 1;
	char 		*_procname = "InitProcess";       /* detach() stuff */
	
	switch(Option[1])
	{
	case 'l':
		LinesPerPage = atoi(&Option[2]);
		if(LinesPerPage < LPP_MIN)
		{
			LinesPerPage = LPP_DEF;
			printf(" Invalid lines per page. Changed to %d.\n", LinesPerPage);
		}
		break;
	case 'd':
		Init = TRUE;
		strcpy(initstr,&Option[2]);
		succes = Execute(initstr,0,0);
		if (succes == 0)
			printf("I/O error %ld\n with %s\n", IoErr(), initstr);
		break;
	case 'a':
		strcpy(ansistr,"\0\0\0\0\0\0\0\0");
		if (Option[2] != '') 
		{
			do
			{	
				switch(Option[2+t])	
				{
					case 'r':
						strcpy(tempstr,Esc"c");
						strcat(ansistr,tempstr);
						break;
					case 'l':
						strcpy(tempstr,"\n");
						strcat(ansistr,tempstr);
						break;
					case 'f':
						strcpy(tempstr,"\f");
						strcat(ansistr,tempstr);
						break;
					case 'e':
						strcpy(tempstr,Esc"[2w");
						strcat(ansistr,tempstr);
						break;
					case 'c':
						strcpy(tempstr,Esc"[4w");
						strcat(ansistr,tempstr);
						break;
					case 'b':
						strcpy(tempstr,Esc"[1m");
						strcat(ansistr,tempstr);
						break;
					case 'n':
						strcpy(tempstr,Esc"[2\"z");
						strcat(ansistr,tempstr);
						break;
					case 'd':
						strcpy(tempstr,Esc"[4\"z");
						strcat(ansistr,tempstr);
						break;
					case 'g':
						strcpy(tempstr,Esc"[6w");
						strcat(ansistr,tempstr);
						break;
					case 's':
						strcpy(tempstr,Esc"[2v");
						strcat(ansistr,tempstr);
					case 'v':
						strcpy(tempstr,Esc"[0z");
						strcat(ansistr,tempstr);
						break;
					case 'm':
						if (Option[3+t]=='0')
						{
							strcpy(tempstr,Esc"[0s");
							++t;
						}
						else if (Option[3+t]=='5')
						{
							strcpy(tempstr,Esc"[5s");
							++t;
						}
						else
						{
							strcpy(tempstr,Esc"[10s");
						}
						strcat(ansistr,tempstr);
						break;
					default:
						if(Option[2+t]>'0' && Option[2+t] <'z')
							printf("Invalid option %c\n",Option[2+t]);
				}
				++t;
			}while(Option[2+t] != '\0');
		}
		else
		{
			strcpy(ansistr,&Option[2]); 
		}
		printer = fopen(Output,"a");
			if (printer == 0)
			{
				printf("Can't open %s for output!\n",Output);
			}
			else
			{
				fprintf( printer,ansistr);
			}
		fclose(printer);
		break;
	case 't':
		TABSize = atoi(&Option[2]);
		if (TABSize < TAB_MIN || TABSize > TAB_MAX)
		{
			TABSize = TAB_DEF;
			printf("Invalid TAB size. Changed to %d.\n",TABSize);
		}
		break;
	case'c':
		Columns = atoi(&Option[2]);
		if (Columns < COL_MIN || Columns > COL_MAX)
		{
			Columns = COL_DEF;
			printf("Invalid column size. Changed to %d\n", Columns);
		}
		break;
	case'n':
		ShowNumber = TRUE;
		break;
	case's':
		SkipPage = TRUE;
		StartPage = atoi(&Option[2]);
		break;
	case'e':
		EndPage = atoi(&Option[2]);
		break;
	case 'h':
		if (Option[2]=='0')
		{
			Head = TRUE;
			BeHead = TRUE;
		}
		else if (Option[2]=='1')
		{
			NoHead = TRUE;
		}
		break;
	case'o':
		if (strlen(Option) >2)
		{
			lineptr = strcpy(Output, &Option[2]);
		}
		else
		{
			printf("Output file/device not specified. Option ignored.\n");
		}
		break;
	case'i':
		strcpy(FileName, &Option[2]);
		list = fopen(FileName, "r");
		if (list == 0)
		{
			printf("Can't open list file: %s.\n",FileName);
		}
		else
		{
			while (fgets(FileName, MAXFILE, list) != 0)
			{	
				if (FileName[0] != ';' && FileName[0] != '-')	
				{	
					if (!BeHead) Head = FALSE;
					CurrentPage =	0;
					printer = fopen(Output,"a");
					if (printer == 0)	
						{
						printf("Can't open %s for output!\n",Output);
						}
					else 
					{
						PrintLines = LinesPerPage - (HEADER+TRAILER);
						FileName[strlen(FileName)-1] = '\0';
						PrintFile(printer,FileName,PrintLines);
					}
					fclose(printer);
				}
				else if (FileName[0] == '-')
				{
					ProcessOptions(FileName,Output,&ListFile);
				}
			}
			fclose(list);
		}
		break;
	default:
		printf("Invalid option: %s.\n", Option);
	}
}

/* Print File */

PrintFile(printer, FileName, PrintLines)

FILE *printer;
char *FileName;
int PrintLines;

{
	int			CurrentLine;
	char        *fgets();
	char		*line;         
	int         LineNumber;
	char		*lineptr;
	FILE		*list;
	static char	NewLine[MAXCHAR];
	BOOL		NewPage;
	static char	SourceLine[MAXCHAR];
	char		*strcpy();
	BOOL		WrapAround;
	int			x;
	
	list = fopen(FileName, "r");
	if (list == 0)
	{
		printf("Can't open file %s.\n", FileName);
	}
	else
	{
		printf("Printing file %s...  [3mCTRL-C to abort [0m\n", FileName);
		LineNumber = 0;
		NewPage = TRUE;
		WrapAround = FALSE;
		while (line != 0)
		{
			if (!WrapAround)
			{
				line = fgets(SourceLine, MAXCHAR, list);
				if (line != 0)
				{
					if (ShowNumber)
					{
						LineNumber = LineNumber +1;
						sprintf(NewLine, LINEFORMAT, LineNumber);
						lineptr = strcpy(&NewLine[LINESPACE], SourceLine);
						lineptr = strcpy(SourceLine, NewLine);
					}
					ConvertTABtoSpace(SourceLine);
				}
			}
			if (line != 0)
			{
				if (NewPage && !Head)
				{	
					PrintHeader(printer, FileName);
					if (NoHead) 
						Head = TRUE;
					NewPage = FALSE;
					CurrentLine = 0;
				}
				if ((strlen(SourceLine) -1) > Columns)
				{
					ProcessWrapAround(printer, SourceLine, &WrapAround);
				}
				else
				{	
					if (!SkipPage)
						fprintf(printer, "%s", SourceLine);
					WrapAround = FALSE;
				}
				CurrentLine = CurrentLine + 1;
				if (CurrentLine >= PrintLines) 
				{
					if (Head == FALSE)
					{
						for (x=0; x<TRAILER ; x=x+1)
						{
							if (!SkipPage) 
								fprintf(printer,"\n");						
						}
						NewPage = TRUE;
					}
				}
			}
		}
		fclose (list);
		if (!NewPage)
		{
			for (x = CurrentLine;x<LinesPerPage-HEADER;x++)
			{
				if (!SkipPage && !NoHead) 
					fprintf(printer, "\n");
				
			}
		}
	}
}
	
/*    Print Header      */

PrintHeader(printer, FileName)

FILE *printer;
char FileName[];

{
	long int	clocktime;
	struct tm	*CTime;
	struct tm 	*gmtime();
	int			MiddleLine;
	long int	Month;
	char        *Mois[];
	long int	time();
	int			x;
	int			y;
	int			z;
	
	CurrentPage = CurrentPage +1;
	if (CurrentPage < StartPage || CurrentPage > EndPage)
	{	
		SkipPage = TRUE;
	}
	else
	{	
		SkipPage = FALSE;
	}
	MiddleLine = HEADER/2;
	for (x = 0;x < HEADER; x=x+1)
	{
		if (x != MiddleLine)
		{
			if (!SkipPage)
				fprintf(printer, "\n");
		}
		else
		{
			for (y=0; y <=  Columns - TIMESIZE && FileName[y] != '\0'; y++)	
			{	
				if (!SkipPage)
					fputc(FileName[y],printer);
			}
			if(y<=Columns-TIMESIZE)
			{
				for (z=y; z<=Columns - TIMESIZE;z++)
				{
					if (!SkipPage)
						fputc(' ', printer);
				}
			}
			time(&clocktime);
			if (clocktime == -1)
			{
				if (!SkipPage)
					fprintf(printer, NOTMFORMAT, CurrentPage);
			}
			else
			{
				CTime = gmtime(&clocktime);
				if (CTime == 0)
				{
					if (!SkipPage)
				 		fprintf( printer, NOTMFORMAT, CurrentPage);
				}
				else
				{
					Month = CTime->tm_mon+1;
					switch (Month) 
					{
						case 1: strcpy( Mois,"janv ");break;
						case 2: strcpy( Mois,"févr ");break;
						case 3: strcpy( Mois,"mars ");break;
						case 4: strcpy( Mois,"avr ");break;
						case 5: strcpy( Mois,"mai ");break;
						case 6: strcpy( Mois,"juin ");break;
						case 7: strcpy( Mois,"juil ");break;
						case 8: strcpy( Mois,"août ");break;
						case 9: strcpy( Mois,"sept ");break;
						case 10: strcpy( Mois,"oct ");break;
						case 11: strcpy( Mois,"nov ");break;
						case 12: strcpy( Mois,"déc ");break;
					}
					if (!SkipPage)
					{
				    	fprintf(printer,TIMEFORMAT, CTime->tm_mday,
				     		Mois, CTime->tm_year, CurrentPage);
				
					}
				}
			}
		}
	}
}

/* Process Wrap-Around */

ProcessWrapAround(printer, SourceLine, WrapAround)

FILE *printer;
char SourceLine[];
int  *WrapAround;

{
	static int	FirstChar;
	char		*lineptr;
	static char	NewLine[MAXCHAR];			
	char		*strcpy();
	char		*strncpy();
	int			y;
	
	for (y=0; y<Columns-R_ARW_SIZE;y++)
	{
		if (!SkipPage)
			fputc(SourceLine[y], printer);
	}	
		if (!SkipPage)
			fprintf(printer, R_ARW_TEXT);
	if (*WrapAround != TRUE)
	{
		if(ShowNumber)
		{
			y = LINESPACE;
		}
		else
		{
			y = 0;
		}
		FirstChar = -1;
		while (y <= Columns-(L_ARW_SIZE+R_ARW_SIZE) && FirstChar == -1) 
		{
			if (SourceLine[y] != ' ')
			{
				FirstChar = y;
			}
			else
			{
				y = y +1;
			}
		}
	}
	for (y=0; y < FirstChar; y = y+1)
	{
		NewLine[y] = ' ';
	}
	lineptr = strcpy(&NewLine[y], L_ARW_TEXT, L_ARW_SIZE);
	lineptr = strcpy(&NewLine[y+L_ARW_SIZE], &SourceLine[Columns - L_ARW_SIZE]);
	lineptr = strcpy(SourceLine, NewLine);
	*WrapAround = TRUE;
}

/* Convert TAB to space */

ConvertTABtoSpace (SourceLine)

char SourceLine[];
	{
	int			FromChar;
	char		*lineptr;
	int			LineOffset;
	static char	NewLine[MAXCHAR];
	int			Spaces;
	char		*strcpy();
	int			ToChar;
	int			x;
	
if (TABSize >0)
	{
		if(ShowNumber)
		{
			LineOffset = LINESPACE;
		}
		else
		{
			LineOffset = 0;
		}
		ToChar = 0;		
		for (FromChar = 0; FromChar <= strlen(SourceLine); FromChar++)
		{
			if (SourceLine[FromChar] == TAB)
			{
				Spaces = TABSize - ((ToChar-LineOffset) % TABSize);
				for(x=0; x < Spaces; x++)
				{
					NewLine[ToChar] = SPACE;
					ToChar = ToChar + 1;
				}
			}
			else
			{
				NewLine[ToChar] = SourceLine[FromChar];
				ToChar = ToChar + 1;
			}
		}
		lineptr = strcpy(SourceLine, NewLine);
	}
}
			
_wb_parse() {}

