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


/* prototypes */
BOOL StatHandleGadget(struct IntuiMessage *);
void StatInit(void);
void StatReport(categoryNode *);
void StatGroupReport(groupNode *);
void StatFill(void);
void StatReportZero(void);

ExtErrorData StatExtData;
GUIFront *statGUI;
WORD	statlistActive;

struct {
	UWORD 	filttrans;
	balanceType  	fbal;
	balanceType	fdep;
	balanceType	fwith;
	
	UWORD 	regtrans;
	balanceType 	rbal;
	balanceType	rdep;
	balanceType	rwith;

} statReport;

static int listtype = 0;
char fbalstr[AMNTSIZE+1];
char fdepstr[AMNTSIZE+1];
char fwithstr[AMNTSIZE+1];
char rbalstr[AMNTSIZE+1];
char rdepstr[AMNTSIZE+1];
char rwithstr[AMNTSIZE+1];

/* quick definition of some tags */
struct TagItem statsCatList[] =
{
        {GTLV_ShowSelected, NULL},
                /*
	{GTLV_Labels, ~0},
	{GTLV_Selected,~0},
        */
        {TAG_DONE},
};

STRPTR listtypelabels[] =
{
	"Categories",
	"Groups",
	NULL,
};

struct TagItem listtypeTags[] =
{
	{GTCY_Labels, listtypelabels},
	{TAG_DONE},
};

/* define gadgetspec */
GadgetSpec STPgadgetspecs[] = 
{
	{LISTVIEW_KIND,30,8, {0,0,0,0,NULL,NULL,GID_STPCATLIST,
		PLACETEXT_ABOVE},statsCatList,GS_DefaultTags},

        {TEXT_KIND,AMNTSIZE-4,0,{0,0,0,0,"Balance", NULL, GID_STPFILTSUM,         
                PLACETEXT_LEFT}, TxtBorder, GS_DefaultTags},

        {TEXT_KIND,AMNTSIZE-4,0,{0,0,0,0,"Balance", NULL, GID_STPTOTSUM,         
                PLACETEXT_LEFT}, TxtBorder, GS_DefaultTags},

        {NUMBER_KIND,0,0,{0,0,0,0,"Transactions", NULL, GID_STPFILTNUM,         
                PLACETEXT_LEFT}, NumBorder, GS_DefaultTags},

        {NUMBER_KIND,0,0,{0,0,0,0,"Transactions", NULL, GID_STPTOTNUM,         
                PLACETEXT_LEFT}, NumBorder, GS_DefaultTags},

        {TEXT_KIND,0,0,{0,0,0,0,"Deposits", NULL, GID_STPTOTDEP,         
                PLACETEXT_LEFT}, TxtBorder, GS_DefaultTags},

        {TEXT_KIND,0,0,{0,0,0,0,"Withdrawals", NULL, GID_STPTOTWITH,         
                PLACETEXT_LEFT}, TxtBorder, GS_DefaultTags},

        {TEXT_KIND,0,0,{0,0,0,0,"Deposits", NULL, GID_STPFILTDEP,         
                PLACETEXT_LEFT}, TxtBorder, GS_DefaultTags},

        {TEXT_KIND,0,0,{0,0,0,0,"Withdrawals", NULL, GID_STPFILTWITH,         
                PLACETEXT_LEFT}, TxtBorder, GS_DefaultTags},

        {BUTTON_KIND,6,0,{0,0,0,0,"_OK", NULL, GID_STPOK,         
                PLACETEXT_IN}, NULL, GS_DefaultTags}, 

	{CYCLE_KIND,0,1, {0,0,0,0,"_List",NULL,GID_STPLIST,
		PLACETEXT_LEFT},listtypeTags,GS_DefaultTags| GS_NoHeightExtend},

};

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


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

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

		GUIL_HorizGroup,2,
			GUIL_FrameType, GUILFT_Ridge,
			GUIL_VertGroup,0,
				GUIL_GadgetSpecID, GID_STPLIST,
				GUIL_GadgetSpecID, GID_STPCATLIST,
			TAG_DONE,

		   	GUIL_VertGroup,1,
				GUIL_Flags, GUILF_EqualWidth,
                	GUIL_VertGroup,0,
				GUIL_FrameType, GUILFT_Ridge,
				GUIL_FrameHeadline, "Filter-based",
                        	GUIL_Flags, GUILF_PropShare | GUILF_EqualWidth | GUILF_LabelAlign,
                                              
				GUIL_GadgetSpecID, GID_STPFILTNUM,
				GUIL_GadgetSpecID, GID_STPFILTSUM,
				GUIL_GadgetSpecID, GID_STPFILTDEP,
				GUIL_GadgetSpecID, GID_STPFILTWITH,
                	TAG_DONE,

			GUIL_VertGroup,0,
				GUIL_FrameType, GUILFT_Ridge,
				GUIL_FrameHeadline, "Register-based",
                        	GUIL_Flags, GUILF_PropShare | GUILF_EqualWidth | GUILF_LabelAlign,
                                              
				GUIL_GadgetSpecID, GID_STPTOTNUM,
				GUIL_GadgetSpecID, GID_STPTOTSUM,
				GUIL_GadgetSpecID, GID_STPTOTDEP,
				GUIL_GadgetSpecID, GID_STPTOTWITH,
                	TAG_DONE,
			TAG_DONE,



		TAG_DONE,

	TAG_DONE,
        
    TAG_DONE,
#if 0    
    GUIL_HorizGroup,1,
        GUIL_Flags, GUILF_EqualSize | GUILF_EqualWidth,
        
           GUIL_GadgetSpecID, GID_STPOK,
           
    TAG_DONE,   
#endif
           
TAG_DONE,
};


/****************************************************
* StatGUI ()
*
*	Creates the GUI for the stat panel.
*****************************************************/
void  StatGUI(void)
{
 BOOL done = FALSE;
 UWORD ordinal;
 categoryNode *cat;
 ULONG signal;
     
 AmiLock();

 
		GF_SetGUIAttr(statGUI, GUI_OpenGUI, TRUE, TAG_DONE);
 		StatInit();

                /* 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_CLOSEWINDOW:
					done = TRUE;
                                        break;

				case IDCMP_RAWKEY:
					if (GF_ProcessListView(statGUI,STP_StatSpecs[GID_STPCATLIST],
						imsg,&ordinal)) {
						cat = (categoryNode *)DataOrd2Node(&categories,ordinal);
						StatReport(cat);
						StatFill();							
					}
					else AmiHelpKey(imsg,STATS_PANEL);
					break;

				case IDCMP_GADGETUP:
					done=StatHandleGadget(imsg);
					break;

				case IDCMP_REFRESHWINDOW:
					RegRefresh(TRUE);
					break;
                        }
                                     
                              
                        GF_ReplyIMsg(imsg);
               }

        }
   GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPCATLIST].gs_Gadget,
			GTLV_Labels, ~0,
			TAG_DONE);
   GF_SetGUIAttr(statGUI, GUI_OpenGUI, FALSE, TAG_DONE);               
   AmiUnlock();
}

/***************************************************
* StatHandleGadget()
*
*	Handles gadget events for this panel
****************************************************/
BOOL StatHandleGadget(struct IntuiMessage *imsg)
{
 BOOL done = FALSE;
 struct Gadget *gad = (struct Gadget *)(imsg->IAddress);
 UWORD code = imsg->Code;
 categoryNode *cat;

 switch (gad->GadgetID) {

	case GID_STPLIST:
		listtype = code;
		StatReportZero();
		GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPCATLIST].gs_Gadget,
			GTLV_Labels, ~0,
			GTLV_Selected, ~0,
			TAG_DONE);
		
		GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPCATLIST].gs_Gadget,
			GTLV_Labels, (listtype==0)?&categories:&grouplist,
			GTLV_Selected, ~0,
			TAG_DONE);

		break;
	
	case GID_STPCATLIST:
		if (listtype == 0) {
			cat = (categoryNode *)DataOrd2Node(&categories,code);
			StatReport(cat);
			StatFill();
		}
		else {
			StatGroupReport((groupNode *)DataOrd2Node(&grouplist,code));
			StatFill();
		}
		break;

	case GID_STPOK:
		done = TRUE;	
		break;
 }

 return (done);
}

/****************************************************
* StatInit()
*
*	Set up some globals
*****************************************************/
void StatInit(void)
{
 memset(&statReport,0,sizeof(statReport));
 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPCATLIST].gs_Gadget,
			GTLV_Labels, &categories,
			GTLV_Selected, ~0,
			/*GTLV_MakeVisible,0,*/
			TAG_DONE);
 
 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPLIST].gs_Gadget,
			GTCY_Active, 0,
			TAG_DONE);

  StatReportZero();
}

/******************************************************
* StatReportZero()
*
*******************************************************/
void StatReportZero(void)
{
 amountType zero = 0;

 /* reset to 0 */
 DataInitBal(DEPOSITTYPE,&zero,&statReport.rdep);
 DataInitBal(DEPOSITTYPE,&zero,&statReport.fdep);
 DataInitBal(DEPOSITTYPE,&zero,&statReport.rwith);
 DataInitBal(DEPOSITTYPE,&zero,&statReport.fwith);

 statReport.regtrans = statReport.filttrans = 0;
 
 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPFILTSUM].gs_Gadget,
	GTTX_Text,"",
	TAG_DONE);

 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPTOTSUM].gs_Gadget,
	GTTX_Text,"",
	TAG_DONE);

 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPFILTDEP].gs_Gadget,
	GTTX_Text,"",
	TAG_DONE);

 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPFILTWITH].gs_Gadget,
	GTTX_Text,"",
	TAG_DONE);

 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPTOTDEP].gs_Gadget,
	GTTX_Text,"",
	TAG_DONE);

 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPTOTWITH].gs_Gadget,
	GTTX_Text,"",
	TAG_DONE);

 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPFILTNUM].gs_Gadget,
	GTNM_Number,statReport.filttrans,
	TAG_DONE);

 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPTOTNUM].gs_Gadget,
	GTNM_Number,statReport.regtrans,
	TAG_DONE);
}

/****************************************************
* StatReport()
*
*	Calculate values and report them
*****************************************************/
void StatReport(categoryNode *cat)
{
 amountType zero = 0;
 entryNode *work = (entryNode *)entries.mlh_Head, *next;
 filterNode *fwork= (filterNode*)filtered.mlh_Head, *fnext;

 DataInitBal(DEPOSITTYPE,&zero,&statReport.rdep);
 DataInitBal(DEPOSITTYPE,&zero,&statReport.fdep);
 DataInitBal(DEPOSITTYPE,&zero,&statReport.rwith);
 DataInitBal(DEPOSITTYPE,&zero,&statReport.fwith);

 statReport.regtrans = statReport.filttrans = 0;

 if (entries.mlh_TailPred != &entries)  {

	/* calculate totals */
	while ( (next = (entryNode *)work->node.mln_Succ) ) {
		if ( !(work->flags & VOIDED) && 
			strcmpi(cat->catname,work->category) == 0) {

			statReport.regtrans++;
			
			if (work->type == DEPOSITTYPE) {
				DataAddBal(DEPOSITTYPE,&work->amount,&statReport.rdep);
			}
			else {
				DataAddBal(DEPOSITTYPE,&work->amount,&statReport.rwith);
			}
		}
	
		work = next;
	}
 }

 if (filtered.mlh_TailPred != &filtered) {

	/* calculate filtered */
	while ( (fnext = (filterNode *)fwork->node.mln_Succ) ) {
	
		if ( !(fwork->entry->flags & VOIDED) &&
		 	strcmpi(cat->catname,fwork->entry->category) == 0) {

			statReport.filttrans++;

			if (fwork->entry->type == DEPOSITTYPE) {
				DataAddBal(DEPOSITTYPE,&fwork->entry->amount,&statReport.fdep);
			}
			else {
				DataAddBal(DEPOSITTYPE,&fwork->entry->amount,&statReport.fwith);
			}
		}

		fwork = fnext;
	}
 }

 statReport.rwith.neg = TRUE;
 statReport.fwith.neg = TRUE;
 DataBalAddBal(usrAccount.decimal,&statReport.rbal,&statReport.rdep, &statReport.rwith);
 DataBalAddBal(usrAccount.decimal,&statReport.fbal,&statReport.fdep, &statReport.fwith);
 statReport.rwith.neg = FALSE;
 statReport.fwith.neg = FALSE;

 return;
}

/****************************************************
* StatGroupReport()
*
*	Calculate values and report them
*****************************************************/
void StatGroupReport(groupNode *group)
{
 amountType zero = 0;
 categoryNode *cat = NULL;
 entryNode *work = (entryNode *)entries.mlh_Head, *next;
 filterNode *fwork= (filterNode*)filtered.mlh_Head, *fnext;

 statReport.regtrans = statReport.filttrans = 0;
 DataInitBal(DEPOSITTYPE,&zero,&statReport.rdep);
 DataInitBal(DEPOSITTYPE,&zero,&statReport.fdep);
 DataInitBal(DEPOSITTYPE,&zero,&statReport.rwith);
 DataInitBal(DEPOSITTYPE,&zero,&statReport.fwith);


while ( (cat = (categoryNode *)DataGetNext(&group->catlist,cat)) != NULL) {
 work = (entryNode *)entries.mlh_Head;
 fwork= (filterNode*)filtered.mlh_Head;

 if (entries.mlh_TailPred != &entries)  {

	/* calculate totals */
	while ( (next = (entryNode *)work->node.mln_Succ) ) {
		if ( !(work->flags & VOIDED) && 
			strcmpi(cat->catname,work->category) == 0) {

			statReport.regtrans++;

			if (work->type == DEPOSITTYPE) {
				DataAddBal(DEPOSITTYPE,&work->amount,&statReport.rdep);
			}
			else {
				DataAddBal(DEPOSITTYPE,&work->amount,&statReport.rwith);
			}
		}
	
		work = next;
	}
 }

 if (filtered.mlh_TailPred != &filtered) {

	/* calculate filtered */
	while ( (fnext = (filterNode *)fwork->node.mln_Succ) ) {
	
		if ( !(fwork->entry->flags & VOIDED) &&
		 	strcmpi(cat->catname,fwork->entry->category) == 0) {

			statReport.filttrans++;

			if (fwork->entry->type == DEPOSITTYPE) {
				DataAddBal(DEPOSITTYPE,&fwork->entry->amount,&statReport.fdep);
			}
			else {
				DataAddBal(DEPOSITTYPE,&fwork->entry->amount,&statReport.fwith);
			}
		}

		fwork = fnext;
	}
 }

}

 statReport.rwith.neg = TRUE;
 statReport.fwith.neg = TRUE;
 DataBalAddBal(usrAccount.decimal,&statReport.rbal,&statReport.rdep, &statReport.rwith);
 DataBalAddBal(usrAccount.decimal,&statReport.fbal,&statReport.fdep, &statReport.fwith);
 statReport.rwith.neg = FALSE;
 statReport.fwith.neg = FALSE;

 return;
}


/************************************************
* StatFill()
*
*	fill the report entries into the panel
*************************************************/
void StatFill(void)
{

 DataBuildBal(usrAccount.decimal,&statReport.fbal,fbalstr);
 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPFILTSUM].gs_Gadget,
	GTTX_Text,fbalstr,
	TAG_DONE);

 DataBuildBal(usrAccount.decimal,&statReport.rbal,rbalstr);
 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPTOTSUM].gs_Gadget,
	GTTX_Text,rbalstr,
	TAG_DONE);

 DataBuildBal(usrAccount.decimal,&statReport.fdep,fdepstr);
 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPFILTDEP].gs_Gadget,
	GTTX_Text,fdepstr,
	TAG_DONE);

 DataBuildBal(usrAccount.decimal,&statReport.fwith,fwithstr);
 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPFILTWITH].gs_Gadget,
	GTTX_Text,fwithstr,
	TAG_DONE);

 DataBuildBal(usrAccount.decimal,&statReport.rdep,rdepstr);
 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPTOTDEP].gs_Gadget,
	GTTX_Text,rdepstr,
	TAG_DONE);

 DataBuildBal(usrAccount.decimal,&statReport.rwith,rwithstr);
 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPTOTWITH].gs_Gadget,
	GTTX_Text,rwithstr,
	TAG_DONE);

 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPFILTNUM].gs_Gadget,
	GTNM_Number,statReport.filttrans,
	TAG_DONE);

 GF_SetGadgetAttrs(statGUI,STPgadgetspecs[GID_STPTOTNUM].gs_Gadget,
	GTNM_Number,statReport.regtrans,
	TAG_DONE);
}
