/* sortPanel.c 
 *
 *  defines the GUIFront characteristics of the sort panel 
 */
  
#include <stdio.h>  
#include <intuition/gadgetclass.h>
#include "amiCheck.h"
#include "sortPanel.h"
#include "dataBase.h"
#include <string.h>


/* prototypes */
BOOL SortHandleGadget(struct IntuiMessage *);
void SortInit(void);
void SortInsert(UWORD);
void SortRemove(UWORD);
void SortDisableMoves(BOOL);
BOOL sortretval;

ExtErrorData SortExtData;
GUIFront *sortGUI;
UWORD sortActive;

sortNode tempSorts[SORTENTRIES];
sortState tempState;
struct List tempSortList; 

/* quick configure of some gadgets */

STRPTR  sortLabels[] =
{	
	"Ascending",
	"Descending",
	NULL,
};

struct TagItem orderTags[] =
{
	{GTCY_Labels,sortLabels},
	{TAG_DONE},
};

/* define gadgetspec */
GadgetSpec SRPgadgetspecs[] = 
{
	{CHECKBOX_KIND,0,0, {0,0,0,0,"C_heck Number",NULL,GID_SRPCHECK,
		PLACETEXT_RIGHT},NULL,GS_DefaultTags},

	{CHECKBOX_KIND,0,0, {0,0,0,0,"_Name Field",NULL,GID_SRPNAME,
		PLACETEXT_RIGHT},NULL,GS_DefaultTags},

	{CHECKBOX_KIND,0,0, {0,0,0,0,"_Memo Field",NULL,GID_SRPMEMO,
		PLACETEXT_RIGHT},NULL,GS_DefaultTags},

	{CHECKBOX_KIND,0,0, {0,0,0,0,"Transaction Dat_e",NULL,GID_SRPDATE,
		PLACETEXT_RIGHT},NULL,GS_DefaultTags},

	{CHECKBOX_KIND,0,0, {0,0,0,0,"_Amount",NULL,GID_SRPAMNT,
		PLACETEXT_RIGHT},NULL,GS_DefaultTags},

	{CHECKBOX_KIND,0,0, {0,0,0,0,"Cate_gory",NULL,GID_SRPCATEGORY,
		PLACETEXT_RIGHT},NULL,GS_DefaultTags},

	{CYCLE_KIND,0,0,{0,0,0,0,"O_rder",NULL,GID_SRPORDER,
		PLACETEXT_LEFT},orderTags,GS_DefaultTags},

	{LISTVIEW_KIND,20,8, {0,0,0,0,NULL,NULL,GID_SRPFIELDLIST,
		PLACETEXT_ABOVE},ListView,GS_DefaultTags},

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

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

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

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

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

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

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


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

   GUIL_HorizGroup, 1,
        GUIL_Flags, GUILF_PropShare | GUILF_EqualHeight,
	GUIL_FrameType, GUILFT_Recess,
        
	GUIL_VertGroup, 1,
		GUIL_Flags, GUILF_LabelAlign,
		GUIL_FrameType, GUILFT_Ridge,
		GUIL_FrameHeadline, "Sort Criteria",

		GUIL_GadgetSpecID, GID_SRPCHECK,
		GUIL_GadgetSpecID, GID_SRPDATE,
		GUIL_GadgetSpecID, GID_SRPAMNT,
		GUIL_GadgetSpecID, GID_SRPNAME,
		GUIL_GadgetSpecID, GID_SRPMEMO,
		GUIL_GadgetSpecID, GID_SRPCATEGORY,

	TAG_DONE,
        
	GUIL_VertGroup, 1,
		GUIL_FrameType, GUILFT_Ridge,
		GUIL_FrameHeadline, "Sort Priority",
		
		GUIL_HorizGroup, 1,
			GUIL_GadgetSpecID, GID_SRPFIELDLIST,
			
			GUIL_VertGroup,1,
				GUIL_GadgetSpecID, GID_SRPUP,
				GUIL_GadgetSpecID, GID_SRPDOWN,
				GUIL_GadgetSpecID, GID_SRPTOP,
				GUIL_GadgetSpecID, GID_SRPBOTTOM,
			TAG_DONE,
		TAG_DONE,

		GUIL_GadgetSpecID, GID_SRPORDER,

	TAG_DONE,

    TAG_DONE,
    
    GUIL_HorizGroup,1,
        GUIL_Flags, GUILF_EqualSize | GUILF_EqualWidth,
        
           GUIL_GadgetSpecID, GID_SRPOK,
           GUIL_GadgetSpecID, GID_SRPCANCEL,
           
    TAG_DONE,   
           
TAG_DONE,
};


/****************************************************
* SortGUI ()
*
*	Creates the GUI for the sort panel.
*****************************************************/
BOOL SortGUI(void)
{
 BOOL done = FALSE;
 UWORD ordinal;
 ULONG signal;
     
   AmiLock();

   NewList(&tempSortList); 
   GF_SetGUIAttr(sortGUI,GUI_OpenGUI,TRUE,TAG_DONE);
  
		SortInit();
		
                /* 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))
                    {
                        switch (imsg->Class) {
				case IDCMP_REFRESHWINDOW:
					RegRefresh(TRUE);
					break;

                                case IDCMP_CLOSEWINDOW:
					done = TRUE;
                                        break;

				case IDCMP_RAWKEY:
					if (GF_ProcessListView(sortGUI,SRP_SortSpecs[GID_SRPFIELDLIST],
						imsg,&ordinal)) {
							sortActive = ordinal;			
							SortDisableMoves(FALSE);
					}
					else AmiHelpKey(imsg,SORT_PANEL);
					break;

				case IDCMP_GADGETUP:
					done=SortHandleGadget(imsg);
					break;
                        }
                                     
                              
                        GF_ReplyIMsg(imsg);
                    }
                }

   GF_SetGadgetAttrs(sortGUI,SRPgadgetspecs[GID_SRPFIELDLIST].gs_Gadget,
				GTLV_Labels, ~0,
				TAG_DONE);	

   GF_SetGUIAttr(sortGUI, GUI_OpenGUI, FALSE, TAG_DONE);         
   AmiUnlock();

 return (sortretval);
}

/***************************************************
* SortHandleGadget()
*
*	Handles gadget events for this panel
****************************************************/
BOOL  SortHandleGadget(struct IntuiMessage *imsg)
{
 UWORD x;
 BOOL done = FALSE;
 struct Gadget *gad =  (struct Gadget *)(imsg->IAddress);
 UWORD code = imsg->Code;
 sortNode *curr, *parent;
 
 switch (gad->GadgetID) {

	case GID_SRPCHECK:
		tempState.check = code;
		if (code) SortInsert(SORTCHECK);
		else SortRemove(SORTCHECK);
		break;

	case GID_SRPDATE:
		tempState.date = code;
		if (code) SortInsert(SORTDATE);
		else SortRemove(SORTDATE);
		break;

	case GID_SRPAMNT:
		tempState.amnt = code;
		if (code) SortInsert(SORTAMNT);
		else SortRemove(SORTAMNT);
		break;

	case GID_SRPNAME:
		tempState.name = code;
		if (code) SortInsert(SORTNAME);
		else SortRemove(SORTNAME);
		break;

	case GID_SRPMEMO:
		tempState.memo = code;
		if (code) SortInsert(SORTMEMO);
		else SortRemove(SORTMEMO);
		break;

	case GID_SRPCATEGORY:
		tempState.category = code;
		if (code) SortInsert(SORTCATEGORY);
		else SortRemove(SORTCATEGORY);
		break;

	case GID_SRPFIELDLIST:
		sortActive = code;
		SortDisableMoves(FALSE);
		curr = (sortNode *)DataOrd2Node(&tempSortList,sortActive);
		GF_SetGadgetAttrs(sortGUI,SRPgadgetspecs[GID_SRPORDER].gs_Gadget,
				GTCY_Active, curr->order,
				TAG_DONE);
		break;

	case GID_SRPORDER:
		curr = (sortNode *)DataOrd2Node(&tempSortList,sortActive);
		curr->order = code;
		break;

	case GID_SRPTOP:
		DataListTop(sortGUI,SRPgadgetspecs[GID_SRPFIELDLIST].gs_Gadget,
			&tempSortList, &sortActive,0);
		break;

	case GID_SRPBOTTOM:
		DataListBottom(sortGUI,SRPgadgetspecs[GID_SRPFIELDLIST].gs_Gadget,
			&tempSortList, &sortActive,DataCountNodes(&tempSortList));
		break;

	case GID_SRPUP:
		DataListUp(sortGUI,SRPgadgetspecs[GID_SRPFIELDLIST].gs_Gadget,
			&tempSortList, &sortActive);
		break;

	case GID_SRPDOWN:
		DataListDown(sortGUI,SRPgadgetspecs[GID_SRPFIELDLIST].gs_Gadget,
			&tempSortList, &sortActive);
		break;

	case GID_SRPCANCEL:
		done = TRUE;
		break;
                                                         
	case GID_SRPOK:
		amiChangedItems = TRUE;
		memcpy(&sortStates, &tempState, sizeof(sortState));
		for (x=0;x<SORTENTRIES;x++)
			memcpy(&sortEntries[x],&tempSorts[x],sizeof(sortNode));
		DataMoveSort(&sortfields, sortEntries, &tempSortList, tempSorts);
		sortretval = TRUE;
		done = TRUE;
 		break;
 }

 return (done);
}

/****************************************************
* SortInit()
*
*	Set up some globals
*****************************************************/
void SortInit(void)
{
UWORD x;

 sortretval = FALSE;

 /* initialize our sort list */
 memcpy(&tempState, &sortStates, sizeof(sortState));

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPFIELDLIST]->gs_Gadget,
		GTLV_Labels, ~0,
		TAG_DONE);

 for (x=0;x<SORTENTRIES;x++) {
	memcpy(&tempSorts[x],&sortEntries[x],sizeof(sortNode));
	tempSorts[x].node.ln_Name = tempSorts[x].field;
 }
 DataMoveSort(&tempSortList, tempSorts, &sortfields, sortEntries);

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPFIELDLIST]->gs_Gadget,
		GTLV_Labels, &tempSortList,
		TAG_DONE);

 /* set up checkboxes! */
 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPCHECK]->gs_Gadget,
		GTCB_Checked, tempState.check,
		TAG_DONE);

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPMEMO]->gs_Gadget,
		GTCB_Checked,tempState.memo,
		TAG_DONE);

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPNAME]->gs_Gadget,
		GTCB_Checked,tempState.name,
		TAG_DONE);

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPDATE]->gs_Gadget,
		GTCB_Checked,tempState.date,
		TAG_DONE);

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPAMNT]->gs_Gadget,
		GTCB_Checked,tempState.amnt,
		TAG_DONE);

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPCATEGORY]->gs_Gadget,
		GTCB_Checked, tempState.category,
		TAG_DONE);

 /* disable order */
 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPORDER]->gs_Gadget,
		GA_Disabled, TRUE,
		TAG_DONE);

 SortDisableMoves(TRUE);
}

/**********************************************************
* SortInsert()
*
*	Insert a field
***********************************************************/
void SortInsert(UWORD entry)
{
 /* remove list */
 GF_SetGadgetAttrs(sortGUI, SRP_SortSpecs[GID_SRPFIELDLIST]->gs_Gadget,
		GTLV_Labels, ~0,
		TAG_DONE);

 AddTail(&tempSortList,(struct Node *)&tempSorts[entry]);

 /* re-instate list */
 GF_SetGadgetAttrs(sortGUI, SRP_SortSpecs[GID_SRPFIELDLIST]->gs_Gadget,
		GTLV_Labels, &tempSortList,
		GTLV_Selected, ~0,
		TAG_DONE);

 /* disable misc */
 SortDisableMoves(TRUE);

}

/**********************************************************
* SortRemove()
*
*	remove a field
***********************************************************/
void SortRemove(UWORD entry)
{
 /* remove list */
 GF_SetGadgetAttrs(sortGUI, SRP_SortSpecs[GID_SRPFIELDLIST]->gs_Gadget,
		GTLV_Labels, ~0,
		TAG_DONE);

 Remove((struct Node *)&tempSorts[entry]);

 /* re-instate list */
 GF_SetGadgetAttrs(sortGUI, SRP_SortSpecs[GID_SRPFIELDLIST]->gs_Gadget,
		GTLV_Labels, &tempSortList,
		GTLV_Selected, ~0,
		TAG_DONE);



 /* disable misc */
 SortDisableMoves(TRUE);
}

/******************************************************
* SortDisableMoves()
*
*	Disable the up/down, etc buttons
*******************************************************/
void SortDisableMoves(BOOL dis)
{

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPUP]->gs_Gadget,
		GA_Disabled, dis,
		TAG_DONE);

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPDOWN]->gs_Gadget,
		GA_Disabled, dis,
		TAG_DONE);

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPTOP]->gs_Gadget,
		GA_Disabled, dis,
		TAG_DONE);

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPBOTTOM]->gs_Gadget,
		GA_Disabled, dis,
		TAG_DONE);

 GF_SetGadgetAttrs (sortGUI, SRP_SortSpecs[GID_SRPORDER]->gs_Gadget,
		GA_Disabled, dis,
		TAG_DONE);
}
