home *** CD-ROM | disk | FTP | other *** search
/ Amiga Times / AmigaTimes.iso / sonstiges / tools / amiCheck / Source / analysispanel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-06  |  21.7 KB  |  1,071 lines

  1. /* analysisPanel.c 
  2. *
  3. *  defines the GUIFront characteristics of the analysis panel
  4. */
  5.  
  6. #include <math.h>  
  7. #include <libraries/guifront.h>
  8. #include <intuition/gadgetclass.h>
  9. #include <exec/memory.h>
  10. #include <clib/graphics_protos.h>
  11. #include <clib/exec_protos.h>
  12. #include <clib/diskfont_protos.h>
  13. #include <intuition/screens.h>
  14. #include <clib/intuition_protos.h>
  15. #include <graphics/gfxmacros.h>
  16. #include <graphics/gfxbase.h>
  17.  
  18. #include "amiCheck.h"
  19. #include "database.h"
  20. #include "regGadget.h"
  21. #include "analysisPanel.h"
  22.  
  23. extern struct GfxBase *GfxBase;
  24.  
  25. #define ANAREA_SIZE    200
  26.  
  27. #define CTRLLEFT    0
  28. #define CTRLRIGHT    1
  29. #define SHIFTLEFT    2
  30. #define SHIFTRIGHT    3
  31. #define LEFT        4
  32. #define RIGHT        5
  33.  
  34. extern struct TextFont *regFont;
  35. GUIFront *analGUI;
  36. struct Window *anWin;
  37.  
  38. static char anBalance[80];
  39. static ULONG anFinalSel;
  40. static int graphtype=0;
  41. static long barScale;
  42. static int andepth;
  43. static ULONG anSelBar = -1;
  44. static ULONG anTopBar;
  45. float  anBarScale;
  46. static ULONG anNumBars;
  47. static long anTopScale;
  48. static int anBarHeight, anBarWidth, anBarMax;
  49. static struct RastPort anWorkRP, *anRP = NULL;
  50. static chip struct BitMap anbuffer;
  51. static chip struct AreaInfo anarea;
  52. static chip struct TmpRas antmp;
  53. static chip void *antmprp = NULL;
  54. static chip UWORD anAreaBuffer[ANAREA_SIZE];
  55. LONG anHeight, anWidth, anTop, anWidth, anLeft;
  56.  
  57. BOOL AnHandleGadget(struct IntuiMessage *);
  58. BOOL AnHandleGadgetDown (struct IntuiMessage *);
  59. void AnHandleMouseMove (struct IntuiMessage *);
  60. BOOL AnalysisCreate(void);
  61. void AnGraphInit(void);
  62. void AnRenderBars(int);
  63. void AnRefresh(void);
  64. BOOL AnHitTest(ULONG,ULONG,ULONG,ULONG);
  65. void AnSelect(int,BOOL);
  66. void AnBalance(void);
  67. BOOL AnProcessRawkeys(struct IntuiMessage *);
  68. void AnKeyScroll(char);
  69. void AnKeyScale(char);
  70. void AnScrollBars(long,long,long,long);
  71. balanceType AnFilterBal(void);
  72.  
  73. /* define imagery tags */
  74.  
  75. struct TagItem getGraphScrollTypes[] =
  76. {
  77.         {PGA_Freedom, LORIENT_HORIZ},          
  78.     {GA_Immediate, TRUE},
  79.         {TAG_DONE},
  80. };
  81.  
  82.  
  83. STRPTR graphlabels[] =
  84. {
  85.     "Running Balance",
  86.     "Filter's Balance",
  87.     "Amounts",
  88.     NULL,
  89. };
  90.  
  91. struct TagItem graphCycleTags[] =
  92. {
  93.     {GTCY_Labels, graphlabels},
  94.     {TAG_DONE},
  95. };
  96.  
  97.  
  98. /* define gadgetspec */
  99. GadgetSpec an_gadgetspecs[] = 
  100. {
  101.                 
  102.         {TEXT_KIND, 50,12,{0,0,0,0, NULL,NULL,GID_ANFIELD,
  103.                 PLACETEXT_IN}, TxtBorder, GS_DefaultTags},
  104.  
  105.     {TEXT_KIND,10 ,1, {0,0,0,0,NULL,NULL,GID_ANBAL,
  106.         PLACETEXT_IN}, TxtBorder, GS_DefaultTags},
  107.  
  108.         {SCROLLER_KIND,10,1,{0,0,0,0, "Scroll X:",NULL,GID_ANSCROL,
  109.                 PLACETEXT_LEFT}, getGraphScrollTypes, GS_DefaultTags},
  110.  
  111.         {SCROLLER_KIND,10,1,{0,0,0,0, "Scale Y:",NULL,GID_ANSCALE,
  112.                 PLACETEXT_LEFT}, getGraphScrollTypes, GS_DefaultTags},
  113.  
  114.         {CYCLE_KIND,10,1,{0,0,0,0,"_Graph Type:",NULL, GID_ANTYPE,
  115.                PLACETEXT_LEFT}, graphCycleTags, GS_DefaultTags},    
  116.  
  117.     {BUTTON_KIND,6,0,{0,0,0,0,"_OK",NULL,GID_ANOK,
  118.         PLACETEXT_IN}, NULL, GS_DefaultTags},
  119. };
  120.  
  121.  
  122. /* set up array of pointers to our specs */
  123. GadgetSpec *AN_MainSpecs[] =
  124. {
  125.         &an_gadgetspecs[0],
  126.         &an_gadgetspecs[1],
  127.         &an_gadgetspecs[2],
  128.     &an_gadgetspecs[3],
  129.     &an_gadgetspecs[4],
  130.     &an_gadgetspecs[5],
  131.         NULL,
  132. };
  133.  
  134.  
  135. /* define the layout of this panel */
  136. ULONG AN_MainPanel[] =
  137. {
  138.    GUIL_Flags, GUILF_PropShare | GUILF_EqualWidth,
  139.    
  140.     GUIL_HorizGroup, 1,
  141. /*    GUIL_FrameType, GUILFT_Recess,*/
  142.  
  143.         GUIL_VertGroup,1,
  144.         
  145.         GUIL_HorizGroup, 1,
  146.             GUIL_Flags, GUILF_PropShare,
  147.                     GUIL_GadgetSpecID, GID_ANTYPE,
  148.             GUIL_GadgetSpecID, GID_ANBAL,
  149.         TAG_DONE,
  150.  
  151.         GUIL_VertGroup, 1,
  152.             GUIL_Flags, GUILF_PropShare | GUILF_EqualWidth,
  153.             GUIL_GadgetSpecID, GID_ANFIELD,
  154.  
  155.             GUIL_VertGroup,1,
  156.                 GUIL_Flags, GUILF_EqualWidth|GUILF_LabelAlign,
  157.                 GUIL_GadgetSpecID, GID_ANSCROL,
  158.                 GUIL_GadgetSpecID, GID_ANSCALE,
  159.             TAG_DONE,
  160.  
  161.         TAG_DONE,
  162.               
  163.         TAG_DONE,
  164.  
  165.    TAG_DONE,
  166.     
  167. #if 0
  168.     GUIL_HorizGroup,1,
  169.         GUIL_Flags, GUILF_EqualSize | GUILF_EqualWidth,
  170.         
  171.            GUIL_GadgetSpecID, GID_ANOK,
  172.            
  173.     TAG_DONE,   
  174. #endif
  175.   
  176.   TAG_DONE,
  177. };
  178.  
  179.  
  180.  
  181. /***********************************************************************/
  182. BOOL AnalysisGUI(void)
  183. {
  184.  BOOL done = FALSE;
  185.  BOOL reply = TRUE;
  186.  filterNode *filt;
  187.  ULONG signal;
  188.  
  189.  AmiLock();
  190.  
  191.  GF_SetGUIAttr(analGUI, GUI_OpenGUI, TRUE, TAG_DONE);
  192.  GF_GetGUIAttr(analGUI, GUI_Window, &anWin, TAG_DONE);
  193.  
  194.  /* initialize stuff real quick */
  195.  AnGraphInit();
  196.  
  197.  /* Process input events */
  198.  while (!done)
  199.                 {
  200.                     struct IntuiMessage *imsg;
  201.  
  202.                     /* Wait for an event to occur */
  203.  
  204.                     signal = GF_Wait(guiapp,AmigaGuideSignal(agc));
  205.             if (signal & AmigaGuideSignal(agc)) {
  206.             AmiHelpMsg();
  207.             continue;
  208.             }
  209.  
  210.                     /* We only bother to listen for CLOSEWINDOW events.
  211.                      * Of course, in a real application, you would be
  212.                      * examining the Class field for IDCMP_GADGETUP
  213.                      * messages and act accordingly.
  214.                      */
  215.  
  216.                     while (imsg = GF_GetIMsg(guiapp))
  217.                     {
  218.             reply = TRUE;
  219.                         switch (imsg->Class) {
  220.                                 case IDCMP_CLOSEWINDOW:
  221.                     done = TRUE;
  222.                                         break;
  223.  
  224.                 case IDCMP_RAWKEY:
  225.                     done = AnProcessRawkeys(imsg);
  226.                     break;
  227.  
  228.                 case IDCMP_MOUSEMOVE:
  229.                     AnHandleMouseMove(imsg);
  230.                     break;
  231.  
  232.                 case IDCMP_GADGETUP:
  233.                     reply = FALSE;
  234.                     done=AnHandleGadget(imsg);
  235.                     break;
  236.  
  237.                 case IDCMP_GADGETDOWN:
  238.                     done = AnHandleGadgetDown(imsg);
  239.                     break;
  240.  
  241.                 case IDCMP_REFRESHWINDOW:
  242.                     AnRefresh();
  243.                     RegRefresh(TRUE);
  244.                     break;
  245.  
  246.                 default:
  247.                     AnRefresh();
  248.                     break;
  249.                         }
  250.                                      
  251.                               
  252.              if (reply)
  253.                 GF_ReplyIMsg(imsg);
  254.                     }
  255.                 }
  256.  
  257.  
  258.  GF_SetGUIAttr(analGUI, GUI_OpenGUI, FALSE, TAG_DONE);               
  259.  AmiUnlock();
  260.  
  261.  if (anFinalSel != -1) {
  262.     selRow = anFinalSel;
  263.     filt = (filterNode *)DataOrd2Node((struct List *)&filtered,anFinalSel);    
  264.     RegMoveToSel(&filtered);
  265.     return (TRUE);
  266.  }
  267.  return (FALSE);
  268. }
  269.  
  270. /*******************************************************/
  271. BOOL AnProcessRawkeys(struct IntuiMessage *imsg)
  272. {
  273. BOOL done = FALSE;
  274. static BOOL upevent = FALSE;
  275. static long upval;
  276. static BOOL shift = FALSE, ctrl = FALSE;
  277.  
  278.  
  279. if (upevent && imsg->Code != upval)
  280.     return done;
  281.  
  282.  
  283. upevent = FALSE;
  284.  
  285. /* for now, use raw keys */
  286. switch (imsg->Code) {
  287.  
  288.     case 0x44:
  289.         if (anSelBar != -1) {
  290.             anFinalSel = anSelBar;
  291.             done = TRUE;
  292.         }
  293.         break;
  294.  
  295.     case 0xe1:
  296.     case 0xe0:
  297.         shift = FALSE;
  298.         break;
  299.  
  300.     case 0x61:
  301.     case 0x60:
  302.         shift = TRUE;
  303.         break;
  304.  
  305.     case 0xe3:
  306.         ctrl = FALSE;
  307.         break;
  308.     
  309.     case 0x63:
  310.         ctrl = TRUE;
  311.         break;
  312.  
  313.     case 0x4f:
  314.         upevent = TRUE;
  315.         upval = imsg->Code | 0x80;
  316.         if (shift)
  317.             AnKeyScroll(SHIFTLEFT);
  318.         else if (ctrl)
  319.             AnKeyScroll(CTRLLEFT);
  320.         else
  321.             AnKeyScroll(LEFT);
  322.         break;
  323.  
  324.     case 0x4e:
  325.         upevent = TRUE;
  326.         upval = imsg->Code | 0x80;
  327.         if (shift)
  328.             AnKeyScroll(SHIFTRIGHT);
  329.         else if (ctrl)
  330.             AnKeyScroll(CTRLRIGHT);
  331.         else
  332.             AnKeyScroll(RIGHT);
  333.         break;
  334.  
  335.     case 0x4c:
  336.  
  337.         upevent = TRUE;
  338.         upval = imsg->Code | 0x80;
  339.         if (shift) 
  340.             AnKeyScale(SHIFTUP);
  341.         else if (ctrl)
  342.             AnKeyScale(CTRLUP);
  343.         else 
  344.             AnKeyScale(UP);
  345.         break;
  346.  
  347.     case 0x4d:
  348.         upevent = TRUE;
  349.         upval = imsg->Code | 0x80;
  350.  
  351.         if (shift) 
  352.             AnKeyScale(SHIFTDOWN);
  353.         else if (ctrl)
  354.             AnKeyScale(CTRLDOWN);
  355.         else 
  356.             AnKeyScale(DOWN);
  357.         break;
  358.  
  359.     default:
  360.         AmiHelpKey(imsg,ANALYSIS_PANEL);    
  361.         break;
  362. }
  363.  
  364.  return (done);
  365. }
  366.  
  367. /*******************************************************/
  368. void AnKeyScale(char code)
  369. {
  370.  long visual = anTopScale;
  371.  
  372.  switch (code) {
  373.     case CTRLUP:        
  374.         visual = anBarHeight*20;
  375.         break;
  376.  
  377.     case CTRLDOWN:
  378.         visual = 0;
  379.         break;
  380.  
  381.     case SHIFTUP:
  382.         if (visual > anBarHeight*20)
  383.             visual = anBarHeight*20;
  384.         else    visual += anBarHeight;
  385.         break;
  386.  
  387.     case SHIFTDOWN:
  388.         if (visual < anBarHeight)
  389.             visual = 0;
  390.         else     visual -= anBarHeight;
  391.         break;
  392.  
  393.     case UP:
  394.         if (visual < anBarHeight*20)
  395.             visual++;
  396.         break;
  397.  
  398.     case DOWN:
  399.         if (visual > 0)
  400.             visual--;
  401.         break;
  402.  }
  403.  
  404.  anBarScale = (float)visual/(float)barScale;
  405.  anTopScale = visual;
  406.  AnScrollBars(GID_ANSCALE,visual,anBarHeight*20,anBarHeight);
  407.  AnRenderBars(anTopBar);
  408.  AnRefresh();
  409. }
  410.  
  411. /*******************************************************/
  412. void AnKeyScroll(char code)
  413. {
  414.  long col;
  415.  
  416.  switch (code) {
  417.     case CTRLLEFT:
  418.         /* jump to beginning */
  419.         anTopBar = 0;
  420.  
  421.         /* select first */
  422.         AnSelect(0,FALSE);
  423.  
  424.         AnRenderBars(anTopBar);
  425.         AnRefresh();
  426.         break;
  427.  
  428.     case CTRLRIGHT:
  429.         /* jump to end */
  430.         if (anNumBars > anBarMax) {
  431.             anTopBar = anNumBars-anBarMax;
  432.             /* select last */
  433.             AnSelect(anBarMax-1,FALSE);
  434.         }
  435.         else {
  436.             /* select last */
  437.             AnSelect(anNumBars-1,FALSE);
  438.         }
  439.         
  440.         AnRenderBars(anTopBar);
  441.         AnRefresh();
  442.         break;
  443.  
  444.     case SHIFTLEFT:
  445.         if (anSelBar == -1)
  446.             AnSelect(0,TRUE);
  447.         else if (anTopBar < anBarMax) {
  448.             anTopBar=0;
  449.             AnSelect(0,FALSE);
  450.             AnRenderBars(anTopBar);
  451.             AnRefresh();
  452.         }
  453.         else {
  454.             col = anSelBar-anTopBar;
  455.             anTopBar -= anBarMax-1;
  456.             AnSelect(col,FALSE);
  457.             AnRenderBars(anTopBar);
  458.             AnRefresh();
  459.         }
  460.         break;
  461.  
  462.     case SHIFTRIGHT:
  463.         if (anSelBar == -1)
  464.             AnSelect(0,TRUE);
  465.         else if (anNumBars <= anBarMax) {
  466.             AnSelect(anNumBars-1,TRUE);
  467.         }
  468.         else if (anTopBar == anNumBars-anBarMax) 
  469.             AnSelect(anBarMax-1,TRUE);
  470.         else if (anNumBars - (anTopBar + anBarMax) < anBarMax) {
  471.             anTopBar = anNumBars-anBarMax;
  472.             AnSelect(anBarMax-1,FALSE);
  473.             AnRenderBars(anTopBar);
  474.             AnRefresh();
  475.         }
  476.         else {
  477.             col = anSelBar-anTopBar;
  478.             anTopBar += anBarMax-1;
  479.             AnSelect(col,FALSE);
  480.             AnRenderBars(anTopBar);
  481.             AnRefresh();
  482.         }
  483.         break;
  484.  
  485.     case LEFT:
  486.         if (anSelBar == -1)
  487.             AnSelect(0,TRUE);
  488.         else if (anSelBar == 0)
  489.             break;
  490.         else if (anSelBar == anTopBar) {
  491.             if (anTopBar > 0) {
  492.                 anTopBar--;
  493.                 AnSelect(0,FALSE);
  494.                 AnRenderBars(anTopBar);
  495.                 AnRefresh();
  496.             }
  497.         }
  498.         else AnSelect(anSelBar-anTopBar-1,TRUE);
  499.         break;
  500.  
  501.     case RIGHT:
  502.         if (anSelBar == -1)
  503.             AnSelect(0,TRUE);
  504.         else if (anSelBar == anNumBars-1)
  505.             break;
  506.         else if (anSelBar == anTopBar + anBarMax-1) {
  507.             if (anTopBar+anBarMax < anNumBars) {
  508.                 anTopBar++;
  509.                 AnSelect(anBarMax-1,FALSE);
  510.                 AnRenderBars(anTopBar);
  511.                 AnRefresh();
  512.             }
  513.         }
  514.         else AnSelect(anSelBar-anTopBar+1,TRUE);
  515.  
  516.         break;
  517.  }
  518.  
  519.  AnScrollBars(GID_ANSCROL,anTopBar,anNumBars,anBarMax);
  520.  AnBalance(); 
  521. }
  522.  
  523. /*******************************************************/
  524. BOOL AnHandleGadget(struct IntuiMessage *imsg)
  525. {
  526.  BOOL done = FALSE;
  527.  struct Gadget *gad = (struct Gadget *)(imsg->IAddress);
  528.  UWORD code = imsg->Code;
  529.  
  530.  switch (gad->GadgetID) {
  531.     case GID_ANTYPE:
  532.         graphtype = code;
  533.         AnRenderBars(anTopBar);
  534.         AnRefresh();
  535.         AnBalance();
  536.         break;
  537.  
  538.     case GID_ANOK:
  539.         done=TRUE;
  540.         break;
  541.  }
  542.  
  543.  GF_ReplyIMsg(imsg);
  544.  return (done);
  545. }
  546.  
  547. /********************************************************/
  548. BOOL AnHandleGadgetDown(struct IntuiMessage *imsg)
  549. {
  550.  struct Gadget *gad = (struct Gadget *)(imsg->IAddress);
  551.  UWORD code = imsg->Code;
  552.  BOOL done = FALSE;
  553.  
  554.  switch (gad->GadgetID) {
  555.     case GID_ANFIELD:
  556.         if (AnHitTest(imsg->Micros, imsg->Seconds, imsg->MouseX,imsg->MouseY)) {
  557.             anFinalSel = anSelBar;
  558.             done = TRUE;
  559.         }
  560.         else AnBalance();
  561.         break;
  562.  
  563.     case GID_ANSCROL:
  564.         anTopBar = code;
  565.         AnRenderBars(anTopBar);
  566.         AnRefresh();
  567.         break;
  568.  
  569.     case GID_ANSCALE:
  570.         /*anBarHeight = code;*/
  571.         anBarScale = (float)code/(float)barScale;
  572.         AnRenderBars(anTopBar);
  573.         AnRefresh();
  574.         break;
  575.  }
  576.  
  577.  return (done);
  578. }
  579.  
  580.  
  581. /********************************************************/
  582. void AnHandleMouseMove(struct IntuiMessage *imsg)
  583. {
  584.  struct Gadget *gad = (struct Gadget *)(imsg->IAddress);
  585.  UWORD code = imsg->Code;
  586.  
  587.  switch (gad->GadgetID) {
  588.     case GID_ANSCROL:
  589.         anTopBar = code;
  590.         AnRenderBars(anTopBar);
  591.         AnRefresh();
  592.         break;
  593.  
  594.     case GID_ANSCALE:
  595.         /*barScale = code;*/
  596.         anBarScale = (float)code/(float)barScale;
  597.         AnRenderBars(anTopBar);
  598.         AnRefresh();
  599.         break;
  600.  }
  601.  
  602. }
  603.  
  604. /*******************************************************/
  605. void AnBalance(void)
  606. {
  607.  filterNode *filt;
  608.  amountType zero =0;
  609.  balanceType bal;
  610.  
  611.  if (anSelBar == -1)
  612.     return;
  613.  
  614.  /* calculate the balance */
  615.  filt = (filterNode *)DataOrd2Node((struct List *)&filtered,anSelBar);
  616.  switch (graphtype) {
  617.     case 0: memcpy(&bal,&filt->runningBal, sizeof(balanceType));
  618.         break;
  619.  
  620.     case 1: memcpy(&bal,&filt->filterBal, sizeof(balanceType));
  621.         break;
  622.  
  623.     case 2:    if (filt->entry->flags & VOIDED && filt->entry->type == CHECKTYPE)
  624.             DataInitBal(DEPOSITTYPE,&zero,&bal);
  625.         else    {
  626.             DataInitBal(filt->entry->type,&filt->entry->amount,&bal);
  627.         }
  628.         break;
  629.  }
  630.  
  631.  DataBuildBal(usrAccount.decimal,&bal,anBalance);
  632.  GF_SetGadgetAttrs(analGUI,an_gadgetspecs[GID_ANBAL].gs_Gadget,
  633.     GTTX_Text,anBalance,
  634.     TAG_DONE);
  635. }
  636.  
  637. /*******************************************************/
  638. void AnGraphInit(void)
  639. {
  640.  balanceType runbal;
  641.  
  642.  anBalance[0] = 0;
  643.  GF_SetGadgetAttrs(analGUI,an_gadgetspecs[GID_ANBAL].gs_Gadget,
  644.     GTTX_Text,anBalance,
  645.     TAG_DONE);
  646.  
  647.  /* grab window RP */
  648.  GF_GetGUIAttr(analGUI, GUI_Window, &anWin, TAG_DONE);
  649.  anRP = anWin->RPort;
  650.  
  651.  /* reset state vars */
  652.  anSelBar = selRow;
  653.  anNumBars = entryCount;
  654.  anFinalSel = -1;
  655.  
  656.  /* turn on mouse clicks in field */
  657.  AN_MainSpecs[GID_ANFIELD]->gs_Gadget->Activation |= GACT_IMMEDIATE;
  658.  
  659.  /* running balances and barmax */
  660.  runbal = DataRunningBals(&entries,&filtered);
  661.  barScale = runbal.dollar; /* round off cents */
  662.  anBarScale = (float)anBarHeight / (float)barScale;
  663.  
  664.  AnFilterBal();
  665.  
  666.  /* if selrow, render around selrow in middle */
  667.  if (anSelBar != -1) {
  668.     if (anSelBar < anBarMax)
  669.         anTopBar = 0;
  670.     else if (anNumBars - anSelBar <= anBarMax)
  671.         anTopBar = anNumBars - anBarMax;
  672.     else    anTopBar = anSelBar - (anBarMax/2);
  673.     
  674.  }
  675.  else {
  676.      /* render from rightmost */
  677.     if (anBarMax > anNumBars)
  678.           anTopBar = 0;
  679.     else
  680.         anTopBar = anNumBars-anBarMax;
  681.  }
  682.  
  683.  /* prep scroll bars */
  684.  anTopScale = anBarHeight;
  685.  AnScrollBars(GID_ANSCROL,anTopBar,anNumBars,anBarMax);
  686.  AnScrollBars(GID_ANSCALE,anBarHeight,anBarHeight*20,anBarHeight);
  687.  
  688.  AnRenderBars(anTopBar);
  689.  
  690.  /* refresh display */
  691.  AnRefresh();
  692.  
  693.  if (anSelBar != -1)
  694.     AnBalance();
  695. }
  696.  
  697. /********************************************************/
  698. void AnScrollBars(long bar, long top, long total, long visible)
  699. {
  700.   GF_SetGadgetAttrs(analGUI,AN_MainSpecs[bar]->gs_Gadget,
  701.     GTSC_Top, top,
  702.     GTSC_Total, total,
  703.     GTSC_Visible, visible,
  704.     TAG_DONE);
  705. }
  706.  
  707. /********************************************************/
  708. void AnDeselect(BOOL towin)
  709. {
  710.  BYTE oldmode, oldmask;
  711.  ULONG height,top, row = anSelBar;
  712.  
  713.  if (anSelBar == -1) return;
  714. ;
  715.  anSelBar = -1;
  716.  
  717.  /* if not visible, skip graphical rendering */
  718.  if (row < anTopBar || row > anTopBar+anBarMax-1)
  719.         return; 
  720.  
  721.  /* make zero based */
  722.  row -= anTopBar;
  723.  
  724.  /* vert color over bar */
  725.  if (towin) {
  726.     oldmode = anRP->DrawMode;
  727.     oldmask = anRP->Mask;
  728.     SetDrMd(anRP,COMPLEMENT);
  729.     SafeSetWriteMask(anRP,0x2);
  730.  
  731.     RectFill(anRP,
  732.             anLeft + anBarWidth*row, anTop,
  733.             anLeft + anBarWidth*(row+1)-1,anTop+anHeight-1 );
  734.  
  735.     WaitBlit();
  736.  
  737.     SetDrMd(anRP,oldmode);
  738.     SafeSetWriteMask(anRP,oldmask);
  739.  
  740. }
  741.  
  742. /* now render it in the real buffer */
  743. oldmode = anWorkRP.DrawMode;
  744. oldmask = anWorkRP.Mask;
  745. SetDrMd(&anWorkRP,COMPLEMENT);
  746. SafeSetWriteMask(&anWorkRP,0x2);
  747.  
  748. RectFill(&anWorkRP,
  749.             anBarWidth*row, 0,
  750.             anBarWidth*(row+1)-1,anHeight-1 );
  751.  
  752. WaitBlit();
  753.  
  754. SetDrMd(&anWorkRP,oldmode);
  755. SafeSetWriteMask(&anWorkRP,oldmask);
  756.  
  757. anSelBar = -1;
  758.  
  759. }
  760.  
  761. /********************************************************/
  762. void AnSelect(int row, BOOL towin)
  763. {
  764. BYTE oldmode,oldmask;
  765. ULONG height,top;
  766.  
  767. if (anSelBar == row + anTopBar)
  768.     return;
  769.  
  770. AnDeselect(towin);
  771.  
  772. /* vert color over bar */
  773. if (towin) {
  774.     oldmode = anRP->DrawMode;
  775.     oldmask = anRP->Mask;
  776.     SetDrMd(anRP,COMPLEMENT);
  777.     SafeSetWriteMask(anRP,0x2);
  778.  
  779.     RectFill(anRP,
  780.             anLeft + anBarWidth*row, anTop,
  781.             anLeft + anBarWidth*(row+1)-1,anTop+anHeight-1 );
  782.  
  783.     WaitBlit();
  784.  
  785.     SetDrMd(anRP,oldmode);
  786.     SafeSetWriteMask(anRP,oldmask);
  787.  
  788. }
  789.  
  790. /* now render it in the real buffer */
  791. oldmode = anWorkRP.DrawMode;
  792. oldmask = anWorkRP.Mask;
  793. SetDrMd(&anWorkRP,COMPLEMENT);
  794. SafeSetWriteMask(&anWorkRP,0x2);
  795.  
  796. RectFill(&anWorkRP,
  797.             anBarWidth*row, 0 ,
  798.             anBarWidth*(row+1)-1,anHeight-1 );
  799.  
  800. WaitBlit();
  801.  
  802. SetDrMd(&anWorkRP,oldmode);
  803. SafeSetWriteMask(&anWorkRP,oldmask);
  804.  
  805. anSelBar = row+anTopBar;
  806. }
  807.  
  808.  
  809. /********************************************************/
  810. BOOL AnHitTest(ULONG Micros, ULONG Seconds, ULONG x, ULONG y)
  811. {
  812.  ULONG col,test;
  813.  static LONG lastcol = -1;
  814.  BOOL retval = FALSE;
  815.  static ULONG micros = 0, secs = 0;
  816.  
  817.   if (anBarMax > anNumBars)
  818.     test = anNumBars;
  819.  else    test = anBarMax;
  820.  
  821.  /* quick clip of analysis gadget */
  822.  if (x < anLeft || x > anWidth+anLeft ||
  823.      y < anTop  || y > anHeight+anTop )
  824.           return (FALSE);
  825.  
  826.  
  827.  /* calc row */
  828.  x -= anLeft;
  829.  col = x / anBarWidth;
  830.  
  831.  /* ok, is it a valid col? */
  832.  if (col < test) {
  833.     if (DoubleClick(secs,micros,Seconds,Micros) && lastcol == col) {
  834.         retval = TRUE;
  835.     }
  836.        AnSelect(col, TRUE);
  837.  }
  838.  
  839.  micros = Micros;
  840.  secs = Seconds;
  841.  lastcol = col;
  842.  
  843.  return (retval);
  844.  
  845. }
  846.  
  847. /********************************************************/
  848. void AnRenderBars(int bar)
  849. {
  850. filterNode *filter;
  851. long  barx, bary, barh;
  852. BOOL neg = 0;
  853. int x;
  854. int sb = anSelBar;
  855.  
  856. bar++;
  857.  
  858.  
  859. /* clear area */
  860. SetAPen(&anWorkRP,DETAILPEN);
  861. /*RectFill(&anWorkRP,0,0,anWidth,anHeight);*/
  862. SetRast(&anWorkRP, DETAILPEN);
  863.  
  864. filter = (filterNode *)DataOrd2Node((struct List *)&filtered,bar-1);
  865. for (x=bar;x<=anNumBars && x < bar + anBarMax; x++) {
  866.  
  867.     barx = (x-bar)*anBarWidth;
  868.     if (filter->entry->flags & VOIDED)
  869.         barh=0;
  870.     else {
  871.         if (graphtype == 2) {
  872.             barh = filter->entry->amount / decimalModulos[usrAccount.decimal];
  873.             if (barh < 0) {
  874.                 neg = 1;
  875.                 barh *= -1;
  876.             }
  877.         }
  878.         else if (graphtype == 1) {
  879.             barh = filter->filterBal.dollar;
  880.             neg = filter->filterBal.neg;
  881.         }
  882.         else    {
  883.             barh = filter->runningBal.dollar;
  884.             neg = filter->runningBal.neg;
  885.         }
  886.     }
  887.  
  888.     bary = anBarHeight;
  889.     if (neg) {
  890.         barh = barh*anBarScale;
  891.         if (barh >= anBarHeight) {
  892.             SetAPen(&anWorkRP,SHINEPEN);
  893.             Move(&anWorkRP,barx+1,anHeight-1);
  894.             Draw(&anWorkRP,barx+anBarWidth-2,anHeight-1);
  895.             barh = anBarHeight-2;
  896.         }
  897.  
  898.         /*scoot below the dashed line */
  899.         bary += barh;
  900.         barh = anBarHeight;
  901.     }
  902.     else     {
  903.         barh = (long)(barh*anBarScale); 
  904.         if (barh  >= anBarHeight) {
  905.             SetAPen(&anWorkRP,SHINEPEN);
  906.             Move(&anWorkRP,barx+1,0);
  907.             Draw(&anWorkRP,barx+anBarWidth-2,0);
  908.             barh = anBarHeight-1;
  909.         }
  910.         barh = anBarHeight - barh;
  911.     }
  912.  
  913.     if (filter->entry->type == DEPOSITTYPE) 
  914.         SetAPen(&anWorkRP, TEXTPEN);
  915.     else    SetAPen(&anWorkRP, BLOCKPEN);
  916.  
  917.     RectFill(&anWorkRP, barx + 1, barh, barx + anBarWidth - 2, bary );
  918.     WaitBlit();
  919.  
  920.     filter = (filterNode*) filter->node.mln_Succ;
  921. }
  922.  
  923. /* draw dashed middle line */
  924. SetAPen(&anWorkRP,SHINEPEN);
  925. SetDrPt(&anWorkRP,0xaaaa);
  926. Move(&anWorkRP,0,anHeight/2);
  927. Draw(&anWorkRP,anWidth,anHeight/2);
  928. SetDrPt(&anWorkRP,~0);
  929.  
  930. /* is the selected bar visible? */
  931. if (anSelBar != -1 && anSelBar >= anTopBar && anSelBar <= anTopBar+anBarMax-1) {
  932.     sb = anSelBar;
  933.     anSelBar = -1;
  934.     AnSelect(sb-anTopBar,FALSE);
  935. }
  936. }
  937.  
  938. /********************************************************/
  939. void AnRefresh(void)
  940. {
  941. /*
  942.  BltBitMapRastPort(anWorkRP.BitMap,0,0,anRP,anLeft,anTop,
  943.         anWidth,anHeight,0xc0);
  944.  WaitBlit();
  945. */
  946.  
  947. ClipBlit(&anWorkRP,0,0,anRP,anLeft,anTop,anWidth,anHeight,(ULONG)0xc0);
  948. }
  949.  
  950. /*****************************************************************/
  951. BOOL AnalysisSetup(void)
  952. {
  953.  if (AnalysisCreate() == FALSE) {
  954.     AnalysisFree();
  955.     return (FALSE);
  956.  }
  957.  
  958.  return (TRUE);
  959. }
  960.  
  961. /*****************************************************************/
  962. BOOL AnalysisCreate(void)
  963. {
  964.  int x;  
  965.  
  966.  /* define geometry (-2 accounts for shadowing border) */
  967.  anWidth =  AN_MainSpecs[GID_ANFIELD]->gs_Gadget->Width - 4;
  968.  anHeight=  AN_MainSpecs[GID_ANFIELD]->gs_Gadget->Height - 2;
  969.  anTop   =  AN_MainSpecs[GID_ANFIELD]->gs_Gadget->TopEdge + 1;
  970.  anLeft  =  AN_MainSpecs[GID_ANFIELD]->gs_Gadget->LeftEdge + 2;
  971.  
  972.  /* 
  973.   * extract information about our main window 
  974.   */
  975.    
  976.  GF_GetGUIAttr(gui, GUI_Window, &anWin, TAG_DONE);
  977.  
  978.  anRP = anWin->RPort;
  979.  andepth = anRP->BitMap->Depth;  
  980.             
  981.  /* 
  982.   * create working rast port area 
  983.   */
  984.  
  985.  /* create bitmap */
  986.  InitBitMap(&anbuffer,andepth, anWidth, anHeight);
  987.  
  988.  for (x=0;x<andepth;x++) {
  989.         anbuffer.Planes[x] = (PLANEPTR)AllocRaster(anWidth+1, 
  990.                                         anHeight+1);
  991.         if (anbuffer.Planes[x] == NULL) return (FALSE);
  992.  }
  993.  
  994.  /* create area buffer */
  995.  for (x=0;x<ANAREA_SIZE;x++) anAreaBuffer[x] =0;
  996.  InitArea(&anarea, anAreaBuffer, (ANAREA_SIZE*2)/5);
  997.  
  998.  /* create TmpRas */
  999.  antmprp = (void *)AllocVec((anWidth+1)*(anHeight+1), MEMF_CHIP);
  1000.  if (antmprp == NULL) return (FALSE);
  1001.  
  1002.  InitTmpRas(&antmp,antmprp,(anWidth+1)*(anHeight+1));
  1003.  
  1004.  /* link in to our work rastport */
  1005.  InitRastPort(&anWorkRP);
  1006.  anWorkRP.BitMap = &anbuffer;
  1007.  anWorkRP.AreaInfo = &anarea;
  1008.  anWorkRP.TmpRas = &antmp;
  1009.  anWorkRP.Layer = NULL;
  1010.  
  1011.  /* some tiny layout calcs */
  1012.  anBarWidth = regFont->tf_XSize;
  1013.  anBarMax = anWidth / anBarWidth;
  1014.  anBarHeight = anHeight / 2;
  1015.  
  1016.  return (TRUE);
  1017. }
  1018.  
  1019. /**************************************************************/
  1020. void AnalysisFree(void)
  1021. {
  1022.  int x;
  1023.  
  1024.  /*
  1025.   * anRP stuff
  1026.   */
  1027.        
  1028.  /* free up bitmap */
  1029.  for (x=0;x<andepth;x++)
  1030.         if (anbuffer.Planes[x] != NULL) {
  1031.                  FreeRaster(anbuffer.Planes[x],anWidth+1,anHeight+1);  
  1032.         }
  1033.         
  1034.  /* free anTmpRas */
  1035.  if (antmprp != NULL) {
  1036.         FreeVec(antmprp);
  1037.  }
  1038.  
  1039. }
  1040.  
  1041. /****************************************************************/
  1042. balanceType AnFilterBal(void)
  1043. {
  1044.  filterNode *next, *filt;
  1045.  amountType zero = 0;
  1046.  balanceType bal, largest;
  1047.  
  1048.  DataInitBal(DEPOSITTYPE,&zero,&largest);
  1049.  DataInitBal(DEPOSITTYPE,&zero,&bal);
  1050.  
  1051.  if (filtered.mlh_TailPred == &filtered)
  1052.     return largest;
  1053.  
  1054.  filt = (filterNode *)filtered.mlh_Head;
  1055.  while ((next = (filterNode *)filt->node.mln_Succ)) {
  1056.     if (filt->entry->flags & VOIDED)
  1057.         DataInitBal(DEPOSITTYPE,&zero,&filt->filterBal);
  1058.     else {
  1059.         DataAddBal(filt->entry->type,&filt->entry->amount,&bal);
  1060.         memcpy(&filt->filterBal,&bal, sizeof(balanceType));
  1061.  
  1062.         if (DataCmpBal(FALSE,&bal, &largest) == 1)
  1063.             memcpy(&largest,&bal,sizeof(balanceType));            
  1064.     }
  1065.  
  1066.     filt = next;
  1067.  }
  1068.  
  1069.  return largest; 
  1070. }
  1071.