/* newTempPanel.c 
 *
 *  defines the GUIFront characteristics of the template data-entry panel 
 */

#include <stdio.h>  
#include <intuition/gadgetclass.h>
#include "amiCheck.h"
#include "regGadget.h"
#include "dataBase.h"
#include "newtempPanel.h"
#include "edittempPanel.h"
#include "qmemoPanel.h"
#include "qamntPanel.h"
#include "qnamePanel.h"
#include <string.h>
#include <exec/memory.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>

BOOL NewHandleGadget(struct IntuiMessage *);
BOOL NewTempFill(templateNode *);
BOOL NewGoodbye(struct IntuiMessage *,templateNode *);
void NewTempStrip(void);

BOOL ntAttach = FALSE;
char temporigstr[STRINGSIZE];
ExtErrorData NewTempExtData;
UWORD newcatActive;
templateNode mytemp, *retval, *dest;
GUIFront *newGUI;
struct Window *newWin;
static char amntstr[AMNTSIZE];
BOOL fixamnt;

/* quick configure of some gadgets */

STRPTR temptypelabels[] =
{
	"Check",
	"Withdrawal",
	"Deposit",
	NULL,
};

struct TagItem typeCycleTags[] =
{
	{GTCY_Labels, temptypelabels},
	{TAG_DONE},
};


/* define gadgetspec */
GadgetSpec NPgadgetspecs[] = 
{
	{CYCLE_KIND,15,1,{0,0,0,0,"_Kind",NULL,GID_NPTYPE,
		PLACETEXT_LEFT},typeCycleTags,GS_DefaultTags,GS_NoWidthExtend},

	{STRING_KIND,20,1,{0,0,0,0,"_ID Name",NULL,GID_NPTYPENAME,
		PLACETEXT_LEFT},strTempTags,GS_DefaultTags,GS_NoWidthExtend},

        {STRING_KIND,40,1,{0,0,0,0,"_Name",NULL,GID_NPNAME,
                PLACETEXT_LEFT}, strNameTags,GS_DefaultTags},
 
        {STRING_KIND,40,1,{0,0,0,0,"_Memo",NULL,GID_NPMEMO,
                PLACETEXT_LEFT}, strMemoTags,GS_DefaultTags},
 
        {STRING_KIND,15,1,{0,0,0,0,"_Amount",NULL,GID_NPAMNT,
                PLACETEXT_LEFT}, strAmntTags,GS_DefaultTags,GS_NoWidthExtend},
           
        {CHECKBOX_KIND,0,0,{0,0,0,0,"Mark _Printed",NULL,GID_NPPRINTED,
                PLACETEXT_RIGHT}, NULL,GS_DefaultTags},

        {CHECKBOX_KIND,0,0,{0,0,0,0,"_Tax Deductible",NULL,GID_NPTAX,
                PLACETEXT_RIGHT}, NULL,GS_DefaultTags},

        {CHECKBOX_KIND,0,0,{0,0,0,0,"Mark _Voided",NULL,GID_NPVOIDED,
                PLACETEXT_RIGHT}, NULL,GS_DefaultTags},

        {LISTVIEW_KIND,  30,4,{0,0,0,0,NULL,NULL,GID_NPCATEGORY,
                PLACETEXT_ABOVE}, ListView, GS_DefaultTags},
          
        {BUTTON_KIND,0,0,{0,0,0,0,"_OK", NULL, GID_NPOK, 
                PLACETEXT_IN}, NULL, GS_DefaultTags},
                              
        {BUTTON_KIND,0,0,{0,0,0,0,"_Cancel", NULL, GID_NPCANCEL, 
                PLACETEXT_IN}, NULL, GS_DefaultTags},

        {GETALT_KIND, 0,0,{0,0,0,0,NULL,NULL,GID_NPMEMOLIST,
                PLACETEXT_LEFT}, MiscButton, GS_DefaultTags}, 

        {GETALT_KIND, 0,0,{0,0,0,0,NULL,NULL,GID_NPAMNTLIST,
                PLACETEXT_LEFT}, MiscButton, GS_DefaultTags}, 

        {GETALT_KIND, 0,0,{0,0,0,0,NULL,NULL,GID_NPNAMELIST,
                PLACETEXT_LEFT}, MiscButton, GS_DefaultTags}, 
};

/* set up array of pointers to our specs */
GadgetSpec *NP_EnterSpecs[] =
{
        &NPgadgetspecs[0],
        &NPgadgetspecs[1],
        &NPgadgetspecs[2],
        &NPgadgetspecs[3],
        &NPgadgetspecs[4],
        &NPgadgetspecs[5],
        &NPgadgetspecs[6],
        &NPgadgetspecs[7],
        &NPgadgetspecs[8],
        &NPgadgetspecs[9],
        &NPgadgetspecs[10],
	&NPgadgetspecs[11],
        &NPgadgetspecs[12],
	&NPgadgetspecs[13],
        NULL,
};


/* define the layout of this panel */
ULONG NP_EnterPanel[] =
{
   GUIL_Flags, GUILF_PropShare | GUILF_EqualWidth,
      
   GUIL_HorizGroup, 1,
        GUIL_Flags, GUILF_PropShare, /* | GUILF_LabelAlign,*/
        GUIL_FrameType, GUILFT_Recess,
        
                GUIL_VertGroup,1,
			GUIL_HorizGroup, 1,
				GUIL_VertGroup,1,
                        		GUIL_Flags, GUILF_PropShare | GUILF_LabelAlign | GUILF_EqualWidth,
                   
					GUIL_GadgetSpecID, GID_NPTYPE,
					GUIL_GadgetSpecID, GID_NPTYPENAME,

					GUIL_HorizGroup,0,
						GUIL_GadgetSpecID, GID_NPAMNT,
						GUIL_GadgetSpecID, GID_NPAMNTLIST,
					TAG_DONE,
					GUIL_HorizGroup,0,
       						GUIL_GadgetSpecID, GID_NPNAME,
						GUIL_GadgetSpecID, GID_NPNAMELIST,
					TAG_DONE,
					GUIL_HorizGroup,0,
                        			GUIL_GadgetSpecID, GID_NPMEMO,
						GUIL_GadgetSpecID, GID_NPMEMOLIST,
					TAG_DONE,
				TAG_DONE,
			TAG_DONE,     

			GUIL_HorizGroup, 1,
				GUIL_Flags, GUILF_PropShare | GUILF_EqualHeight,

				GUIL_VertGroup,1,
					GUIL_FrameType, GUILFT_Ridge,
					GUIL_FrameHeadline, "Category",

					GUIL_GadgetSpecID, GID_NPCATEGORY,

				TAG_DONE,

				GUIL_VertGroup, 1,
					GUIL_FrameType, GUILFT_Ridge,
					GUIL_FrameHeadline,"Flags",
					GUIL_GadgetSpecID, GID_NPTAX,
					GUIL_GadgetSpecID, GID_NPVOIDED,
       	  				GUIL_GadgetSpecID, GID_NPPRINTED,
            				
				TAG_DONE,
			TAG_DONE,

		TAG_DONE,
		     
    TAG_DONE,
    
    GUIL_HorizGroup,1,
        GUIL_Flags, GUILF_EqualSize | GUILF_EqualWidth,
        
           GUIL_GadgetSpecID, GID_NPOK,
           GUIL_GadgetSpecID, GID_NPCANCEL,
           
    TAG_DONE,
                  
TAG_DONE,
};



/*********************************************************************
* NewTempGUI()
*
*	GUI for this panel
**********************************************************************/
templateNode *NewTempGUI(templateNode *def, char *wint)
{
 BOOL noreply,done = FALSE;
 UWORD ordinal;
 categoryNode *temp;
 ULONG signal;
     
   GF_LockGUI(edittempGUI);

   GF_SetGUIAttr(newGUI, GUI_OpenGUI, TRUE, TAG_DONE);
   NewTempStrip();
   GF_GetGUIAttr(newGUI, GUI_Window, &newWin, TAG_DONE);
   SetWindowTitles(newWin,wint,(UBYTE *)-1);
   if (NewTempFill(def) != TRUE) done = TRUE;
  		
		newcatActive = 0;
		retval = NULL;

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

                    /* Wait for an event to occur */
                    signal = GF_Wait(guiapp,AmigaGuideSignal(agc));

                    /* 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.
                     */

		    if (signal & AmigaGuideSignal(agc)) {
			AmiHelpMsg();
			continue;
		    }

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

                                case IDCMP_CLOSEWINDOW:
					retval=NULL;
                                        done = TRUE;
                                        break;

				case IDCMP_RAWKEY:
					if (GF_ProcessListView(newGUI,NP_EnterSpecs[GID_NPCATEGORY],
					    imsg,&ordinal)) {
						newcatActive = ordinal;
						temp = (categoryNode *)DataOrd2Node(&categories,newcatActive);
						strncpy(mytemp.template.category,temp->node.ln_Name,CATNAMESIZE);
					}
					else AmiHelpKey(imsg,NEWTEMP_PANEL);	
					break;
	
				case IDCMP_GADGETUP:
					noreply = FALSE;
					done=NewHandleGadget(imsg);
					break;
                        }
                                     
                        if (noreply)   GF_ReplyIMsg(imsg);
                    }
 
               }

   NewTempStrip();
   GF_SetGUIAttr(newGUI, GUI_OpenGUI, FALSE, TAG_DONE);
   GF_UnlockGUI(edittempGUI);

   return (retval);
}

/***************************************************
* NewHandleGadget()
*
*	Handles gadget events for this panel
****************************************************/
BOOL  NewHandleGadget(struct IntuiMessage *imsg)
{
 struct Gadget *gad = (struct Gadget *)(imsg->IAddress);
 UWORD code = imsg->Code;
 BOOL done = FALSE;
 struct Node *temp;
 memoNode *dm;
 amntNode *da;
 nameNode *dn;
 static char newamntstr[AMNTSIZE];

 switch (gad->GadgetID) {

	case GID_NPMEMOLIST:
		if (QMemoGUI(newGUI)) {
			dm=(memoNode*)DataOrd2Node(&memolist,qmemoSel);
			strcpy(mytemp.template.memo,dm->memoStr);
			GF_SetGadgetAttrs(newGUI,NP_EnterSpecs[GID_NPMEMO]->gs_Gadget,
				GTST_String,mytemp.template.memo,
				TAG_DONE);
		}
		break;

	case GID_NPAMNTLIST:
		if (QAmntGUI(newGUI)) {
			da=(amntNode*)DataOrd2Node(&amntlist,qamntSel);
			strcpy(newamntstr,da->amntStr);
			GF_SetGadgetAttrs(newGUI,NP_EnterSpecs[GID_NPAMNT]->gs_Gadget,
				GTST_String,newamntstr,
				TAG_DONE);
		}
		break;

	case GID_NPNAMELIST:
		if (QNameGUI(newGUI)) {
			dn=(nameNode*)DataOrd2Node(&namelist,qnameSel);
			strcpy(mytemp.template.name,dn->nameStr);
			GF_SetGadgetAttrs(newGUI,NP_EnterSpecs[GID_NPNAME]->gs_Gadget,
				GTST_String,mytemp.template.name,
				TAG_DONE);
		}
		break;


	case GID_NPCATEGORY:
		newcatActive = code;
		temp = DataOrd2Node(&categories,newcatActive);
		strncpy(mytemp.template.category,temp->ln_Name,CATNAMESIZE);
		break;

	case GID_NPTYPE:
		mytemp.template.type = (WORD)code;
		GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPPRINTED]->gs_Gadget,
			GA_Disabled, (mytemp.template.type != CHECKTYPE)?TRUE:FALSE,
			TAG_DONE);

		GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPVOIDED]->gs_Gadget,
			GA_Disabled,( mytemp.template.type != CHECKTYPE)?TRUE:FALSE,
			TAG_DONE);
		break;

	case GID_NPTYPENAME:
		/* is it simply the original name? */
		if (temporigstr[0] != NULL && 
		    (strcmpi(temporigstr,((struct StringInfo *)gad->SpecialInfo)->Buffer) == 0) ) {
			strncpy(mytemp.tempname,((struct StringInfo *)gad->SpecialInfo)->Buffer, TEMPNAMESIZE);
		}

		else {
			if (DataIsUnique(newGUI, &testtemps,((struct StringInfo *)gad->SpecialInfo)->Buffer,TRUE,
				"Template ID name already exists\nor is invalid.\n")==TRUE) {
				strncpy(mytemp.tempname,((struct StringInfo *)gad->SpecialInfo)->Buffer, TEMPNAMESIZE);
			}
			else {
				GF_ReplyIMsg(imsg);
				DataSitNSpin(NP_EnterSpecs[GID_NPTYPENAME]->gs_Gadget,newWin);
		   		return (done);
			}
		}
		break;

	case GID_NPNAME:
		strncpy(mytemp.template.name,((struct StringInfo *)gad->SpecialInfo)->Buffer, STRINGSIZE);
		break;

	case GID_NPMEMO:
		strncpy(mytemp.template.memo,((struct StringInfo *)gad->SpecialInfo)->Buffer, STRINGSIZE);
		break;

	case GID_NPAMNT:
		
		/* special case return early.... activated gadget */
		if (!DataVerifyAmnt(((struct StringInfo*)gad->SpecialInfo)->Buffer,newamntstr) ) {
			DisplayBeep(newWin->WScreen);
			DataAnnounceAmount(newGUI);
			GF_ReplyIMsg(imsg);
			DataSitNSpin(NP_EnterSpecs[GID_NPAMNT]->gs_Gadget,newWin);
		  	return (done);
		}
 		else {
			DataStoreAmnt(&mytemp.template.amount,newamntstr );
			GF_SetGadgetAttrs(newGUI,NP_EnterSpecs[GID_NPAMNT]->gs_Gadget,
				GTST_String,newamntstr,
				TAG_DONE);
		}
		break;
	
	case GID_NPVOIDED:
		if (code)
			mytemp.template.flags |= VOIDED;
		else 	mytemp.template.flags &= !VOIDED;
		break;

	case GID_NPPRINTED:
		if (code)
			mytemp.template.flags |= PRINTED;
		else	mytemp.template.flags &= ~PRINTED;
		break;

	case GID_NPTAX:
		if (code)
			mytemp.template.flags |= TAXDEDUCT;
		else 	mytemp.template.flags &= ~TAXDEDUCT;
		break;

	case GID_NPCANCEL:
		retval = NULL;
		done=TRUE;
		break;

	case GID_NPOK:
		if (NewGoodbye(imsg, &mytemp)) {
			retval = &mytemp;
			done = TRUE;
		}
		else return (FALSE);
		break;
 }

 GF_ReplyIMsg(imsg);
 return (done);
}

/***************************************************
* NewTempFill()
*
*	Fills in default if editing node
****************************************************/
BOOL NewTempFill(templateNode *def)
{
int active;

 dest = def;

 NewTempStrip();
 if (def != NULL) {
	strcpy(temporigstr,def->tempname);
	memcpy(&mytemp,def,sizeof(templateNode));
	DataBuildAmnt(FALSE,&mytemp.template.amount,amntstr);

	/* update gfx */
	GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPTYPE]->gs_Gadget,
		GTCY_Active,def->template.type,
		TAG_DONE);

	GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPTYPENAME]->gs_Gadget,
		GTST_String,def->tempname,
		TAG_DONE);

	GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPNAME]->gs_Gadget,
		GTST_String,def->template.name,
		TAG_DONE);

	GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPMEMO]->gs_Gadget,
		GTST_String,def->template.memo,
		TAG_DONE);

	GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPAMNT]->gs_Gadget,
		GTST_String,amntstr,
		TAG_DONE);

	GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPPRINTED]->gs_Gadget,
		GTCB_Checked,(def->template.flags & PRINTED)?1:0,
		TAG_DONE);

	GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPVOIDED]->gs_Gadget,
		GTCB_Checked,(def->template.flags & VOIDED)?1:0,
		TAG_DONE);

	GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPTAX]->gs_Gadget,
		GTCB_Checked,(def->template.flags & TAXDEDUCT)?1:0,
		TAG_DONE);

	active =  DataNode2Ord(&categories,def->template.category);

	GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPCATEGORY]->gs_Gadget,
		GTLV_Labels, &categories,
		GTLV_Selected,active,
		GTLV_MakeVisible,active,
		TAG_DONE);						  
 }
 else  {
	temporigstr[0]=NULL;
	memset(&mytemp, 0, sizeof(templateNode));
	GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPAMNT]->gs_Gadget,
		GTST_String,"0.00",
		TAG_DONE);

	GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPCATEGORY]->gs_Gadget,
		GTLV_Labels, &categories,
		GTLV_Selected, 0,
		GTLV_MakeVisible,0,
		TAG_DONE);

 }

 /* comment out voided & printed if this is not a check! */
 GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPPRINTED]->gs_Gadget,
	GA_Disabled, (mytemp.template.type == CHECKTYPE)?FALSE:TRUE,
	TAG_DONE);

 GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPVOIDED]->gs_Gadget,
	GA_Disabled, (mytemp.template.type == CHECKTYPE)?FALSE:TRUE,
	TAG_DONE);

 ntAttach=TRUE;
 return (TRUE);
}

/**************************************************************
* NewGoodbye()
*
*	Ensures correct data in strings
***************************************************************/
BOOL NewGoodbye(struct IntuiMessage *imsg, templateNode *temp)
{
 BOOL retval = TRUE;
 char *grab;
 char newamntstr[AMNTSIZE+1];
 categoryNode *tempcat;

 /* verify data from "special" strings */
 grab = ((struct StringInfo *)(NP_EnterSpecs[GID_NPAMNT]->gs_Gadget)->SpecialInfo)->Buffer;
 if (!DataVerifyAmnt(grab,newamntstr) ) {
	DisplayBeep(newWin->WScreen);
	DataAnnounceAmount(newGUI);
	GF_ReplyIMsg(imsg);
	DataSitNSpin(NP_EnterSpecs[GID_NPAMNT]->gs_Gadget,newWin);
	return (FALSE);
 }
 else {
	DataStoreAmnt(&temp->template.amount,newamntstr );
 }

 grab = ((struct StringInfo *)(NP_EnterSpecs[GID_NPTYPENAME]->gs_Gadget)->SpecialInfo)->Buffer;

 /* don't test if id unchanged */
 if (temporigstr[0] == NULL || strcmpi(temporigstr,temp->tempname)!= 0) {

 	if (DataIsUnique(newGUI, &testtemps,grab,TRUE,
    	"Template ID name already exists\nor is invalid.\n")==TRUE) {
		strncpy(temp->tempname,grab, TEMPNAMESIZE);
 	}
 	else {
		GF_ReplyIMsg(imsg);
		DataSitNSpin(NP_EnterSpecs[GID_NPTYPENAME]->gs_Gadget,newWin);
		return (FALSE);
 	}
 }

 /* pull data from each string */
 grab = ((struct StringInfo *)(NP_EnterSpecs[GID_NPNAME]->gs_Gadget)->SpecialInfo)->Buffer;
 strncpy(temp->template.name,grab, STRINGSIZE);

 grab = ((struct StringInfo *)(NP_EnterSpecs[GID_NPMEMO]->gs_Gadget)->SpecialInfo)->Buffer;
 strncpy(temp->template.memo,grab, STRINGSIZE);

 /* check for non-check and void/print */
 if (temp->template.type != CHECKTYPE) {
	temp->template.flags &= ~(VOIDED|PRINTED);
 }

 /* grab category string and stuff it in! */
 tempcat = (categoryNode *)DataOrd2Node(&categories,newcatActive);
 strncpy(temp->template.category,tempcat->node.ln_Name,CATNAMESIZE); 

 return (retval);
}

/**********************************************************
* NewTempStrip()
* 
*  Strip away labels
***********************************************************/
void NewTempStrip()
{
  if (ntAttach == TRUE) {
        GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPCATEGORY]->gs_Gadget,
		                GTLV_Selected, ~0,
                        TAG_DONE);

        GF_SetGadgetAttrs (newGUI, NP_EnterSpecs[GID_NPCATEGORY]->gs_Gadget,
		                GTLV_Labels, ~0,
                        TAG_DONE);
	        
        ntAttach = FALSE;
  }
}
