/* formPanel.c 
 *
 *  defines the GUIFront characteristics of the form panel 
 */
  
#include <stdio.h>  
#include <intuition/gadgetclass.h>
#include <clib/intuition_protos.h>
#include <clib/asl_protos.h>
#include <libraries/asl.h>
#include <string.h>
#include <stdio.h>
#include "amiCheck.h"
#include "dataBase.h"
#include "formPanel.h"
#include "printPanel.h"
#include "regGadget.h"

/* prototypes */
BOOL FormHandleGadget(struct IntuiMessage *);
void FormInit(void);
void FormChangeTemplate(int template);
void FormTestPrint(void);
BOOL FormCheckField(ULONG margin, ULONG width, ULONG line, char *resp);
BOOL FormGoodbye(struct IntuiMessage *imsg);

static checkForm outofbounds = {
	FALSE,
 	MAXCHECKLINES,	/* lines per check */
	10,		        /* checks per page */

	MAXCHECKCOLS,	/* pay margin */
	STRINGSIZE, 	        /* pay width */
	MAXCHECKLINES,	/* pay line */

	MAXCHECKCOLS,	/* date margin */
	DATESIZE,	        /* date width */
	MAXCHECKLINES,	/* date line */

	MAXCHECKCOLS,	/* amnt margin */
	AMNTSIZE, 	        /* amnt width */
	MAXCHECKLINES,	/* amnt line */
	
	MAXCHECKCOLS,	/* memo margin */
	STRINGSIZE, 	        /* memo width */
	MAXCHECKLINES,	/* memo line */
 

	4,		        /* voucher type */
	MAXCHECKCOLS,	/* voucher margin */
	MAXCHECKCOLS,	/* voucher width */

	MAXCHECKCOLS,        /* string stuff */
	MAXCHECKCOLS,
	MAXCHECKLINES,

	MAXCHECKLINES,       /* top check lines */
   	MAXCHECKCOLS         /* check cols */
};

formControl localForms;
ExtErrorData FormExtData;
GUIFront *formGUI;
static struct Window *myWin;


STRPTR fpvlabels[] =
{
	"none",
	"Left/Right",
	"Above+Below",
	"Two Below",
   	"One Above",
   	"One Below",
	NULL,
};

struct TagItem fopdev[] = {
	{ALT_Image, ALTI_GetFile},
	{ALT_AslRequester, FALSE},
	/*{GA_Immediate,TRUE},*/
	{TAG_DONE},
};

struct TagItem  fptcytags[] = {
	{GTCY_Labels,fptlabels},
	{TAG_DONE},
};

struct TagItem  fpvcytags[] = {
	{GTCY_Labels,fpvlabels},
	{TAG_DONE},
};


/* define gadgetspec */
GadgetSpec FOPgadgetspecs[] = 
{
	{CYCLE_KIND,10,0,{0,0,0,0,"_Use Template:",NULL, GID_FOPTEMPLATE,
		PLACETEXT_LEFT}, fptcytags, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"_Lines per Check:", NULL, GID_FOPCHECKLINES,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"O_rder margin:", NULL, GID_FOPPAYMARGIN,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Order width:", NULL, GID_FOPPAYWIDTH,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Order line#:", NULL, GID_FOPPAYLINE,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"_Date margin:", NULL, GID_FOPDATEMARGIN,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Date width:", NULL, GID_FOPDATEWIDTH,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Date line#:", NULL, GID_FOPDATELINE,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"_$ margin:", NULL, GID_FOPAMNTMARGIN,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"$ width:", NULL, GID_FOPAMNTWIDTH,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"$ line#:", NULL, GID_FOPAMNTLINE,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"_Memo margin:", NULL, GID_FOPMEMOMARGIN,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Memo width:", NULL, GID_FOPMEMOWIDTH,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Memo line#:", NULL, GID_FOPMEMOLINE,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

	{CYCLE_KIND,4,0,{0,0,0,0,"_Voucher Type:",NULL, GID_FOPVOUCHERTYPE,
		PLACETEXT_LEFT}, fpvcytags, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Voucher margin:", NULL, GID_FOPVOUCHERMARGIN,         
	        PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Voucher width:", NULL, GID_FOPVOUCHERWIDTH,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Checks per Pa_ge:", NULL, GID_FOPCHECKSPAGE,         
	        PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

	{CHECKBOX_KIND,0,0,{0,0,0,0,"S_heet",NULL,GID_FOPFF,
		PLACETEXT_LEFT},NULL,GS_DefaultTags},

        {BUTTON_KIND,0,0,{0,0,0,0,"_OK", NULL, GID_FOPOK,         
                PLACETEXT_IN}, NULL, GS_DefaultTags}, 

        {BUTTON_KIND,0,0,{0,0,0,0,"_Test", NULL, GID_FOPTEST,         
                PLACETEXT_IN}, NULL, GS_DefaultTags},

        {BUTTON_KIND,0,0,{0,0,0,0,"_Cancel", NULL, GID_FOPCANCEL,         
                PLACETEXT_IN}, NULL, GS_DefaultTags},

	{STRING_KIND,10,0,{0,0,0,0,"Output Devi_ce:", NULL, GID_FOPDEVICE,
		PLACETEXT_LEFT},NULL,GS_DefaultTags},

	{GETALT_KIND,0,0,{0,0,0,0,NULL, NULL, GID_FOPFILE,
		PLACETEXT_LEFT},fopdev,GS_DefaultTags},

	{INTEGER_KIND,0,0,{0,0,0,0,"Columns",NULL,GID_FOPCOLS,
		PLACETEXT_LEFT},TxtInt,GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"_Pay margin:", NULL, GID_FOPSTRMARGIN,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Pay width:", NULL, GID_FOPSTRWIDTH,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Pay line#:", NULL, GID_FOPSTRLINE,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},

        {INTEGER_KIND,4,0,{0,0,0,0,"Top Lines:", NULL, GID_FOPTOPLINES,         
                PLACETEXT_LEFT}, TxtInt, GS_DefaultTags},
	
};

/* set up array of pointers to our specs */
GadgetSpec *FP_FormSpecs[] =
{
        &FOPgadgetspecs[0],
        &FOPgadgetspecs[1],
        &FOPgadgetspecs[2],
        &FOPgadgetspecs[3],
        &FOPgadgetspecs[4],
        &FOPgadgetspecs[5],
        &FOPgadgetspecs[6],
        &FOPgadgetspecs[7],
        &FOPgadgetspecs[8],
        &FOPgadgetspecs[9],
        &FOPgadgetspecs[10],        
	&FOPgadgetspecs[11],
        &FOPgadgetspecs[12],
        &FOPgadgetspecs[13],    
	&FOPgadgetspecs[14],    
	&FOPgadgetspecs[15], 
	&FOPgadgetspecs[16], 
	&FOPgadgetspecs[17], 
	&FOPgadgetspecs[18],
	&FOPgadgetspecs[19],  
	&FOPgadgetspecs[20], 
	&FOPgadgetspecs[21], 
 	&FOPgadgetspecs[22],
	&FOPgadgetspecs[23],
	&FOPgadgetspecs[24],
	&FOPgadgetspecs[25],
	&FOPgadgetspecs[26],
	&FOPgadgetspecs[27],
	&FOPgadgetspecs[28],
	NULL,
};


/* define the layout of this panel */
ULONG FP_FormPanel[] =
{
   GUIL_Flags, GUILF_PropShare | GUILF_EqualWidth,

   GUIL_HorizGroup, 1,
        GUIL_Flags, GUILF_PropShare | GUILF_EqualHeight,
	GUIL_FrameType, GUILFT_Recess,
        
		GUIL_VertGroup, 1,
	            GUIL_VertGroup, 1,
			GUIL_FrameType, GUILFT_Ridge,
			GUIL_FrameHeadline, "Print Settings",
			GUIL_Flags, GUILF_LabelAlign | GUILF_EqualShare | GUILF_EqualWidth,

			GUIL_GadgetSpecID, GID_FOPTEMPLATE,
			GUIL_HorizGroup,0,
				GUIL_Flags, GUILF_PropShare | GUILF_EqualHeight,
				GUIL_GadgetSpecID, GID_FOPDEVICE,
				GUIL_GadgetSpecID, GID_FOPFILE,
			TAG_DONE,
		    TAG_DONE,

		    GUIL_VertGroup,1,
				GUIL_FrameType, GUILFT_Ridge,
				GUIL_FrameHeadline, "Page Settings",

				GUIL_Flags, GUILF_EqualShare | GUILF_LabelAlign | GUILF_EqualWidth,
				GUIL_GadgetSpecID, GID_FOPCHECKSPAGE,
				GUIL_GadgetSpecID, GID_FOPCHECKLINES,
				GUIL_GadgetSpecID, GID_FOPVOUCHERTYPE,
				GUIL_GadgetSpecID, GID_FOPVOUCHERMARGIN,
				GUIL_GadgetSpecID, GID_FOPVOUCHERWIDTH,
                        GUIL_HorizGroup,1,
                                GUIL_Flags, GUILF_PropShare,
                                GUIL_GadgetSpecID, GID_FOPCOLS,
				        GUIL_GadgetSpecID, GID_FOPFF,
                        TAG_DONE,                                
            TAG_DONE,

		TAG_DONE, /* print settings */

		GUIL_HorizGroup, 1,
			GUIL_FrameType, GUILFT_Ridge,
			GUIL_FrameHeadline, "Field Settings",
			GUIL_Flags, GUILF_PropShare | GUILF_LabelAlign | GUILF_EqualWidth,

			GUIL_VertGroup,0,
				GUIL_Flags, GUILF_EqualHeight | GUILF_LabelAlign | GUILF_EqualWidth,
				GUIL_GadgetSpecID, GID_FOPDATEMARGIN,
				GUIL_GadgetSpecID, GID_FOPDATEWIDTH,
				GUIL_GadgetSpecID, GID_FOPDATELINE,
				GUIL_GadgetSpecID, GID_FOPAMNTMARGIN,
				GUIL_GadgetSpecID, GID_FOPAMNTWIDTH,
				GUIL_GadgetSpecID, GID_FOPAMNTLINE,
				GUIL_GadgetSpecID, GID_FOPSTRMARGIN,
				GUIL_GadgetSpecID, GID_FOPSTRWIDTH,
			TAG_DONE,

			GUIL_VertGroup,0,
				GUIL_Flags, GUILF_EqualHeight | GUILF_LabelAlign | GUILF_EqualWidth,
				GUIL_GadgetSpecID, GID_FOPSTRLINE,
				GUIL_GadgetSpecID, GID_FOPPAYMARGIN,
				GUIL_GadgetSpecID, GID_FOPPAYWIDTH,
				GUIL_GadgetSpecID, GID_FOPPAYLINE,
				GUIL_GadgetSpecID, GID_FOPMEMOMARGIN,
				GUIL_GadgetSpecID, GID_FOPMEMOWIDTH,
				GUIL_GadgetSpecID, GID_FOPMEMOLINE,
				GUIL_GadgetSpecID, GID_FOPTOPLINES,
					
			TAG_DONE,
		TAG_DONE, /* field settings */

	TAG_DONE, /* horiz group of window */

    GUIL_HorizGroup,1,
        GUIL_Flags, GUILF_EqualSize | GUILF_EqualWidth,
        
           GUIL_GadgetSpecID, GID_FOPOK,
	   GUIL_GadgetSpecID, GID_FOPTEST,
	   GUIL_GadgetSpecID, GID_FOPCANCEL,
           
    TAG_DONE,   
           
TAG_DONE,
};


/****************************************************
* FormGUI ()
*
*	Creates the GUI for the form panel.
*****************************************************/
void  FormGUI(void)
{
 BOOL done = FALSE;
 BOOL reply = TRUE;    
 ULONG signal;

 AmiLock();
 GF_SetGUIAttr(formGUI, GUI_OpenGUI, TRUE, TAG_DONE);
 /* grab window */
 GF_GetGUIAttr(formGUI,GUI_Window,&myWin,TAG_DONE);
 FormInit();

 /* Process input events */
 while (!done) {
     	struct IntuiMessage *imsg;

	/* Wait for an event to occur */
	signal = GF_Wait(guiapp,AmigaGuideSignal(agc));
	if (signal & AmigaGuideSignal(agc)) {
		AmiHelpMsg();
		continue;
	}

        /* We only bother to listen for CLOSEWINDOW events.
         * Of course, in a real application, you would be
         * examining the Class field for IDCMP_GADGETUP
         * messages and act accordingly.
         */

         while (imsg = GF_GetIMsg(guiapp)) {
		reply = TRUE;
                switch (imsg->Class) {
			case IDCMP_REFRESHWINDOW:
				RegRefresh(TRUE);
				break;

                        case IDCMP_CLOSEWINDOW:
				done = TRUE;
                                break;

			case IDCMP_GADGETUP:
				reply = FALSE;
				done=FormHandleGadget(imsg);
				break;

			case IDCMP_RAWKEY:
				AmiHelpKey(imsg,FORMS_PANEL);
				break;
                }
                                                                  
		if (reply)
                       	GF_ReplyIMsg(imsg);
          }
 }

 GF_SetGUIAttr(formGUI, GUI_OpenGUI, FALSE, TAG_DONE);               
 AmiUnlock();
}

/***************************************************
* FormHandleGadget()
*
*	Handles gadget events for this panel
****************************************************/
BOOL FormHandleGadget(struct IntuiMessage *imsg)
{
 BOOL done = FALSE;
 struct Gadget *gad = (struct Gadget *)(imsg->IAddress);
 UWORD code = imsg->Code;
 int val;
 char resp[STRINGSIZE];

 switch (gad->GadgetID) {

	case GID_FOPDEVICE:
		strcpy(localForms.device,((struct StringInfo*)gad->SpecialInfo)->Buffer);
		break;

	case GID_FOPFILE:
		if (AmiGetFile(formGUI,devASL,localForms.device,STRINGSIZE)) {
			GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPDEVICE]->gs_Gadget,
				GTST_String, localForms.device,
				TAG_DONE);
		}
		break;

	case GID_FOPTEMPLATE:
		FormChangeTemplate(code);
		break;

	case GID_FOPFF:
		localForms.userForm.sheet_feed = code;
		break;

   	case GID_FOPCOLS:
        	val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (val > outofbounds.columns || val < 20) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, "Value too large/small");
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPCOLS]->gs_Gadget,myWin);
			return (done);
		}
		else localForms.userForm.columns = val;
        break;
        
	case GID_FOPTOPLINES:
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (val > outofbounds.top_lines) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, "Value too large");
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPTOPLINES]->gs_Gadget,myWin);
		   	return (done);
		}
		else localForms.userForm.top_lines = val;
		break;

	case GID_FOPCHECKLINES:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (val > outofbounds.lines_check) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, "Value too large");
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPCHECKLINES]->gs_Gadget,myWin);
			return (done);
		}
		else localForms.userForm.lines_check = val;
		break;

	case GID_FOPCHECKSPAGE:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (val > outofbounds.checks_page) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, "Value too large");
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPCHECKSPAGE]->gs_Gadget,myWin);
		   	return (done);
		}
		else localForms.userForm.checks_page = val;
		break;

	case GID_FOPPAYMARGIN:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(val,localForms.userForm.pay_width,localForms.userForm.pay_line,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPPAYMARGIN]->gs_Gadget,myWin);
			return (done);
		}
		else localForms.userForm.pay_margin = val;
		break;

	case GID_FOPPAYWIDTH:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(localForms.userForm.pay_margin,val,localForms.userForm.pay_line,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPPAYWIDTH]->gs_Gadget,myWin);
		   	return (done);
		}
		else localForms.userForm.pay_width = val;
		break;

	case GID_FOPPAYLINE:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(localForms.userForm.pay_margin,localForms.userForm.pay_width,val,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPPAYLINE]->gs_Gadget,myWin);
			return (done);
		}
		else localForms.userForm.pay_line = val;
		break;

	case GID_FOPSTRMARGIN:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(val,localForms.userForm.str_width,localForms.userForm.str_line,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPSTRMARGIN]->gs_Gadget,myWin);
		 	return (done);
		}
		else localForms.userForm.str_margin = val;
		break;

	case GID_FOPSTRWIDTH:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(localForms.userForm.str_margin,val,localForms.userForm.str_line,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPSTRWIDTH]->gs_Gadget,myWin);
			return (done);
		}
		else localForms.userForm.str_width = val;
		break;

	case GID_FOPSTRLINE:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(localForms.userForm.str_margin,localForms.userForm.str_width,val,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPSTRLINE]->gs_Gadget,myWin);
		 	return (done);
		}
		else localForms.userForm.str_line = val;
		break;

	case GID_FOPDATEMARGIN:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(val,localForms.userForm.date_width,localForms.userForm.date_line,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPDATEMARGIN]->gs_Gadget,myWin);
		 	return (done);
		}
		else localForms.userForm.date_margin = val;
		break;

	case GID_FOPDATEWIDTH:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(localForms.userForm.date_margin,val,localForms.userForm.date_line,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPDATEWIDTH]->gs_Gadget,myWin);
			return (done);
		}
		else localForms.userForm.date_width = val;
		break;

	case GID_FOPDATELINE:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(localForms.userForm.date_margin,localForms.userForm.date_width,val,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPDATELINE]->gs_Gadget,myWin);
			return (done);
		}
		else localForms.userForm.date_line = val;
		break;

	case GID_FOPAMNTMARGIN:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(val,localForms.userForm.amnt_width,localForms.userForm.amnt_line,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPAMNTMARGIN]->gs_Gadget,myWin);
		 	return (done);
		}
		else localForms.userForm.amnt_margin = val;
		break;

	case GID_FOPAMNTWIDTH:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(localForms.userForm.amnt_margin,val,localForms.userForm.amnt_line,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPAMNTWIDTH]->gs_Gadget,myWin);
		 	return (done);
		}
		else localForms.userForm.amnt_width = val;
		break;

	case GID_FOPAMNTLINE:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(localForms.userForm.amnt_margin,localForms.userForm.amnt_width,val,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPAMNTLINE]->gs_Gadget,myWin);
			return (done);
		}
		else localForms.userForm.amnt_line = val;
		break;

	case GID_FOPMEMOMARGIN:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(val,localForms.userForm.memo_width,localForms.userForm.memo_line,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPMEMOMARGIN]->gs_Gadget,myWin);
		  	return (done);
		}
		else localForms.userForm.memo_margin = val;
		break;

	case GID_FOPMEMOWIDTH:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(localForms.userForm.memo_width,val,localForms.userForm.memo_line,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPMEMOWIDTH]->gs_Gadget,myWin);
		 	return (done);
		}
		else localForms.userForm.memo_width = val;
		break;

	case GID_FOPMEMOLINE:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (!FormCheckField(localForms.userForm.memo_margin,localForms.userForm.memo_width,val,resp)) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, resp);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPMEMOLINE]->gs_Gadget,myWin);
		 	return (done);
		}
		else localForms.userForm.memo_line = val;
		break;

	case GID_FOPVOUCHERTYPE:
		localForms.userForm.voucher_type = code;
	
		 /* disable voucher fields if needed */
 		 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPVOUCHERMARGIN]->gs_Gadget,
			GA_Disabled, (localForms.userForm.voucher_type != VT_LEFTRIGHT),
			TAG_DONE);

 		 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPVOUCHERWIDTH]->gs_Gadget,
			GA_Disabled, (localForms.userForm.voucher_type != VT_LEFTRIGHT),
			TAG_DONE);

		break;

	case GID_FOPVOUCHERMARGIN:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (val > outofbounds.voucher_margin) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, "Value too large");
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPVOUCHERMARGIN]->gs_Gadget,myWin);
			return (done);
		}
		else localForms.userForm.voucher_margin = val;
		break;

	case GID_FOPVOUCHERWIDTH:
		/* test for ridiculous value */
		val = (UWORD)((struct StringInfo*)gad->SpecialInfo)->LongInt;
		if (val > outofbounds.voucher_width) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, "Value too large");
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPVOUCHERWIDTH]->gs_Gadget,myWin);
			return (done);
		}
		else localForms.userForm.voucher_width = val;
		break;

	case GID_FOPTEST:
		if (FormGoodbye(imsg))
			FormTestPrint();
		return (FALSE);
		break;

	case GID_FOPCANCEL:
		done = TRUE;	
		break;
	
	case GID_FOPOK:
		amiChangedItems = TRUE;
		/* verify stuff? FormGoodbye() */
		if (FormGoodbye(imsg) == TRUE) {
			memcpy (&checkForms,&localForms,sizeof(formControl));
			done = TRUE;	
		}
		else return (FALSE);
		break;
 }

 GF_ReplyIMsg(imsg);
 return (done);
}

/****************************************************
* FormInit()
*
*	Set up some globals
*****************************************************/
void FormInit(void)
{
 /* grab active form */
 memcpy (&localForms,&checkForms,sizeof(formControl));

 /* fill in form details */
 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPTEMPLATE]->gs_Gadget,
	GTCY_Active, NUMCHECKFORMS,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPDEVICE]->gs_Gadget,
	GTST_String, localForms.device,
	TAG_DONE);

 FormChangeTemplate(NUMCHECKFORMS);
}

/****************************************************************************
* FormChangeTemplate()
*
*	change the template for the user
*****************************************************************************/
void FormChangeTemplate(int template)
{
 BOOL dis = TRUE;

 if (template < NUMCHECKFORMS) 
 	memcpy(&localForms.userForm, &checkForms.forms[template],sizeof(checkForm));
 else	memcpy(&localForms.userForm, &checkForms.userForm,sizeof(checkForm));

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPFF]->gs_Gadget,
	GTCB_Checked, localForms.userForm.sheet_feed,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPPAYMARGIN]->gs_Gadget,
	GTIN_Number, localForms.userForm.pay_margin,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPPAYWIDTH]->gs_Gadget,
	GTIN_Number, localForms.userForm.pay_width,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPPAYLINE]->gs_Gadget,
	GTIN_Number, localForms.userForm.pay_line,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPSTRMARGIN]->gs_Gadget,
	GTIN_Number, localForms.userForm.str_margin,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPSTRWIDTH]->gs_Gadget,
	GTIN_Number, localForms.userForm.str_width,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPSTRLINE]->gs_Gadget,
	GTIN_Number, localForms.userForm.str_line,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPDATEMARGIN]->gs_Gadget,
	GTIN_Number, localForms.userForm.date_margin,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPDATEWIDTH]->gs_Gadget,
	GA_Disabled, TRUE,
	GTIN_Number, localForms.userForm.date_width,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPDATELINE]->gs_Gadget,
	GTIN_Number, localForms.userForm.date_line,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPAMNTMARGIN]->gs_Gadget,
	GTIN_Number, localForms.userForm.amnt_margin,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPAMNTWIDTH]->gs_Gadget,
	GTIN_Number, localForms.userForm.amnt_width,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPAMNTLINE]->gs_Gadget,
	GTIN_Number, localForms.userForm.amnt_line,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPMEMOMARGIN]->gs_Gadget,
	GTIN_Number, localForms.userForm.memo_margin,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPMEMOWIDTH]->gs_Gadget,
	GTIN_Number, localForms.userForm.memo_width,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPMEMOLINE]->gs_Gadget,
	GTIN_Number, localForms.userForm.memo_line,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPVOUCHERMARGIN]->gs_Gadget,
	GTIN_Number, localForms.userForm.voucher_margin,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPVOUCHERWIDTH]->gs_Gadget,
	GTIN_Number, localForms.userForm.voucher_width,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPVOUCHERTYPE]->gs_Gadget,
	GTCY_Active, localForms.userForm.voucher_type,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPCHECKSPAGE]->gs_Gadget,
	GTIN_Number, localForms.userForm.checks_page,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPCHECKLINES]->gs_Gadget,
	GTIN_Number, localForms.userForm.lines_check,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPTOPLINES]->gs_Gadget,
	GTIN_Number, localForms.userForm.top_lines,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPCOLS]->gs_Gadget,
	GTIN_Number, localForms.userForm.columns,
	TAG_DONE);

 /* disable voucher fields if needed */
 if (localForms.userForm.voucher_type == VT_LEFTRIGHT)
	dis = FALSE;

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPVOUCHERMARGIN]->gs_Gadget,
	GA_Disabled, dis,
	TAG_DONE);

 GF_SetGadgetAttrs (formGUI, FP_FormSpecs[GID_FOPVOUCHERWIDTH]->gs_Gadget,
	GA_Disabled, dis,
	TAG_DONE);
}

/****************************************************************
* FormTestPrint()
*
*	Test-print a form 
*****************************************************************/
void FormTestPrint(void)
{
 int bogus = 1;
 FILE *out;
 BOOL fail = FALSE;
 entryNode entry;
 filterNode filt;
 UBYTE decim = usrAccount.decimal;

 strcpy(entry.name,"PAYEE FIELD");
 strcpy(entry.memo,"MEMO FIELD");
 strcpy(entry.category,"CATEGORY");
 entry.flags = CLEARED | TAXDEDUCT | RECONCILED;
 entry.type = CHECKTYPE;
 entry.check = 1;
 entry.amount = 12345;
 memcpy(&entry.date,&currDate,sizeof(dateType));

 filt.entry = &entry;


 /* now open the check device */
 if ( (out = fopen(localForms.device,"w")) == NULL) {
	AmiAnnounce("Device Failure.\nCannot open device.");
	return;
 }

 GF_LockGUI(formGUI);

 usrAccount.decimal = 2;

 checkImage = PrintCheckAlloc(&localForms.userForm);
 if (checkImage) {
	 fail = !PrintItem(out,&filt,&localForms, TRUE,TRUE, &bogus);
	free (checkImage);
 }
 else AmiAnnounce("Cannot allocate RAM for check print\n");

 usrAccount.decimal = decim;

 GF_UnlockGUI(formGUI);
 fclose(out);

 if (fail) 
	AmiAnnounce("Printer failure.\nOperation cancelled.");

}

/*********************************************************
* FormCheckField()
*
*	Validates user input
**********************************************************/
BOOL FormCheckField(ULONG margin, ULONG width, ULONG line, char *resp)
{
 ULONG lines = localForms.userForm.lines_check;

 /* check line */
 if (line + 1 > lines) {
	strcpy(resp,"Field on illegal line.\n");
	return (FALSE);
 }

 /* check width */
 if (width > MAXCHECKCOLS - margin) {
	strcpy(resp,"Field too wide or margin off.\n");
	return (FALSE);
 }

 /* check stupid width */
 if (width < 5) {
	strcpy(resp,"Field width too small.\n");
	return (FALSE);
 }

 /* check against items too large */
 if (width > MAXCHECKCOLS) {
	strcpy(resp,"Field width too large.\n");
	return (FALSE);
 }

 /* this should never happen, but... */
 if (margin > MAXCHECKCOLS) {
	strcpy(resp,"Field margin too far to right.\n");
	return (FALSE);
 }

 return (TRUE);
}

/*******************************************************
* FormGoodbye()
*
* 	Verifies user input before accepting an OK
*	_or_ a TEST.
********************************************************/
BOOL FormGoodbye(struct IntuiMessage *imsg)
{
 ULONG val;
 char resp[STRINGSIZE];

 val = (UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPCHECKLINES]->gs_Gadget)->SpecialInfo)->LongInt;
 if (val > outofbounds.lines_check) {
	DisplayBeep(myWin->WScreen);
	DataAnnounce(formGUI, "Lines/Check Value too large");
	GF_ReplyIMsg(imsg);
	DataSitNSpin(FP_FormSpecs[GID_FOPCHECKLINES]->gs_Gadget,myWin);
	return (FALSE);
 }
 else localForms.userForm.lines_check = val;

 val = (UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPCOLS]->gs_Gadget)->SpecialInfo)->LongInt;
 if (val > outofbounds.columns || val < 20) {
	DisplayBeep(myWin->WScreen);
	DataAnnounce(formGUI, "Columns value too large/small");
	GF_ReplyIMsg(imsg);
	DataSitNSpin(FP_FormSpecs[GID_FOPCOLS]->gs_Gadget,myWin);
	return (FALSE);
 }
 else localForms.userForm.columns = val; 
 
 val = (UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPCHECKSPAGE]->gs_Gadget)->SpecialInfo)->LongInt;
 if (val > outofbounds.checks_page) {
	DisplayBeep(myWin->WScreen);
	DataAnnounce(formGUI, "Checks/Page Value too large");
	GF_ReplyIMsg(imsg);
	DataSitNSpin(FP_FormSpecs[GID_FOPCHECKSPAGE]->gs_Gadget,myWin);
	return (FALSE);
 }
 else localForms.userForm.checks_page = val;
	
 /* grab all payfield data */
 localForms.userForm.pay_margin = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPPAYMARGIN]->gs_Gadget)->SpecialInfo)->LongInt;
 localForms.userForm.pay_width = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPPAYWIDTH]->gs_Gadget)->SpecialInfo)->LongInt;
 localForms.userForm.pay_line = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPPAYLINE]->gs_Gadget)->SpecialInfo)->LongInt;

 if (!FormCheckField(localForms.userForm.pay_margin,localForms.userForm.pay_width,localForms.userForm.pay_line,resp)) {
	DisplayBeep(myWin->WScreen);
	DataAnnounce(formGUI, "Payee field illegal.");
	GF_ReplyIMsg(imsg);
	DataSitNSpin(FP_FormSpecs[GID_FOPPAYMARGIN]->gs_Gadget,myWin);
	return (FALSE);
 }
 
 /* grab all memo data */
 localForms.userForm.memo_margin = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPMEMOMARGIN]->gs_Gadget)->SpecialInfo)->LongInt;
 localForms.userForm.memo_width = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPMEMOWIDTH]->gs_Gadget)->SpecialInfo)->LongInt;
 localForms.userForm.memo_line = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPMEMOLINE]->gs_Gadget)->SpecialInfo)->LongInt;

 if (!FormCheckField(localForms.userForm.memo_margin,localForms.userForm.memo_width,localForms.userForm.memo_line,resp)) {
	DisplayBeep(myWin->WScreen);
	DataAnnounce(formGUI, "Memo field illegal.");
	GF_ReplyIMsg(imsg);
	DataSitNSpin(FP_FormSpecs[GID_FOPMEMOMARGIN]->gs_Gadget,myWin);
	return (FALSE);
 }

 /* grab all amntstr stuff */
 localForms.userForm.str_margin = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPSTRMARGIN]->gs_Gadget)->SpecialInfo)->LongInt;
 localForms.userForm.str_width = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPSTRWIDTH]->gs_Gadget)->SpecialInfo)->LongInt;
 localForms.userForm.str_line = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPSTRLINE]->gs_Gadget)->SpecialInfo)->LongInt;

 if (!FormCheckField(localForms.userForm.str_margin,localForms.userForm.str_width,localForms.userForm.str_line,resp)) {
	DisplayBeep(myWin->WScreen);
	DataAnnounce(formGUI, "Amount string field illegal.");
	GF_ReplyIMsg(imsg);
	DataSitNSpin(FP_FormSpecs[GID_FOPSTRMARGIN]->gs_Gadget,myWin);
	return (FALSE);
 }

 /* grab all date stuff */
 localForms.userForm.date_margin = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPDATEMARGIN]->gs_Gadget)->SpecialInfo)->LongInt;
 localForms.userForm.date_width = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPDATEWIDTH]->gs_Gadget)->SpecialInfo)->LongInt;
 localForms.userForm.date_line = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPDATELINE]->gs_Gadget)->SpecialInfo)->LongInt;

 if (!FormCheckField(localForms.userForm.date_margin,localForms.userForm.date_width,localForms.userForm.date_line,resp)) {
	DisplayBeep(myWin->WScreen);
	DataAnnounce(formGUI, "Date field illegal.");
	GF_ReplyIMsg(imsg);
	DataSitNSpin(FP_FormSpecs[GID_FOPDATEMARGIN]->gs_Gadget,myWin);
	return (FALSE);
 }

 /* grab all amnt stuff */
 localForms.userForm.amnt_margin = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPAMNTMARGIN]->gs_Gadget)->SpecialInfo)->LongInt;
 localForms.userForm.amnt_width = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPAMNTWIDTH]->gs_Gadget)->SpecialInfo)->LongInt;
 localForms.userForm.amnt_line = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPAMNTLINE]->gs_Gadget)->SpecialInfo)->LongInt;

 if (!FormCheckField(localForms.userForm.amnt_margin,localForms.userForm.amnt_width,localForms.userForm.amnt_line,resp)) {
	DisplayBeep(myWin->WScreen);
	DataAnnounce(formGUI, "Amount field illegal.");
	GF_ReplyIMsg(imsg);
	DataSitNSpin(FP_FormSpecs[GID_FOPAMNTMARGIN]->gs_Gadget,myWin);
	return (FALSE);
 }

 /* test top lines field */	
 localForms.userForm.top_lines = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPTOPLINES]->gs_Gadget)->SpecialInfo)->LongInt;
 if (localForms.userForm.top_lines > outofbounds.top_lines) {
			DisplayBeep(myWin->WScreen);
			DataAnnounce(formGUI, "Top Lines: Value too large");
			GF_ReplyIMsg(imsg);
			DataSitNSpin(FP_FormSpecs[GID_FOPTOPLINES]->gs_Gadget,myWin);
		 	return (FALSE);
 }

 /* verify voucher stuff */
 localForms.userForm.voucher_margin = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPVOUCHERMARGIN]->gs_Gadget)->SpecialInfo)->LongInt;
 localForms.userForm.voucher_width = 
		(UWORD)((struct StringInfo*)(FP_FormSpecs[GID_FOPVOUCHERWIDTH]->gs_Gadget)->SpecialInfo)->LongInt;

 if (localForms.userForm.voucher_type) {
 	if (localForms.userForm.voucher_margin > outofbounds.voucher_margin ||
     			localForms.userForm.voucher_width > outofbounds.voucher_width) {
		DisplayBeep(myWin->WScreen);
		DataAnnounce(formGUI, "Voucher field: illegal width or margin");
		GF_ReplyIMsg(imsg);
		DataSitNSpin(FP_FormSpecs[GID_FOPAMNTMARGIN]->gs_Gadget,myWin);
		return (FALSE);
	}
 }

 /* grab file device */
 strcpy(localForms.device, 
	((struct StringInfo *)(FP_FormSpecs[GID_FOPDEVICE]->gs_Gadget)->SpecialInfo)->Buffer);

 return (TRUE);
}
