/*
 *  Super Return Label program
 *    by Joel Swank 12-11-88
 *
 */

/********* INCLUDES ************************ */


#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#include <stdio.h>
#include <errno.h>

/* external Text in abouthelp.c  */
extern struct IntuiText prerrtxt ;
extern struct IntuiText prerrtxt2 ;
extern struct IntuiText badcoptxt ;
extern struct IntuiText oktxt ;
extern struct IntuiText parfailtxt ;
extern struct IntuiText prfailtxt ;
extern struct IntuiText cantxt ;
extern struct IntuiText retrytxt ;

/* Defines for setting/clearing GADGDISABLED flag */
#define OffGad(gad) (gad).Flags = gad.Flags | GADGDISABLED;
#define OnGad(gad) (gad).Flags = gad.Flags & ~(GADGDISABLED);


struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;

struct Window *wG = NULL;
struct RastPort *rpG;
struct IntuiMessage *message;	/* the message from the IDCMP */

struct Window *OpenWindow();
struct IntuiMessage *GetMsg();
struct MenuItem *ItemAddress();
void *OpenLibrary();
FILE *print;

/* get the PowerWindows 2.0 code */
#include "srwindow.h"

/* internal modes */
int lmode = 3 ;    /* number of lines - 3,4,5 */
int cmode = 23 ;   /* number of characters per line - 19,23 */


/* Amiga Printer escape sequences */

char eliteon[] = "\033[2w";
char eliteoff[] = "\033[1w";
char condensedon[] = "\033[4w";
char condensedoff[] = "\033[3w";
char lpi8on[] = "\033[0z";
char lpi6on[] = "\033[1z";
char boldon[] = "\033[1m";
char boldoff[] = "\033[22m";
char nlqon[] = "\033[2\"z";
char nlqoff[] = "\033[1\"z";
char doubon[] = "\033[6w";
char douboff[] = "\033[5w";
char italon[] = "\033[3m";
char italoff[] = "\033[23m";
char reset[] = "\033c";

/* Epson Printer escape sequences */

char Eeliteon[] = "\033M";
char Eeliteoff[] = "\033P";
char Econdensedon[] = "\033\017";
char Econdensedoff[] = "\033\022";
char Elpi8on[] = "\0330";
char Elpi6on[] = "\0332";
char Ereset[] = "\033@";
char Esuperon[] = "\033S0";
char Esuperoff[] = "\033T";
char Six72nds[] = "\033A\06";

char blanks[] = "               "; /* blank stock for center() */

main()
{
	UWORD code;
	ULONG class;
	APTR object;
 

	/* Open the libraries */

	IntuitionBase = (struct IntuitionBase *)
		OpenLibrary("intuition.library", 0L);
	if (IntuitionBase == NULL)
		{
		exit(99);
		}
	GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L);
	if (GfxBase == NULL)
		{
		done(98);
		}

	/* Set up the Gadgets */
	if (lmode == 3) OffGad(TextL4_Gad);
	if (lmode == 3 || lmode == 4 ) OffGad(TextL5_Gad);
	OffGad(Stop_Gad)
	if (SubItem1.Flags & CHECKED) /* if Amiga */
		{
		OffGad(Line4_Gad)
		OffGad(Line5_Gad)
		}


	wG = OpenWindow(&NewWindowStructure1);	/* open the window */
	if ( wG == NULL )
		{
		done(2);
		}

	rpG = wG->RPort;	/* get a rastport pointer for the window */

	SetMenuStrip(wG,&MenuList1);	/* attach my Menu */

	PrintIText(rpG,&IntuiTextList1,0L,0L);	/* Print the text */



	while(1)
	{
		WaitPort(wG->UserPort);
			while( (message = (struct IntuiMessage *)
				GetMsg(wG->UserPort) ) != NULL)
			{
				code = message->Code;  /* MENUNUM */
				object = message->IAddress;  /* Gadget */
				class = message->Class;
				ReplyMsg(message);
				switch (class)
					{
					case CLOSEWINDOW :
						done(0);
					case GADGETDOWN:
						if (object == (APTR) &Char23_Gad ||
							object == (APTR) &Char19_Gad)
							{
							do_chars(object);
							break;
							}
						/* only change lines if Epson selected */
						if (SubItem2.Flags & CHECKED)
						if (object == (APTR) &Line3_Gad ||
							object == (APTR) &Line4_Gad ||
							object == (APTR) &Line5_Gad)
							{
							do_lines(object);
							break;
							}
						break;
					case GADGETUP:
						if (object == (APTR) &Print_Gad)
							{
							do_print();
							break;
							}
						break;
					case MENUPICK:
						if (code != MENUNULL) do_pick((USHORT)code);
						break;
					}
			}
	} 
}

/*
 * Cleanup and exit
 */

done(how)
int how;
{
	if (wG) ClearMenuStrip(wG);
	if (wG) CloseWindow(wG);
	if (GfxBase != NULL) CloseLibrary(GfxBase);
	if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
	exit(how);
}


/*
 * do_pick : handle chain of menu selections
 */

do_pick(menunum)
USHORT menunum;
{
struct MenuItem *item, *ItemAddress();
	while (menunum != MENUNULL)
		{
		switch(MENUNUM(menunum))
			{
			case 0:     /* Project */
			switch(ITEMNUM(menunum))
				{
				case 2: /* Quit */
					done(0);
				case 1: /* About */
					about();
					break;
				case 0: /* Help */
					help();
					break;
				}
			break;
			case 1:     /* Options */
			switch(ITEMNUM(menunum))
				{
				case 1:     /* Printer */
				switch(SUBNUM(menunum))
					{
					case 0:   /* Amiga */
						/* remove all gadgets */
						RemoveGList(wG,&TextL1_Gad,-1L); 
						/* disable 4-line & 5-line */
						OffGad(Line4_Gad)
						OffGad(Line5_Gad)
						/* go to 3-line mode */
						go_3();
						/* add back gadgets and refresh screen */
						redraw_scr();
						break;
					case 1:   /* Epson */
						/* remove all gadgets */
						RemoveGList(wG,&TextL1_Gad,-1L); 
						/* enable 4-line & 5-line */
						OnGad(Line4_Gad)
						OnGad(Line5_Gad)
						/* add back gadgets and refresh screen */
						redraw_scr();
						break;
					}
				break;
				case 0:     /* Centering */
				switch(SUBNUM(menunum))
					{
					case 0:   /* On */
						center_on();
						break;
					case 1:   /* Off */
						center_off();
						break;
					}
				break;
				}
			break;
			default:	/* What's this garbage ? */
				menunum = MENUNULL;
			}       /* end switch MENUNUM  */
		item = ItemAddress(&MenuList1,(long) menunum);
		menunum = item->NextSelect;
		}
}

/*
 * turn off cenetring
 */

center_off()
{

	struct StringInfo *sptr;
	/* remove all gadgets */
	RemoveGList(wG,&TextL1_Gad,-1L); 
	TextL1_Gad.Activation &= ~(STRINGCENTER); /* centering off */
	TextL2_Gad.Activation &= ~(STRINGCENTER);
	TextL3_Gad.Activation &= ~(STRINGCENTER);
	TextL4_Gad.Activation &= ~(STRINGCENTER);
	TextL5_Gad.Activation &= ~(STRINGCENTER);

	/* cleared because centered mode leaves them negative */
	/*  which screws up display           */
	sptr = (struct StringInfo *) TextL1_Gad.SpecialInfo;
	sptr->DispPos = 0;   
	sptr = (struct StringInfo *) TextL2_Gad.SpecialInfo;
	sptr->DispPos = 0;   
	sptr = (struct StringInfo *) TextL3_Gad.SpecialInfo;
	sptr->DispPos = 0;
	sptr = (struct StringInfo *) TextL4_Gad.SpecialInfo;
	sptr->DispPos = 0;
	sptr = (struct StringInfo *) TextL5_Gad.SpecialInfo;
	sptr->DispPos = 0;
	/* add back gadgets and refresh screen */
	redraw_scr();
}

/*
 * turn on cenetring
 */

center_on()
{

	/* remove all gadgets */
	RemoveGList(wG,&TextL1_Gad,-1L); 
	TextL1_Gad.Activation |= STRINGCENTER;
	TextL2_Gad.Activation |= STRINGCENTER;
	TextL3_Gad.Activation |= STRINGCENTER;
	TextL4_Gad.Activation |= STRINGCENTER;
	TextL5_Gad.Activation |= STRINGCENTER;
	/* add back gadgets and refresh screen */
	redraw_scr();
}

/*
 *  do some printing
 */

do_print()
{
	register long copies;
	ULONG class;
	char l1[25], l2[25], l3[25], l4[25], l5[25];
	struct IntuiMessage *message;	/* the message from the IDCMP */
	copies = atol(Copies_GadSIBuff);

	if (copies == 0) copies = 1;

	if (copies < 0)
		{
		AutoRequest(wG,&badcoptxt,0L,&oktxt,0L,0L,300L,75L);
		return;
		}

	/* Open the printer */
	if (SubItem2.Flags & CHECKED) /* if Epson selected , par: */
		{
		while ((print = fopen("par:","w")) == NULL)
			{
			if (AutoRequest(wG,&parfailtxt,&retrytxt,&cantxt,
				0L,0L,300L,75L)) continue;
			return;
			}
		}
	else while ((print = fopen("prt:","w")) == NULL) /* Amiga, prt: */
			{
			if (AutoRequest(wG,&prfailtxt,&retrytxt,&cantxt,
				0L,0L,300L,75L)) continue;
			return;
			}

	off_gads();
	pr_init();    /* init the printer */

	/* do cenetring if requested */
	if (SubItem3.Flags & CHECKED) /* if ON selected , center em */
		{
		center(l1,TextL1_GadSIBuff);
		center(l2,TextL2_GadSIBuff);
		center(l3,TextL3_GadSIBuff);
		center(l4,TextL4_GadSIBuff);
		center(l5,TextL5_GadSIBuff);
		}
	else {      /* else just copy */
		strcpy(l1,TextL1_GadSIBuff);
		strcpy(l2,TextL2_GadSIBuff);
		strcpy(l3,TextL3_GadSIBuff);
		strcpy(l4,TextL4_GadSIBuff);
		strcpy(l5,TextL5_GadSIBuff);
		}

	while (copies > 0)
		{
		if (lmode == 4) /* do first 3 lines at 7/72 line spacing */
			fprintf(print,"\033A\07");
		fprintf(print,"%-*s%-*s%-*s\n",cmode,l1,cmode,l1,cmode,l1);
		fprintf(print,"%-*s%-*s%-*s\n",cmode,l2,cmode,l2,cmode,l2);
		fprintf(print,"%-*s%-*s%-*s\n",cmode,l3,cmode,l3,cmode,l3);
			/* do last line at 15/72 line spacing */
		if (lmode == 4)	fprintf(print,"\033A\017");
		if (lmode == 4 || lmode == 5)
			fprintf(print,"%-*s%-*s%-*s\n",cmode,l4,cmode,l4,cmode,l4);
		if (lmode == 5)
			fprintf(print,"%-*s%-*s%-*s\n",cmode,l5,cmode,l5,cmode,l5);
		if (lmode != 4)	fputs("\n",print);

		if (ferror(print))   /* error on output file */
			{
			prerrtxt2.IText = (UBYTE *) sys_errlist[errno];
			AutoRequest(wG,&prerrtxt,0L,&oktxt,0L,0L,300L,75L);
			break;	/* early exit */
			}

		copies--;
		sprintf(Copies_GadSIBuff,"%ld",copies);
		RefreshGList(&Copies_Gad,wG,NULL,1L);


		Delay(20L);	 /* keeps us down to printer speed */
		if ( (message = (struct IntuiMessage *)
		  GetMsg(wG->UserPort) ) != NULL)
			{
			class = message->Class;
			ReplyMsg(message);
			if (class == CLOSEWINDOW) { pr_rest(); done(0); } /* exit */
			if (class == MENUPICK) continue; /* ignore menus */
			break;    /* else STOP */
			}
		}
	pr_rest();
	fclose(print);
	on_gads();
}

/*
 * init the printer 
 */

pr_init()
{
	if (SubItem2.Flags & CHECKED) /* if Epson selected */
		{
		if (lmode == 3) fputs(Elpi8on,print);
		if (lmode == 5) fputs(Six72nds,print);
		if (lmode == 5 || lmode == 4) fputs(Esuperon,print);
		if (cmode == 23) fputs(Eeliteon,print);
		fputs(Econdensedon,print);
		}
	else {      /* use amiga codes */
		if (lmode == 3) fputs(lpi8on,print);
		if (cmode == 23) fputs(eliteon,print);
		fputs(condensedon,print);
		}
}

/*
 * restore the printer 
 */

pr_rest()
{
	if (SubItem2.Flags & CHECKED) /* if Epson selected */
		{
		fputs(Elpi6on,print);
		if (cmode == 23) fputs(Eeliteoff,print);
		fputs(Econdensedoff,print);
		if (lmode == 5 || lmode == 4) fputs(Esuperoff,print);
		}
	else {      /* use amiga codes */
		fputs(lpi6on,print);
		if (cmode == 23) fputs(eliteoff,print);
		fputs(condensedoff,print);
		}
}

/*
 * center a line
 */

center(line,buf)
char *line, *buf;
{
	int l;
	l = (cmode - strlen(buf))/2;
	if (l > 0)  strncpy(line,blanks,l);
	else l=0;
	line[l] = '\0';
	strcat(line,buf);
}

/*
 * turn back on gadgets after printing
 */

on_gads()
{
	RemoveGList(wG,&TextL1_Gad,-1L); /* remove all gadgets */
	OnGad(TextL1_Gad);    /* enable all */
	OnGad(TextL2_Gad);
	OnGad(TextL3_Gad);
	if (lmode == 4 || lmode == 5) OnGad(TextL4_Gad);
		if (lmode == 5) OnGad(TextL5_Gad);
	OnGad(Char23_Gad);
	OnGad(Char19_Gad);
	OnGad(Line3_Gad);
	if (SubItem2.Flags & CHECKED) /* if Epson selected */
		{
		OnGad(Line4_Gad);
		OnGad(Line5_Gad);
		}
	OnGad(Print_Gad);
	OffGad(Stop_Gad);   /* disable STOP */
	redraw_scr();	     /* add back gadgets and refresh screen */
	SetMenuStrip(wG,&MenuList1);	/* attach my Menu */
}

/*
 * disable gadgets for printing
 */

off_gads()
{
	ClearMenuStrip(wG);      /* disable menus */
	RemoveGList(wG,&TextL1_Gad,-1L); /* remove all Gadgets */
	OffGad(TextL1_Gad);    /* disable all but STOP and COPIES */
	OffGad(TextL2_Gad);
	OffGad(TextL3_Gad);
	OffGad(TextL4_Gad);
	OffGad(TextL5_Gad);
	OffGad(Char23_Gad);
	OffGad(Char19_Gad);
	OffGad(Line3_Gad);
	if (SubItem2.Flags & CHECKED) /* if Epson selected */
		{
		OffGad(Line4_Gad);
		OffGad(Line5_Gad);
		}
	OffGad(Print_Gad);
	OnGad(Stop_Gad);     /* enable STOP */
	redraw_scr();	     /* add back gadgets and refresh screen */
}

/*
 *  Handle line gadget change
 */

do_lines(object)
APTR object;
{
	struct Gadget *gad;
	gad = (struct Gadget *) object;
	RemoveGList(wG,&TextL1_Gad,-1L);
	if (gad->Flags & SELECTED) /* it was on  */
		{
		if (object == (APTR) &Line3_Gad) go_4();
		if (object == (APTR) &Line4_Gad) go_5();
		if (object == (APTR) &Line5_Gad) go_3();
		}
	else {    /* it was off */
		if (object == (APTR) &Line3_Gad) go_3();
		if (object == (APTR) &Line4_Gad) go_4();
		if (object == (APTR) &Line5_Gad) go_5();
		}
	redraw_scr();

}

/*
 * To 3-line lmode
 */

go_3()
{
	Line4_Gad.Flags = Line4_Gad.Flags  & ~(SELECTED);
	Line5_Gad.Flags = Line5_Gad.Flags  & ~(SELECTED);
	Line3_Gad.Flags = Line3_Gad.Flags  | SELECTED;
	OffGad(TextL4_Gad);
	OffGad(TextL5_Gad);
	lmode = 3;
}


/*
 * To 4-line lmode
 */

go_4()
{
	Line5_Gad.Flags = Line5_Gad.Flags  & ~(SELECTED);
	Line3_Gad.Flags = Line3_Gad.Flags  & ~(SELECTED);
	Line4_Gad.Flags = Line4_Gad.Flags  | SELECTED;
	OnGad(TextL4_Gad);
	OffGad(TextL5_Gad);
	lmode = 4;
}


/*
 * To 5-line lmode
 */

go_5()
{
	Line4_Gad.Flags = Line4_Gad.Flags  & ~(SELECTED);
	Line3_Gad.Flags = Line3_Gad.Flags  & ~(SELECTED);
	Line5_Gad.Flags = Line5_Gad.Flags  | SELECTED;
	OnGad(TextL4_Gad);
	OnGad(TextL5_Gad);
	lmode = 5;
}

/*
 *  Handle char gadget change
 */

do_chars(object)
APTR object;
{
	struct Gadget *gad;
	gad = (struct Gadget *) object;
	RemoveGList(wG,&TextL1_Gad,-1L);
	if (gad->Flags & SELECTED) /* it was on */
		{                     /* . . so turn it off and other one on */
		if (object == (APTR) &Char23_Gad) go_19();
		if (object == (APTR) &Char19_Gad) go_23();
		}
	else {     /* it was off */
		if (object == (APTR) &Char23_Gad) go_23();
		if (object == (APTR) &Char19_Gad) go_19();
		}

	TextL1_GadSInfo.MaxChars = (SHORT) cmode+1;
	TextL2_GadSInfo.MaxChars = (SHORT) cmode+1;
	TextL3_GadSInfo.MaxChars = (SHORT) cmode+1;
	TextL4_GadSInfo.MaxChars = (SHORT) cmode+1;
	TextL5_GadSInfo.MaxChars = (SHORT) cmode+1;
	redraw_scr();
}


/*
 * To 19-character lmode
 */

go_19()
{
	cmode = 19;
	Char19_Gad.Flags = Char19_Gad.Flags  | SELECTED;
	Char23_Gad.Flags = Char23_Gad.Flags  & ~(SELECTED);
	TextL1_GadSIBuff[19] = '\0';  /* truncate buffers */
	TextL2_GadSIBuff[19] = '\0';
	TextL3_GadSIBuff[19] = '\0';
	TextL4_GadSIBuff[19] = '\0';
	TextL5_GadSIBuff[19] = '\0';
}


/*
 * To 23-character lmode
 */

go_23()
{                     /* . . so turn it on and other one off */
	Char19_Gad.Flags = Char19_Gad.Flags  & ~(SELECTED);
	Char23_Gad.Flags = Char23_Gad.Flags  | SELECTED;
	cmode = 23;
}

/*
 * Redraw Window
 *  Assumes Gadgets have been removed
 */

redraw_scr()
{
	SetAPen(rpG,0L);
	RectFill(rpG,2L,22L,(long)wG->Width-3,(long)wG->Height-2);
	AddGList(wG,&TextL1_Gad,0L,-1L,NULL);
	RefreshGList(&TextL1_Gad,wG,NULL,-1L);
	PrintIText(rpG,&IntuiTextList1,0L,0L);	/* Print the text */
}
_abort()
{

	done(6);
}
