/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  CHKBK.CPP                          Alan C. Partis                        */
/*                                     Copyright (C) AP MicroSystems, 1991   */
/*                                                                           */
/*  Description:   Contains the client code for the use of Field, Window,    */
/*       and Check objects to operate a checkbook program.                   */
/*                                                                           */
/*  Routines:      EditField()                                               */
/*                 FillRegisterWin()                                         */
/*                 FillXactWin()                                             */
/*                 GetRegister()                                             */
/*                 Page()                                                    */
/*                 ReleaseRegister()                                         */
/*                 RestoreWin()                                              */
/*                 SaveWin()                                                 */
/*                 StatementBalance()                                        */
/*                                                                           */
/*  Date      Initials  Comments                                             */
/*  -----------------------------------------------------------------------  */
/*  05-14-91  ACP       initial creation                                     */
/*  06-09-91  ACP       added file I/O and command line parameters           */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include <apms.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <fstream.h>
#include "chkbk.h"
#include <window.h>
#include <field.h>
#include "check.h"

//
// ----- global variables
//
word     record = 0;                   // current number of checks in system
                                       //  updated when register is read from
                                       //  file and when new checks created


void main(int argc, char *argv[])

{
    byte      checkhole;               // flag for check record renumbering
    int       done = NO;
    int       key;                     // input key stroke
    int       paged = FALSE;           // flags a Page key processing
    Field     *curfield;               // pointer to the active field
    int       rc;
    XACT      xact;
    char      filename[SZ_PATH];
    char      msgstr[FIELD_MAX];       // scratch space for output string
    void      *winsave;                // pointer to saved text window

//
// Fields in the Help Window
//
#define       SZ_HELP_LIST   18
charField     h1 (2,  2,  70, "F1  - View this HELP window.                                          ", FG_HELP, BG_HELP, DISPLAY, (Field *)NULL);
charField     h2 (2,  3,  70, "F2  - SAVE new work and return for more entries.                      ", FG_HELP, BG_HELP, DISPLAY, &h1);
charField     h3 (2,  4,  70, "F3  - QUIT this session WITHOUT saving new entries.                   ", FG_HELP, BG_HELP, DISPLAY, &h2);
charField     h4 (2,  5,  70, "F4  - SAVE new work and QUIT to DOS.  You are DONE.                   ", FG_HELP, BG_HELP, DISPLAY, &h3);
charField     h5 (2,  6,  70, "F5  - reserved for future use.                                        ", FG_HELP, BG_HELP, DISPLAY, &h4);
charField     h6 (2,  7,  70, "F6  - Calculate the balance as it should appear on your bank statement", FG_HELP, BG_HELP, DISPLAY, &h5);
charField     h7 (2,  8,  70, "F7  - Retrieve the check currently highlighted in the Browse window.  ", FG_HELP, BG_HELP, DISPLAY, &h6);
charField     h8 (2,  9,  70, "F8  - Delete the current transaction from the check book.             ", FG_HELP, BG_HELP, DISPLAY, &h7);
charField     h9 (2,  10, 70, "F9  - Toggle the \"cleared\" flag for the current transaction.          ", FG_HELP, BG_HELP, DISPLAY, &h8);
charField     h10(2,  11, 70, "F10 - Start a new check transaction.                                  ", FG_HELP, BG_HELP, DISPLAY, &h9);
charField     h11(2,  12, 70, "Page Up   - Previous page in Browse window.                           ", FG_HELP, BG_HELP, DISPLAY, &h10);
charField     h12(2,  13, 70, "Page Down - Next page in Browse window.                               ", FG_HELP, BG_HELP, DISPLAY, &h11);
charField     h13(2,  14, 70, "Up        - Previous check transaction.                               ", FG_HELP, BG_HELP, DISPLAY, &h12);
charField     h14(2,  15, 70, "Down      - Next check transaction.                                   ", FG_HELP, BG_HELP, DISPLAY, &h13);
charField     h15(2,  16, 70, "Ctrl Right- Update 'Date' field with previous date.                   ", FG_HELP, BG_HELP, DISPLAY, &h14);
charField     h16(2,  17, 70, "Ctrl Left - Update 'Date' field with next date.                       ", FG_HELP, BG_HELP, DISPLAY, &h15);
charField     h17(2,  18, 70, "                                                                      ", FG_HELP, BG_HELP, DISPLAY, &h16);
charField     h18(2,  19, 70, "                     press 'Esc' to continue . . .                    ", FG_HELP, BG_HELP, DISPLAY, &h17);


    //
    // initialize 'register' and 'help' listWindows
    //
    win_reg.WinInit(4, 17, 77, 23, SZ_REG_ITEMS, FG_REG, BG_REG, &Lr1);
    win_help.WinInit(5, 4, 76, 23, SZ_HELP_LIST, FG_HELP, BG_HELP, &h1);



    //
    //declare client code pointers for Checks
    //
    Check     *Head    = (Check *)NULL,
              *Browse  = (Check *)NULL,
              *Current = (Check *)NULL;
    Check     *tmpcheck= (Check *)NULL;


    //
    // check for proper command line
    //   and print help if necessary
    //
    if ((argc == 1) || !(strcmp(argv[1],"?"))) {
         cout << "\n\tChkBk - computerized check book register\n";
         cout << "\tCopyright (C) 1991\n";
         cout << "\tby AP MicroSystems\n";
         cout << "\n\tUsage:  CHKBK <filename>\n";
         cout << "\n\twhere\t<filename> is the name of your check book file\n";
         cout << "\n";
         exit(1);
    }
    else {
         //
         // retrieve filename and remove extension if any
         //
         strcpy(filename, argv[1]);
         strtok(filename, ".");        // replaces '.' with NULL if it exists
    }

    //
    // display the shareware banner
    //
    ShareWareBanner();

    
    win_desk.Display();
    gotoxy(12,25);
    textbackground(BLUE);
    textcolor(WHITE);
    cprintf("Copyright (C) AP MicroSystems, 1991.  All rights reserved");

    GetRegister(filename, Head, Current);   // will assign 'Head' and 'Current'

    //
    // if input file could not be opened, then Head will
    //   not be assigned.  Do not continue if that is
    //   the case.
    //
    if (!Head) {
         exit(1);
    }

    //
    // fill in the display fields and set
    //   initial windows and pointers
    //
    FillXactWin(Current, &xact);

    win_mess.Display();

    Browse = Current;
    FillRegisterWin(Browse, &r1);
    win_reg.Display();

    //
    // Update the Message window
    //
    sprintf(msgstr, "%d", Current->WhoRecord());
    MessRec.Update(msgstr);
    sprintf(msgstr, "%d", record);
    MessRecs.Update(msgstr);
    sprintf(msgstr, "%d", Browse->WhoRecord());
    MessBrws.Update(msgstr);
    win_mess.DisplayFields();

    win_xact.Display();
    curfield = &Number;
    curfield->Hilight(FG_HILIGHT, BG_HILIGHT);

    //
    // process keystrokes
    //
    key = EditField(Current, curfield);
    while (!done) {

         switch (key) {
              case PG_UP_KEY:
                   paged = Page(UP, Browse);
                   if (!paged)
                        BEEP();
                   paged = TRUE;
                   break;

              case PG_DOWN_KEY:
                   paged = Page(DOWN, Browse);
                   if (!paged)
                        BEEP();
                   paged = TRUE;
                   break;

              case TAB_KEY:
              case ENTER_KEY:
                   curfield->Display();
                   do {
                        curfield = curfield->Next();
                        rc = curfield->Hilight(FG_HILIGHT, BG_HILIGHT);
                   } while (rc != PASS);
                   break;

              case STAB_KEY:
                   curfield->Display();
                   do {
                        curfield = curfield->Prev();
                        rc = curfield->Hilight(FG_HILIGHT, BG_HILIGHT);
                   } while (rc != PASS);
                   break;

              case UP_KEY:
                   tmpcheck = Current->Prev();
                   if (tmpcheck != NULL)
                        Current = tmpcheck;
                   break;

              case DOWN_KEY:
                   tmpcheck = Current->Next();
                   if (tmpcheck != NULL)
                        Current = tmpcheck;
                   break;

              case F1_KEY:             // Help panel
                   //
                   // first, save the window area we are about to
                   //   overwrite, display the help window, and 
                   //   restore the desktop afterward.
                   //
                   _setcursortype(_NOCURSOR);
                   winsave = SaveWin(&win_help);
                   win_help.Display();
                   key = getch();
                   while (key != ESC_KEY) {
                        key = getch();
                   }
                   RestoreWin(&win_help, winsave);
                   _setcursortype(_NORMALCURSOR);
                   break;

              case F2_KEY:             // Save work
                   sprintf(msgstr, PLS_WAIT);
                   MessMess.Update(msgstr);
                   win_mess.DisplayFields();
                   ReleaseRegister(filename, Head);
                   GetRegister(filename, Head, Current);   
                   sprintf(msgstr, "");
                   MessMess.Update(msgstr);
                   win_mess.DisplayFields();
                   break;

              case F3_KEY:             // Quit without saving
                   done = YES;
                   break;

              case F4_KEY:             // Save and Quit
                   sprintf(msgstr, PLS_WAIT);
                   MessMess.Update(msgstr);
                   win_mess.DisplayFields();
                   ReleaseRegister(filename, Head);
                   done = YES;
                   break;

              case F6_KEY:             // Show statement balance
                   StatementBalance(Head, &MessMess);
                   win_mess.DisplayFields();
                   break;

              case F7_KEY:             // Retrieve Browsed check
                   Current = Browse;
                   break;

              case F8_KEY:             // Delete Check
                   if (record > 1) {
                        //
                        // set tmpcheck to the next check
                        //  in the list.  If the current check
                        //  is the end of the list, then go back.
                        //
                        tmpcheck = Current->Next();
                        checkhole = TRUE;
                        if (tmpcheck == NULL) {
                             tmpcheck = Current->Prev();
                             checkhole = FALSE;
                        }

                        //
                        // get rid of the current check and
                        //  point to the proper one.
                        //
                        record--;
                        Current->Remove();
                        delete Current;
                        Current = tmpcheck;

                        //
                        // renumber the record numbers to remove
                        //   the "checkhole" - tmpcheck already is
                        //   set to equal Current
                        //
                        if (checkhole) {
                             tmpcheck->NewRecord(tmpcheck->WhoRecord() - 1);
                             while ((tmpcheck = tmpcheck->Next()) != NULL) {
                                  tmpcheck->NewRecord(tmpcheck->WhoRecord() - 1);
                             }
                        }
                   }
                   break;

              case F9_KEY:             // Toggle check "cleared" flag
                   Current->Clear();
                   break;


              case F10_KEY:            // New Check

                   //
                   // go to the end of the line and then create 
                   //  a new check
                   //
                   while ((tmpcheck = Current->Next()) != NULL)
                        Current = tmpcheck;

                   tmpcheck = new Check;
                   tmpcheck->Add(0, NULL_STR, 0.0, 0.0, Current);
                   Current = tmpcheck;
                   Current->NewRecord(++record);

                   curfield = &Number;
                   break;


              default:
                   BEEP();
         }

         //
         // Update the register window
         //
         if (!paged) 
              Browse = Current;
         else 
              paged = FALSE;
         FillRegisterWin(Browse, &r1);
         win_reg.Update();
    
         //
         // Update the Message window
         //
         sprintf(msgstr, "%d", Current->WhoRecord());
         MessRec.Update(msgstr);
         sprintf(msgstr, "%d", record);
         MessRecs.Update(msgstr);
         sprintf(msgstr, "%d", Browse->WhoRecord());
         MessBrws.Update(msgstr);

         win_mess.DisplayFields();

         //
         // Fill the transaction window with the
         //  Current check's numbers
         //
         FillXactWin(Current, &xact);
         win_xact.DisplayFields();
         curfield->Hilight(FG_HILIGHT, BG_HILIGHT);

         if (!done)
              key = EditField(Current, curfield);

    }    // end of while not done

    //
    // reset screen and cursor - then exit
    //
    _setcursortype(_NORMALCURSOR);
    window(1,1,80,25);
    textbackground(BLUE);
    clrscr();

}   /* end of function main() */




/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  EditField()                        Alan C. Partis                        */
/*                                     Copyright (C) AP MicroSystems, 1991   */
/*                                                                           */
/*  Description:   Handles keyboard i/o for the given field.  Controls cursor*/
/*       location and properly updates the Field data.  This function returns*/
/*       the extended keystroke scan code that caused an end to the editing  */
/*       for this field.                                                     */
/*                                                                           */
/*  Input:    current                  pointer to current xact check         */
/*            curfield                 pointer to current field in xact      */
/*                                                                           */
/*  Output:   key                      key that caused end to editing        */
/*                                                                           */
/*  Date      Initials  Comments                                             */
/*  -----------------------------------------------------------------------  */
/*  06-30-91  ACP       initial creation                                     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int EditField(Check *current, Field *curfield)

{

    int   key;
    XACT  xact;
    char  buffer[FIELD_MAX];

    current->WhoCheck(&xact);

    key = curfield->Edit();

    switch (curfield->WhoID()) {

         case FID_NUMBER:
              ((charField *)curfield)->WhoData(buffer);
              xact.number = atoi(buffer);
              break;

         case FID_DATE:
              ((dateField *)curfield)->WhoData((void *)&(xact.date));
              break;

         case FID_DESC:
              ((charField *)curfield)->WhoData(xact.desc);
              wstrunc(xact.desc);      // remove trailing white space
              break;

         case FID_CHECK:
              curfield->WhoData((void *)&(xact.check));
              break;

         case FID_DEPOSIT:
              curfield->WhoData((void *)&(xact.deposit));
              break;

    }

    current->Edit(xact.number,
                  &(xact.date),
                  xact.desc,
                  xact.check,
                  xact.deposit);

    return(key);

}   /* end of function EditField() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  FillRegisterWin()                  Alan C. Partis                        */
/*                                     Copyright (C) AP MicroSystems, 1991   */
/*                                                                           */
/*  Description:   Gets the xaction info for a list of checks and updates    */
/*       the given list window with the data.                                */
/*                                                                           */
/*  Input:    check                    pointer to targeted check             */
/*                                                                           */
/*  Output:   headfield                head of field list to be updated      */
/*                                                                           */
/*  Date      Initials  Comments                                             */
/*  -----------------------------------------------------------------------  */
/*  09-18-91  ACP       initial creation                                     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void FillRegisterWin(Check *check, charField *headfield)

{

    Check     *tmp_check;
    XACT      xact;
    char      str[73];
    charField *field;
    int       i;
    int       target;

    //
    // first we must determine that we start with the earliest check
    //   that will guarentee to fill the entire window.
    //
    target = SZ_REG_LIST - 1;
    tmp_check = check;
    for (i = 0; i < SZ_REG_LIST; i++) {
         if (tmp_check->Prev() == NULL) {
              target = i;
              i = SZ_REG_LIST;
         }
         else {
              if (i < (SZ_REG_LIST - 1))
                   tmp_check = tmp_check->Prev();
         }
    }

    field = headfield;
    tmp_check->WhoCheck(&xact);
    for (i = 0; i < SZ_REG_LIST; i++) {
         //
         // set the browse strip
         //
         if (i == target) {
              field->NewFgnd(FG_LIST_BROWSE);
              field->NewBgnd(BG_LIST_BROWSE);
         }
         else {
              field->NewFgnd(FG_LIST);
              field->NewBgnd(BG_LIST);
         }

         sprintf(str, "%-4d³%.2d-%.2d-%.2d³%-32.32s³%7.2f³%7.2f³%7.2f³%1d", 
                                                       xact.number,
                                                       xact.date.da_mon,
                                                       xact.date.da_day,
                                                       xact.date.da_year % 100,
                                                       xact.desc,
                                                       xact.check,
                                                       xact.deposit,
                                                       xact.balance,
                                                       xact.cleared);
         field->Update(str);
         field = (charField *)(field->Next());
         tmp_check = tmp_check->Next();
         if (tmp_check != NULL)
              tmp_check->WhoCheck(&xact);
         else
              i = SZ_REG_LIST;
    }

}   /* end of function FillRegisterWin() */




/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  FillXactWin()                      Alan C. Partis                        */
/*                                     Copyright (C) AP MicroSystems, 1991   */
/*                                                                           */
/*  Description:   Gets the xaction info for the given current Check and     */
/*       fills the proper fields with updated data.                          */
/*                                                                           */
/*  Input:    Current                  pointer to current xact check         */
/*            xact                     pointer to xact work space            */
/*                                                                           */
/*  Output:   none                                                           */
/*                                                                           */
/*  Date      Initials  Comments                                             */
/*  -----------------------------------------------------------------------  */
/*  05-26-91  ACP       initial creation                                     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void FillXactWin(Check *Current, XACT *xact)

{
    char      tmpstr[80];

    Current->WhoCheck(xact);

    if (xact->number == 0)
         sprintf(tmpstr,"");
    else
         sprintf(tmpstr,"%4d",xact->number);
    Number.Update(tmpstr);
    Date.Update(&(xact->date));
    Desc.Update(xact->desc);
    Chk.Update((void *)&(xact->check));
    Dep.Update((void *)&(xact->deposit));
    Bal.Update((void *)&(xact->balance));

    if (xact->cleared)
         Clr.Update("Yes");
    else
         Clr.Update("No");

}   /* end of function FillXactWin() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  GetRegister()                      Alan C. Partis                        */
/*                                     Copyright (C) AP MicroSystems, 1991   */
/*                                                                           */
/*  Description:   Takes appropriate measures (opens a file) to obtain the   */
/*       current checkbook register.  To do this, new check objects are      */
/*       created as needed.  The Head pointer is assigned to the first check */
/*       in the list and the Current pointer is assigned the last.           */
/*                                                                           */
/*  Input:    none                                                           */
/*                                                                           */
/*  Output:   Head                     pointer to first check in list        */
/*            Current                  pointer to final check in list        */
/*                                                                           */
/*  Date      Initials  Comments                                             */
/*  -----------------------------------------------------------------------  */
/*  06-08-91  ACP       initial creation                                     */
/*  11-12-91  ACP       update record counter                                */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void GetRegister(char *filename, Check*& head, Check*& current)

{

    Check     *check1;
    Check     *check2;
    char      file[128];
    char      ch;                      // temp holder to help check for eof
    _Date     date;

    strcpy(file, filename);
    strcat(file, ".chk");
    ifstream  fp(file);                // declare/open input file

    if (fp) {
         //
         // read record from file and create
         //   new check object instance
         //   and assign the next unique      
         //   global record number
         //
         check1 = new Check;
         check1->Read(fp, (Check *)NULL);
         check1->NewRecord(++record);
         head = check1;

         fp.get(ch);
         while (!fp.eof()) {
              fp.putback(ch);          // if not at eof, then put char back
              check2 = new Check;
              check2->Read(fp, check1);
              check1 = check2;
              check1->NewRecord(++record);

              fp.get(ch);
         }

         current = check1;
    }
    else {
         check1 = new Check;
         check1->NewRecord(++record);
         getdate(&date);
         check1->Edit(0,
                      &date,
                      "",
                      0.0,
                      0.0);
         current = head = check1;
    }

}   /* end of function GetRegister() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  Page()                             Alan C. Partis                        */
/*                                     Copyright (C) AP MicroSystems, 1991   */
/*                                                                           */
/*  Description:   Takes the current Browse pointer and shifts it up or      */
/*       down depending upon the flag input.  If successful in any shifting  */
/*       TRUE is returned, otherwise FALSE is returned.                      */
/*                                                                           */
/*  Input:    flag                     indicates Page UP or Page DOWN        */
/*                                                                           */
/*  Output:   Browse                   pointer to new Browse pointer         */
/*            rc                       TRUE if shifted, FALSE otherwise      */
/*                                                                           */
/*  Date      Initials  Comments                                             */
/*  -----------------------------------------------------------------------  */
/*  10-20-91  ACP       initial creation                                     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int  Page(int flag, Check*& Browse)

{

    int       i;
    int       rc;

    rc = FALSE;
    for (i = 0; i < SZ_REG_LIST; i++) {
         if (flag == UP) {
              if (Browse->Prev() != NULL) {
                   Browse = Browse->Prev();
                   rc = TRUE;
              }
         }
         else {
              if (Browse->Next() != NULL) {
                   Browse = Browse->Next();
                   rc = TRUE;
              }
         }
    }

    return(rc);

}   /* end of function Page() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  ReleaseRegister()                  Alan C. Partis                        */
/*                                     Copyright (C) AP MicroSystems, 1991   */
/*                                                                           */
/*  Description:   Starts with the beginning of the given list, writes each  */
/*       object to a file, and deallocates their memory.  Leaves Head        */
/*       pointing to NULL.                                                   */
/*                                                                           */
/*  Input:    Head                     pointer to beginning of list          */
/*                                                                           */
/*  Output:   none                                                           */
/*                                                                           */
/*  Date      Initials  Comments                                             */
/*  -----------------------------------------------------------------------  */
/*  06-08-91  ACP       initial creation                                     */
/*  11-12-91  ACP       update record counter                                */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void ReleaseRegister(char *filename, Check*& head)

{
    Check     *tmp1,
              *tmp2;
    char      file[128];

    strcpy(file, filename);
    strcat(file, ".chk");
    ofstream  fp(file);                // declare/open output file

    if (fp) {
         tmp1 = head;
         head = NULL;

         //
         // walk register list, releasing memory
         //  and writing records as we go
         //
         while (tmp1->Next() != NULL) {
              tmp2 = tmp1->Next();
              tmp1->Remove();
              *tmp1 >> fp;
              record--;
              delete tmp1;

              tmp1 = tmp2;
         }

         //
         // now take care of last one
         //
         tmp1->Remove();
         *tmp1 >> fp;
         record--;
         delete tmp1;
    }
    else
         cout << "Could not find " << file << " for output\n";

}   /* end of function ReleaseRegister() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  RestoreWin()                       Alan C. Partis                        */
/*                                     Copyright (C) AP MicroSystems, 1991   */
/*                                                                           */
/*  Description:   Restores a given display buffer to the screen at the      */
/*       coordinates of the given window.  Frees memory used by buffer.      */
/*                                                                           */
/*  Input:    buffer                   pointer to saved info                 */
/*            win                      pointer to window for coordinates     */
/*                                                                           */
/*  Output:   none                                                           */
/*                                                                           */
/*  Date      Initials  Comments                                             */
/*  -----------------------------------------------------------------------  */
/*  12-02-91  ACP       initial creation                                     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void     RestoreWin(Window *win, void *buffer)

{

    int       x1, x2, y1, y2;

    //
    // get the coordinates for the window in question, then
    //   restore the buffer
    //
    x1 = win->WhoX1();
    x2 = win->WhoX2();
    y1 = win->WhoY1();
    y2 = win->WhoY2();

    puttext(x1, y1, x2+2, y2+1, buffer);

    free(buffer);

}   /* end of function RestoreWin() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  SaveWin()                          Alan C. Partis                        */
/*                                     Copyright (C) AP MicroSystems, 1991   */
/*                                                                           */
/*  Description:   Saves a portion of the Text mode screen into a dynamically*/
/*       allocated  buffer.  Coordinates for the area to be saved are taken  */
/*       from the given window.                                              */
/*                                                                           */
/*  Input:    win                      pointer to window for coordinates     */
/*                                                                           */
/*  Output:   buffer                   pointer to saved info                 */
/*                                                                           */
/*  Date      Initials  Comments                                             */
/*  -----------------------------------------------------------------------  */
/*  12-02-91  ACP       initial creation                                     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void     *SaveWin(Window *win)

{

    int       x1, x2, y1, y2;
    void      *buffer;

    //
    // get the coordinates for the window in question, then
    //   allocate the buffer
    //
    x1 = win->WhoX1();
    x2 = win->WhoX2();
    y1 = win->WhoY1();
    y2 = win->WhoY2();

    buffer = malloc(((x2+2) - x1) * ((y2+1) - y1) * 2);

    gettext(x1, y1, x2+2, y2+1, buffer);

    return (buffer);

}   /* end of function SaveWin() */



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  ShareWareBanner()                  Alan C. Partis                        */
/*                                     Copyright (C) AP MicroSystems, 1991   */
/*                                                                           */
/*  Description:   Displays a full screen message about the purpose of this  */
/*       shareware product.                                                  */
/*                                                                           */
/*  Input:    none                                                           */
/*                                                                           */
/*  Output:   none                                                           */
/*                                                                           */
/*  Date      Initials  Comments                                             */
/*  -----------------------------------------------------------------------  */
/*  12-06-91  ACP       initial creation                                     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void     ShareWareBanner()

{

    textbackground(BLUE);
    textcolor(LIGHTRED);
    _setcursortype(_NOCURSOR);
    clrscr();

    cprintf("\r\n");
    cprintf("                                   CheckBook\r\n");
    textcolor(WHITE);
    cprintf("\r\n");
    cprintf("                       Copyright(C) 1991, AP MicroSystems\r\n");
    cprintf("\r\n");
    cprintf("\r\n");
    cprintf("\r\n");
    cprintf("        This product is published as shareware and as such, you are\r\n");
    cprintf("        authorized to freely distribute it for evaluation purposes\r\n");
    cprintf("        only.  If you find that ");
    textcolor(LIGHTRED);
    cprintf("CheckBook");
    textcolor(WHITE);
    cprintf(" suits your needs please send\r\n");
    cprintf("        $10 to the address below for the latest registered version.\r\n");
    cprintf("        This will also entitle you to complete documentation, further\r\n");
    cprintf("        upgrade notices, and future product discounts.\r\n");
    cprintf("\r\n");
    cprintf("        Please help keep the spirit of shareware alive.\r\n");
    cprintf("\r\n");
    cprintf("\r\n");
    cprintf("\r\n");
    cprintf("        AP MicroSystems\r\n");
    cprintf("        526 Jaeger Drive\r\n");
    cprintf("        Delray Beach, FL 33444\r\n");
    cprintf("\r\n");
    cprintf("\r\n");
    cprintf("\r\n");
    cprintf("                        press any key to continue . . .");


    //
    // pause to wait for a key to continue
    //
    getch();
    _setcursortype(_NORMALCURSOR);
    clrscr();


}   /* end of function ShareWareBanner() */




/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  StatementBalance()                 Alan C. Partis                        */
/*                                     Copyright (C) AP MicroSystems, 1991   */
/*                                                                           */
/*  Description:   Traverses the list of given checks to derive a current    */
/*       statement balance given the currently "cleared" and yet to be       */
/*       "cleared" entries.  The result is placed in the given field.        */
/*                                                                           */
/*  Input:    head                     pointer to beginning of list          */
/*            output                   pointer to field for output string    */
/*                                                                           */
/*  Output:   none                                                           */
/*                                                                           */
/*  Date      Initials  Comments                                             */
/*  -----------------------------------------------------------------------  */
/*  08-23-91  ACP       initial creation                                     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void     StatementBalance(Check *head, charField *output)

{

    Check     *current;                // pointer travelling through list
    float     balance;                 // running statement balance
    XACT      xact;                    // current check's transaction info
    char      str[FIELD_MAX];          // scratch space for output string

    balance = 0.0;

    //
    // Must start by getting the current pointer to the tail of the 
    //  list to retrieve the current checkbook balance.
    //
    current = head;
    while ((current->Next()) != NULL)
         current = current->Next();

    //
    // initialize running balance
    //
    if (current != NULL)
         balance = current->Balance();

    //
    // gather data to determine proper balance
    //
    while (current != NULL) {
         current->WhoCheck(&xact);
         if (xact.cleared == NO) {
              balance += xact.check;
              balance -= xact.deposit;
         }
         current = current->Prev();
    }

    //
    // generate output string
    //
    sprintf(str, "%s %.2f", STMT_BAL, balance);
    output->Update(str);

}   /* end of function StatementBalance() */



  Copyright © Thundernet Development Group Inc., 2003.
All rights reserved.