/***************************************************************************
 *                                                                         *
 *   AUDIT.C                                                               *
 *                                                                         *
 *   Copyright (c) 1992-1997 Galacticomm, Inc.      All Rights Reserved.   *
 *                                                                         *
 *   Audit trail screen code                                               *
 *                                                                         *
 *                                            - Robert A. Rose 02/14/92    *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "oprlow.h"

#define FILREV "$Revision: 7 $"

VOID audupd(VOID);
UINT audkey(UINT scncod);
VOID scascn(INT num);
VOID aud1st(VOID);
VOID fasadd(VOID);
VOID audPrintEntry(const struct audOldStyle *entry);

extern INT acchdl;                 /* handle for the account screen        */
INT audhdl;                        /* audit screen handle                  */
extern INT ehdl;                   /* handle for the graph screen          */

extern INT stthue;                 /* Audit Trail display attribute code   */

struct scrnid audiscn={
     "wgsaut.bin",                 /* screen filename                      */
     3040,                         /* length of screen (4000 for full scrn)*/
     ALT_D,                        /* select scan code (from main screen)  */
                                   /* ala 'Keyboard Accelerator'           */
     NULL,                         /* screen going away routine            */
     NULL,                         /* screen repaint routine               */
     audkey,                       /* key handler routine                  */
     audupd,                       /* occasional update routine            */
     300,                          /* seconds between occasional updates   */
     0,                            /* seconds to go before next update     */
     NULL,                         /* called every cycle when displayed    */
     2,0,                          /* current cursor position on screen    */
     0,                            /* does cursor move?                    */
     1,                            /* should screen scroll?                */
     1,1,70,16,                    /* scrolling for window (default)       */
     NULL,                         /* perm. save buffer                    */
     NULL                          /* current location of screen           */
};

#define NUMOFFP 8                  /* # audit trail entries visible at once*/
#define NOENTRIES 0xFFFFFFFFL      /* position if audit trail empty        */

extern INT atmess;                 /* summary audit moved from bottom?     */
extern ULONG sumLastVisible;       /* last audit trail entry on summary scr*/

ULONG audLastVisible;              /* last audit trail entry on audit scrn */
GBOOL audMoved=FALSE;              /* user moved audit trail from bottom?  */

VOID
audupd(VOID)                       /* reset audit trail to bottom          */
{
     ULONG lastRec;

     lastRec=audLastRec();
     if (!audMoved && audLastVisible != lastRec) {
          audLastVisible=lastRec;
          aud1st();
     }
     audMoved=FALSE;
     if (atmess == 0 && sumLastVisible != lastRec) {
          sumLastVisible=lastRec;
          iniaud();
     }
     atmess=0;
}

UINT
audkey(                            /* Audit screen keystroke handler       */
UINT scncod)                       /*   keystroke scan code                */
{
     ULONG nRecs;

     switch (scncod) {
     case TAB:
          scn2mai(ehdl);
          break;
     case BAKTAB:
          scn2mai(acchdl);
          break;
     case CRSRUP:
          scascn(-1);
          break;
     case CRSRDN:
          scascn(1);
          break;
     case PGUP:
          scascn(-NUMOFFP);
          break;
     case PGDN:
          scascn(NUMOFFP);
          break;
     case HOME:
          nRecs=audLastRec();
          if (nRecs != NOENTRIES) {
               nRecs=min(NUMOFFP-2,nRecs);
          }
          if (nRecs != audLastVisible) {
               audLastVisible=nRecs;
               aud1st();
               audMoved=TRUE;
          }
          break;
     case END:
          nRecs=audLastRec();
          if (nRecs != audLastVisible) {
               audLastVisible=nRecs;
               aud1st();
               audMoved=FALSE;
          }
          break;
     default:
          return(scncod);
     }
     return(0);
}

VOID
scascn(                            /* scroll audit trail window            */
INT num)                           /*   number/direction to scroll         */
{
     ULONG lastRec,newPos;
     GBOOL newMoved;

     newMoved=TRUE;
     lastRec=audLastRec();
     if (lastRec != NOENTRIES) {
          newPos=audLastVisible;
          if (num < 0 && newPos < -num) {
               newPos=0;
          }
          else {
               newPos+=num;
          }
          if (newPos >= lastRec) {
               newPos=lastRec;
               newMoved=FALSE;
          }
          else if (newPos < NUMOFFP-2) {
               newPos=min(lastRec,NUMOFFP-2);
          }
     }
     if (newPos != audLastVisible) {
          audLastVisible=newPos;
          aud1st();
          audMoved=newMoved;
     }
}

VOID
audFinDisp(VOID)                   /* finish disp of audit trail at startup*/
{
     sumLastVisible=audLastVisible=audLastRec();
     aud1st();
     iniaud();
}

VOID
aud1st(VOID)                       /* show audit trail based on current pos*/
{
     INT i;
     struct audOldStyle buf;

     actvscn(audhdl);
     sstatr(stthue);
     audMoved=FALSE;
     for (i=0 ; i < NUMOFFP ; ++i) {
          locate(1,1+(i*2));
          if (audLastVisible != NOENTRIES && audLastVisible >= (NUMOFFP-1)-i) {
               audGetEntry(audLastVisible-((NUMOFFP-1)-i),&buf);
          }
          else {
               memset(&buf,0,sizeof(buf));
          }
          audPrintEntry(&buf);
     }
}

VOID
fasadd(VOID)                       /* add new entry to full screen audit   */
{
     struct audOldStyle buf;

     if (!audMoved) {
          actvscn(audhdl);
          sstatr(stthue);
          locate(72,17);
          ASSERT(audfNumRecs(hAuditTrail) != 0);
          audLastVisible=audfNumRecs(hAuditTrail)-1;
          audGetEntry(audLastVisible,&buf);
          printf("\n");
          audPrintEntry(&buf);
          rstloc();
          rstwin();
     }
}

ULONG                              /*   record # or NOENTRIES              */
audLastRec(VOID)                   /* get # of last record in audit trail  */
{
     ULONG nRecs;

     if ((nRecs=audfNumRecs(hAuditTrail)) == 0) {
          return(NOENTRIES);
     }
     return(nRecs-1);
}

VOID
audGetEntry(                       /* read an entry from the audit trail   */
ULONG recNum,                      /*   record number to get               */
struct audOldStyle *buf)           /*   buffer to receive entry            */
{
     INT rc;

     rc=audfReadOldStyle(hAuditTrail,recNum,buf,sizeof(struct audOldStyle));
     if (rc < AUDERR_OK) {
          if (rc == AUDERR_FIO) {
               catastro("I/O ERROR READING AUDIT TRAIL (%d)",errno);
          }
          else {
               catastro("ERROR READING AUDIT TRAIL (%d)",rc);
          }
     }
}

VOID
audPrintEntry(                     /* print entry at current position      */
const struct audOldStyle *entry)   /*   entry to print                     */
{
     printf("%14.14s %-32.32s %-21.21s\n      %-63s",
            entry->stamp,entry->brief,entry->channel,entry->detail);
}
