/* amntPanel.c 
 *
 *  defines the GUIFront characteristics of the amnt panel 
 */
  
#include <exec/types.h>
#include <exec/lists.h>
#include <exec/nodes.h>
#include <exec/memory.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/intuition_protos.h>
#include <stdio.h>  
#include <intuition/gadgetclass.h>
#include "amiCheck.h"
#include "dataBase.h"
#include "amntPanel.h"
#include "regGadget.h"
#include "qamntPanel.h"
#include <string.h>


/* prototypes */
BOOL AmntHandleGadget(struct IntuiMessage *);
void AmntInit(void);
void AmntDisableGads(BOOL);

struct List tempamnts;
BOOL updateamnt,amntretval;
ExtErrorData AmntExtData;
GUIFront *amntGUI;
UWORD	amntlistActive;
struct Window *amntWin;
BOOL updateamnts = FALSE;

/* quick configure of some gadgets */
extern struct TagItem amntList[];

/* define gadgetspec */
GadgetSpec AMNTgadgetspecs[] = 
{
	{LISTVIEW_KIND,AMNTSIZE+5,8, {0,0,0,0,NULL,NULL,GID_AMNTLIST,
		PLACETEXT_ABOVE},amntList,GS_DefaultTags},

        {BUTTON_KIND,0,0,{0,0,0,0,"_New", NULL, GID_AMNTNEW,         
                PLACETEXT_IN}, NULL, GS_DefaultTags},

        {BUTTON_KIND,0,0,{0,0,0,0,"_Remove", NULL, GID_AMNTDEL,         
                PLACETEXT_IN}, NULL, GS_DefaultTags},

        {STRING_KIND,20,0,{0,0,0,0,NULL, NULL, GID_AMNTEDIT,         
                PLACETEXT_IN}, NULL, GS_DefaultTags},

        {BUTTON_KIND,0,0,{0,0,0,0,"_Up", NULL, GID_AMNTUP,         
                PLACETEXT_IN}, NULL, GS_DefaultTags},

        {BUTTON_KIND,0,0,{0,0,0,0,"_Down", NULL, GID_AMNTDOWN,         
                PLACETEXT_IN}, NULL, GS_DefaultTags},

        {BUTTON_KIND,0,0,{0,0,0,0,"_Top", NULL, GID_AMNTTOP,         
                PLACETEXT_IN}, NULL, GS_DefaultTags},

        {BUTTON_KIND,0,0,{0,0,0,0,"_Bottom", NULL, GID_AMNTBOTTOM,         
                PLACETEXT_IN}, NULL, GS_DefaultTags},

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

        {BUTTON_KIND,0,0,{0,0,0,0,"_Cancel", NULL, GID_AMNTCANCEL,        
                PLACETEXT_IN}, NULL, GS_DefaultTags},
 
};

struct TagItem amntList[] =
{
        {GTLV_ShowSelected, &AMNTgadgetspecs[GID_AMNTEDIT]},
                /*
	{GTLV_Labels, ~0},
	{GTLV_Selected,~0},
        */
        {TAG_DONE},
};

/* set up array of pointers to our specs */
GadgetSpec *A_AmntSpecs[] =
{
        &AMNTgadgetspecs[0],
        &AMNTgadgetspecs[1],
        &AMNTgadgetspecs[2],
        &AMNTgadgetspecs[3],
        &AMNTgadgetspecs[4],
        &AMNTgadgetspecs[5],
        &AMNTgadgetspecs[6],
        &AMNTgadgetspecs[7],
        &AMNTgadgetspecs[8],
        &AMNTgadgetspecs[9],
        NULL,
};


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

   GUIL_HorizGroup, 1,
        GUIL_Flags, GUILF_PropShare,
	GUIL_FrameType, GUILFT_Recess,
        
	GUIL_VertGroup, 1,

		GUIL_HorizGroup,1,
			GUIL_FrameType, GUILFT_Ridge,
			GUIL_GadgetSpecID, GID_AMNTLIST,

                	GUIL_VertGroup,1,
                        	GUIL_Flags, GUILF_PropShare | GUILF_EqualWidth | GUILF_EqualHeight,
                                              
				GUIL_GadgetSpecID, GID_AMNTUP,
				GUIL_GadgetSpecID, GID_AMNTDOWN,
				GUIL_GadgetSpecID, GID_AMNTTOP,
				GUIL_GadgetSpecID, GID_AMNTBOTTOM,
                	TAG_DONE,

		TAG_DONE,
	
		GUIL_HorizGroup,1,
			GUIL_FrameType, GUILFT_Ridge,
			GUIL_Flags, GUILF_EqualSize | GUILF_EqualWidth,
			GUIL_GadgetSpecID, GID_AMNTDEL,
			GUIL_GadgetSpecID, GID_AMNTNEW,
		TAG_DONE,

	TAG_DONE,
        
    TAG_DONE,
    
    GUIL_HorizGroup,1,
        GUIL_Flags, GUILF_EqualSize | GUILF_EqualWidth,
        
           GUIL_GadgetSpecID, GID_AMNTOK,
           GUIL_GadgetSpecID, GID_AMNTCANCEL,
           
    TAG_DONE,   
           
TAG_DONE,
};


/****************************************************
* AmntGUI ()
*
*	Creates the GUI for the edit temp panel.
*****************************************************/
BOOL AmntGUI(void)
{
 BOOL done = FALSE;
 BOOL noreply;
 UWORD ordinal;
 ULONG signal;
     
   AmiLock();

   /* install temporary list */
   NewList(&tempamnts);
   DataCopyList(&amntlist, &tempamnts, AmntNewEdit);

   updateamnt = FALSE;

		GF_SetGUIAttr(amntGUI, GUI_OpenGUI, TRUE, TAG_DONE);
 		/* grab window */
 		GF_GetGUIAttr(amntGUI,GUI_Window,&amntWin,TAG_DONE);
		AmntInit();


                /* 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))
                    {
			noreply = TRUE;
                        switch (imsg->Class) {
				case IDCMP_REFRESHWINDOW:
					RegRefresh(TRUE);
					break;

                                case IDCMP_CLOSEWINDOW:
					DataFreeList(&tempamnts);
                                        done = TRUE;
                                        break;

				case IDCMP_RAWKEY:
					if (GF_ProcessListView(amntGUI,A_AmntSpecs[GID_AMNTLIST],
						imsg,&ordinal)) {
							amntlistActive = ordinal;
							AmntDisableGads(FALSE);	
					}
					else AmiHelpKey(imsg,AMNT_PANEL);
					break;

				case IDCMP_GADGETUP:
					noreply = FALSE;
					done=AmntHandleGadget(imsg);
					break;
                        }
                                     
                              
                        if (noreply) GF_ReplyIMsg(imsg);
                    }
                }

   
   GF_SetGadgetAttrs(amntGUI,AMNTgadgetspecs[GID_AMNTLIST].gs_Gadget,
			GTLV_Labels, ~0,
			TAG_DONE);
   GF_SetGUIAttr(amntGUI, GUI_OpenGUI, FALSE, TAG_DONE);
   if (updateamnt == TRUE) {
        qamntSel = ~0;
	     DataMoveList(&tempamnts, &amntlist);
	     NewList(&tempamnts);
   }

  AmiUnlock();
  return (amntretval);
}

/***************************************************
* AmntHandleGadget()
*
*	Handles gadget events for this panel
****************************************************/
BOOL  AmntHandleGadget(struct IntuiMessage *imsg)
{
 BOOL done = FALSE;
 struct Gadget *gad = (struct Gadget *)(imsg->IAddress);
 UWORD code = imsg->Code;
 amntNode tempamnt;
 amntNode *temp;
 char tempstr[AMNTSIZE+5];

 switch (gad->GadgetID) {
	
	case GID_AMNTLIST:
		amntlistActive = code;
		AmntDisableGads(FALSE);
		break;

	case GID_AMNTEDIT:
		if (amntlistActive != ~0) {
		  	DataVerifyAmnt(((struct StringInfo*)gad->SpecialInfo)->Buffer,tempstr);
		  if (DataIsUnique(amntGUI, &tempamnts,tempstr,
				TRUE,"Amnt name is not unique or invalid") == TRUE ) {

						/* detach and modify this */
			temp = (amntNode*)DataOrd2Node(&tempamnts,amntlistActive);
			GF_SetGadgetAttrs(amntGUI,AMNTgadgetspecs[GID_AMNTLIST].gs_Gadget,
				GTLV_Labels, ~0,
				TAG_DONE);
			
			strcpy(temp->amntStr, tempstr);
			GF_SetGadgetAttrs(amntGUI,AMNTgadgetspecs[GID_AMNTLIST].gs_Gadget,
				GTLV_Labels, &tempamnts,
				TAG_DONE);	
		  }
		  else {
			GF_ReplyIMsg(imsg);
			DataSitNSpin(A_AmntSpecs[GID_AMNTEDIT]->gs_Gadget,amntWin);
			return (done);
		  }
		}
		break;

	case GID_AMNTNEW:
		strcpy(tempamnt.amntStr,"0.00");
		if (DataIsUnique(amntGUI, &tempamnts,tempamnt.amntStr,TRUE,"You must rename the previous entry first")){
			/* detach and modify list */
			GF_SetGadgetAttrs(amntGUI,AMNTgadgetspecs[GID_AMNTLIST].gs_Gadget,
				GTLV_Labels, ~0,
				TAG_DONE);
			
			temp=AmntNewEdit(&tempamnts,&tempamnt);
			amntlistActive = DataNode2Ord(&tempamnts,temp->amntStr);
					
			GF_SetGadgetAttrs(amntGUI,AMNTgadgetspecs[GID_AMNTLIST].gs_Gadget,
				GTLV_Labels, &tempamnts,
				GTLV_Selected, amntlistActive,
				TAG_DONE);	

			AmntDisableGads(FALSE);
		}
		break;

	case GID_AMNTDEL:
		DataListRemove(amntGUI,AMNTgadgetspecs[GID_AMNTLIST].gs_Gadget,
			&tempamnts, &amntlistActive);

		/* disable up/down? */
		if (IsListEmpty(&tempamnts))
			AmntDisableGads(TRUE);
		break;

	case GID_AMNTUP:
		DataListUp(amntGUI,AMNTgadgetspecs[GID_AMNTLIST].gs_Gadget,
			&tempamnts, &amntlistActive);
		break;

	case GID_AMNTDOWN:
   	DataListDown(amntGUI,AMNTgadgetspecs[GID_AMNTLIST].gs_Gadget,
			&tempamnts, &amntlistActive);
		break;

	case GID_AMNTTOP:
        DataListTop(amntGUI,AMNTgadgetspecs[GID_AMNTLIST].gs_Gadget,
			&tempamnts, &amntlistActive,0);
		break;

	case GID_AMNTBOTTOM:
        DataListBottom(amntGUI,AMNTgadgetspecs[GID_AMNTLIST].gs_Gadget,
			&tempamnts, &amntlistActive, DataCountNodes(&tempamnts));
		break;

	case GID_AMNTCANCEL:
		DataFreeList(&tempamnts);
		done = TRUE;
		break;

	case GID_AMNTOK:
		amiChangedItems = TRUE;
		updateamnt = done = TRUE;	
		break;
 }

 GF_ReplyIMsg(imsg);
 return (done);
}

/****************************************************
* AmntInit()
*
*	Set up some globals
*****************************************************/
void AmntInit(void)
{
	amntretval = FALSE;
	amntlistActive = ~0;	

 /* grab window */
 GF_GetGUIAttr(amntGUI,GUI_Window,&amntWin,TAG_DONE);
 GF_SetGadgetAttrs(amntGUI,AMNTgadgetspecs[GID_AMNTLIST].gs_Gadget,
			GTLV_Labels, &tempamnts,
			GTLV_Selected,~0,
			TAG_DONE);
 AmntDisableGads(TRUE);
}

/****************************************************
* AmntDisableGads()
*
*	Disable/Enable extra gadgets
*****************************************************/
void AmntDisableGads(BOOL dis)
{
 GF_SetGadgetAttrs(amntGUI,AMNTgadgetspecs[GID_AMNTDEL].gs_Gadget,
	GA_Disabled, dis,
	TAG_DONE);

 GF_SetGadgetAttrs(amntGUI,AMNTgadgetspecs[GID_AMNTUP].gs_Gadget,
	GA_Disabled, dis,
	TAG_DONE);

 GF_SetGadgetAttrs(amntGUI,AMNTgadgetspecs[GID_AMNTDOWN].gs_Gadget,
	GA_Disabled, dis,
	TAG_DONE);

 GF_SetGadgetAttrs(amntGUI,AMNTgadgetspecs[GID_AMNTTOP].gs_Gadget,
	GA_Disabled, dis,
	TAG_DONE);

 GF_SetGadgetAttrs(amntGUI,AMNTgadgetspecs[GID_AMNTBOTTOM].gs_Gadget,
	GA_Disabled, dis,
	TAG_DONE);
}

/*************************************************************
* AmntNewEdit()
*
*	Creates a new amnt node and places it at tail
**************************************************************/
amntNode *AmntNewEdit(struct List *el,amntNode *m)
{
 amntNode *work;

 work = (amntNode *)AllocVec(sizeof(amntNode), MEMF_CLEAR);
 strcpy(work->amntStr,m->amntStr);
 work->node.ln_Name = work->amntStr;
 AddTail((struct List *)el,(struct Node *)work);
 return (work);
}
