/*
 *
 * Module : dwprint.c
 *
 * Description : Print program for daisy wheels
 *
 * Author : Simon Raybould
 *
 * Date : January 1990
 *
 * Compiler switches :
 *
 *        TEST - Send output to screen, for testing.
 *
 */
 
#include <stdio.h>			/* Yawn */
#include <intuition/intuition.h>	/* For the window struct stuff */
#include <workbench/startup.h>		/* For the filename from WB */
#include <workbench/workbench.h>	/* For the filename from WB */

#define PRINTER		"PRT:"		/* Printer filename */
#define DEFAULTLPP	66		/* Default lines per page */
#define CTRLL		12		/* Control L */
#define MAXLINELEN	128
#define TAB		0x09		/* ASCii code for a horizontal tab */
#define TABSTOP		8		/* Tab stop every TABSTOP columns */

/*
 *	Globals
 */
char titlebuffer[80];
short LinesPerPage = DEFAULTLPP;

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Window *LittleWindow;
struct IntuiMessage *Message;
struct RastPort *RP;
ULONG IconBase = 0;

/* WB Startup stuff */
extern struct WBStartup *WBenchMsg;
struct FileLock *startlock, *newlock;

/*** The Newwindow Structure. ***/

char TITLETEXT[] = "DWPrint V1.2 S.J.Raybould 1990";

struct TextAttr Font = {
	(STRPTR)"topaz.font",
	TOPAZ_EIGHTY, 0, 0
};

	/* Gadget to do NEXT PAGE */

USHORT NextVectors[] = {
	0, 0, 80, 0, 80, 12, 0, 12, 0, 1,
	79, 1, 79, 11, 1, 11, 1, 1
};

struct Border NextBorder = {
	-2, -2,		/* Initial offsets, gadget relative */
	1, 0, JAM1,	/* Frontpen, Backpen, Drawmode	*/
	9,		/* Number of vectors*/
	NextVectors,	/* Pointer to array of vectors */
	NULL		/* No next border */
};

struct IntuiText NextText = {
	1, 0,				/* Frontpen, Backpen */
	JAM1,				/* Drawmode */
	3, 1,				/* Leftedge, Topedge (relative to gadget) */
	&Font,				/* Pointer to font structure */
	"NEXT PAGE",			/* Actual text */
	NULL				/* Next text */
};

struct Gadget Next = {
	NULL,			/* Pointer to next gadget */
	130, 60, 77, 9,		/* Left, Top, Width, Height */
	GADGHCOMP,		/* Flags */
	RELVERIFY|GADGIMMEDIATE,/* Activation Flags */
	BOOLGADGET,		/* Type */
	(APTR)&NextBorder,	/* Pointer to border border image */
	NULL,			/* No pointer to select render */
	&NextText,		/* Pointer to Ituitext structure */
	0,			/* Mutual exclude */
	NULL,			/* Pointer to Special info */
	0,			/* no ID */
	NULL			/* Pointer to special data */
};

struct NewWindow NewLittleWindow = {
	40,	/* Left edge */
	15,	/* Top edge */
	330,	/* Width */
	80,	/* Height */
	0,	/* Front pen */	
	1,	/* Back pen */
CLOSEWINDOW | GADGETUP,	/* IDCMP Flags */
WINDOWDRAG | WINDOWDEPTH | RMBTRAP | WINDOWCLOSE | NOCAREREFRESH, /* Windo Flagz */	
	&Next,		/* First Gadget */
	NULL,		/* Custom menu image */
	TITLETEXT,	/* Window title */
	NULL,		/* Custom screen */
	NULL,		/* Custom bitmap */
	10,		/* Minimum Width */
	10,		/* Minimum Height */
	500,		/* Maximum Width */
	160,		/* Maximum Height */
	WBENCHSCREEN,	/* Type of screen */
};

void main(argc, argv)
int argc;
char **argv;
{
	register int Class;
	struct Window *OpenWindow();
	struct IntuiMessage *GetMsg();
	struct WBArg *arg;
	char *filename, sbuffer[80], buffer[MAXLINELEN], *buf_ptr, line;
	unsigned char FromWB = FALSE;
	int page=1;
	FILE *fp;
	void ChkToolTypes();
	FILE *pfp;
	char *chstr = "CHANGE PAPER AND CLICK NEXT PAGE";
	char *rchstr= "                                ";
	char ContLine = FALSE;
	char wbuffer[MAXLINELEN], *rptr;
	short wptr;

	newlock = startlock = (struct FileLock *)NULL;

	switch(argc) {
	case 0:
		FromWB = TRUE;
		/* Check if user has set lines per page in tool types */
		ChkToolTypes();
#ifdef TRACE
		printf("NumArgs = %d\n", WBenchMsg->sm_NumArgs);
		arg = WBenchMsg->sm_ArgList;
		printf("Arg0 = %s\n", (char *)arg->wa_Name);
		arg++;
		printf("Arg1 = %s\n", (char *)arg->wa_Name);
#endif /* TRACE */
		if(WBenchMsg->sm_NumArgs != 2) {
			fprintf(stderr, "No file selected.\n");
			Delay(300);
			exit(1);
		} else {
			arg = WBenchMsg->sm_ArgList;
			arg++;
			filename = (char *)arg->wa_Name;
			newlock = (struct FileLock *)arg->wa_Lock;
			startlock = (struct FileLock *)CurrentDir(newlock);
		}
		break;
	case 2:
		filename = argv[1];
		break;
	case 3:
		filename = argv[1];
		LinesPerPage = atoi(argv[2]);
		if(LinesPerPage > 0)
			break;
		/* ELSE FALL THROUGH TO USAGE */
	default:
		fprintf(stderr, "Usage: %s <filename> [n]\n", argv[0]);
		exit(1);
	}

	IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0);
	GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);

	LittleWindow = OpenWindow(&NewLittleWindow);
	if (LittleWindow == NULL) exit(400L);/* No memory for little window! */

	RP = LittleWindow->RPort;

	SetAPen(RP, 1);
	SetBPen(RP, 0);
	SetDrMd(RP, JAM2);

	/*
	 *	OK it's about time we actually did somthing dwprint'ish.
	 */

	if((fp = fopen(filename, "r")) == (FILE *)NULL) {
		fprintf(stderr, "Failed to open input file \"%s\"\n", filename);
		perror("Reason");
		if(FromWB)
			Delay(300);
		CloseWindow(LittleWindow);
		if(newlock != startlock)
			CurrentDir(startlock);
		exit(1);
	}
#ifndef TEST
	if((pfp = fopen(PRINTER, "w")) == (FILE *)NULL) {
		fprintf(stderr, "Failed to open printer\n");
		perror("Reason");
		if(FromWB)
			Delay(300);
		CloseWindow(LittleWindow);
		if(newlock != startlock)
			CurrentDir(startlock);
		exit(1);
	}
	if(FromWB) {
		close(0);
		close(1);
		close(2);
	}
#else	/* If TEST switch set */
	pfp = stdout;
#endif /* TEST */

	SetAPen(RP, 3);
	Move(RP, 50, 20);
	Text(RP, "Printing:", strlen("Printing:"));
	SetAPen(RP, 1);
	Move(RP, 130, 20);
	Text(RP, filename, strlen(filename));

	/* Wait for event */
	for (;;) {
		for(line=1;line<(LinesPerPage+1);line++) {
			sprintf(sbuffer, "Page: %-3d         Line: %-2d", page, line);
			Move(RP, 50, 35);
			Text(RP, sbuffer, strlen(sbuffer));
			if(!ContLine) {
				if(fgets(buffer, MAXLINELEN, fp) == (FILE *)NULL) {
					CloseWindow(LittleWindow);
					if(newlock != startlock)
						CurrentDir(startlock);
					fclose(fp);
					fclose(pfp);
					exit(0);
				}
				buf_ptr = buffer;	/* Reset ptr to start of buffer */
			}
			/* If CTRL-L then end page */
			if(*buf_ptr == CTRLL) {
				ContLine = TRUE;
				fputc(*buf_ptr++, pfp);		/* Send Cntrl L */
				fflush(pfp);
				if(!*buf_ptr)	/* End of line reached. */
					ContLine = FALSE;	/* Don't put NULL on its own page */
				break;
			} else {
				ContLine = FALSE;
				for(wptr = 0;wptr < MAXLINELEN;wptr++)
					wbuffer[wptr] = ' ';
				for(wptr = 0, rptr = buf_ptr;*rptr != '\0';rptr++) {
					if(*rptr == TAB)
						wptr = ((wptr/TABSTOP) + 1) * TABSTOP;
					else
						wbuffer[wptr++] = *rptr;
				}
				wbuffer[wptr] = *rptr;
				fputs(wbuffer, pfp);			/* Output line */
				fflush(pfp);
			}
		}
		Move(RP, 40, 50);
		Text(RP, chstr, strlen(chstr));
		page++;
		SetWindowTitles(LittleWindow, -1, titlebuffer);
		Message = GetMsg(LittleWindow->UserPort);
		while (Message == NULL) {
			/* Lets be nice to other tasks!  Ya! */
			Wait(1<<LittleWindow->UserPort->mp_SigBit);
			Message = GetMsg(LittleWindow->UserPort);
		};
		Class = Message->Class;
		if (Message != NULL) ReplyMsg(Message);
		
		switch(Class) {
		case CLOSEWINDOW:
			CloseWindow(LittleWindow);
			if(newlock != startlock)
				CurrentDir(startlock);
			fclose(fp);
			fclose(pfp);
			exit(0);
		case GADGETUP:
			Move(RP, 40, 50);
			Text(RP, rchstr, strlen(rchstr));
			break;	/* Just go round again */
		default:
#ifdef TRACE
			fprintf(stderr, "Unkown message (0x%x) recieved\n", Class);
#endif /* TRACE */
			break;
		}
	}
}

void ChkToolTypes()
{
	struct DiskObject *diskobj;
	struct WBArg *arg;
	char **toolarray, *s, *progname;

	arg = WBenchMsg->sm_ArgList;
	progname = (char *)arg->wa_Name;

	if(IconBase = OpenLibrary("icon.library", 0)) {
		diskobj = (struct DiskObject *)GetDiskObject(progname);
		if(diskobj) {
			toolarray = diskobj->do_ToolTypes;
			if(s=(char *)FindToolType(toolarray, "LINESPERPAGE")) {
				LinesPerPage = atoi(s);
#ifdef TRACE
				printf("Found it, got %d\n", LinesPerPage);
#endif /* TRACE */
			}
		}
		FreeDiskObject(diskobj);
	}
}
