/***************************************************************************
 *                                                                         *
 *   WGSRDRLN.C                                                            *
 *                                                                         *
 *   Copyright (c) 1996-1997 Galacticomm, Inc.  All Rights Reserved.       *
 *                                                                         *
 *   Display list of all .RLN files found in the server subdirectory and   *
 *   display the contents of each file as it is selected.                  *
 *                                                                         *
 *                                          Richard Skurnick  05/21/96     *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "excphand.h"

#define FILREV "$Revision: 8 $"

static INT nroom=0,
           nposs=0;
static LONG *fposs;
static INT inbuf=-1;
static LONG sofar=0L;
static INT fpdone=0;
static INT errcod=-1;

#define NUMSCNS     2                   /* number of screens in scntbl[]   */
extern CHAR scntbl[NUMSCNS][GVIDSCNSIZ];/* table of mem-resident screens   */
static CHAR savscn[GVIDSCNSIZ];         /* save original screen            */

static INT cntRelNotes(struct ffblk *fbptr);
static VOID pupnotes(CHAR *relnotes);
static CHAR *getline(FILE *fp,INT infile);
static VOID dorln(VOID);

INT
main(                              /* main function                        */
INT argc,
CHAR *argv[])
{
     INT i;
     struct ffblk fbptr;

TRY
     (VOID)argc;
#ifdef GCWINNT
     if (!canRunUtil()) {
          MessageBox(NULL,NOPROCEED,
                    argv[0],MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
          return(1);
     }
#else
     (VOID)argv;
#endif // GCWINNT
     initvid();
     if ((errcod=setjmp(disaster)) != 0) {
          return(errcod);
     }
     for (i=0 ; i < NUMSCNS ; i++) {
          cvtscn(scntbl[i]);
     }
     cursiz(GVIDNOCURS);
     switch (cntRelNotes(&fbptr)) {
     case 0:                       // no .RLN files found
          scn2mem(savscn,0,GVIDSCNSIZ);
          explodeto(scntbl[1],0,17,32,21,23,10);
          getchc();
          mem2scn(savscn,0,GVIDSCNSIZ);
          break;
     case 1:                       // display the only file
          scn2mem(savscn,0,GVIDSCNSIZ);
          mem2scn(scntbl[0],0,GVIDSCNSIZ);
          setatr(0x70);
          printfat(8,0,"%s ",fbptr.ff_name);
          pupnotes(fbptr.ff_name);
          mem2scn(savscn,0,GVIDSCNSIZ);
          break;
     default:                      // give choices
          dorln();
     }
     cursiz(GVIDLILCURS);
     clsvid();
     return(0);
EXCEPT
#ifdef GCWINNT
     return(1);
#endif // GCWINNT
}

static INT                         /*   returns number of .RLN files found */
cntRelNotes(                       /* count number of .RLN files found     */
struct ffblk *fbptr)               /*   contains pointer to last found rec */
{
     INT cnt=0;

     if (fnd1st(fbptr,"*.rln",NULL) == TRUE) {
          do {
               cnt++;
          } while (fndnxt(fbptr));
     }
     return(cnt);
}

static VOID
pupnotes(                          /* put up release notes on screen       */
CHAR *relnotes)                    /*   release notes file name            */
{
     FILE *fp;
     CHAR *cp;
     INT i,whereat;

     if ((fp=fopen(relnotes,FOPRB)) == NULL) {
          catastro("File \"%s\" is missing!",relnotes);
     }
     setwin(0L,2,1,78,23,0);
     cursiz(GVIDNOCURS);
     ansion(1);
     setatr(0x1E);
     for (i=0 ; i < 23 ; i++) {
          if ((cp=getline(fp,i)) != NULL) {
               locate(2,i+1);
               printf("%s",cp);
               cleareol();
          }
     }
     whereat=0;
     while (1) {
          switch (getchc()) {
          case HOME:
               printf("\14");
               for (i=0 ; i < 23 ; i++) {
                    if ((cp=getline(fp,i)) != NULL) {
                         locate(2,i+1);
                         printf("%s",cp);
                         cleareol();
                    }
               }
               whereat=0;
               break;
          case END:
               printf("\14");
               getline(fp,0x7FFF);
               whereat=(nposs-23 < 0 ? 0 : nposs-23);
               for (i=0 ; i < 23 ; i++) {
                    if ((cp=getline(fp,whereat+i)) != NULL) {
                         locate(2,i+1);
                         printf("%s",cp);
                         cleareol();
                    }
               }
               break;
          case CRSRUP:
               if ((cp=getline(fp,whereat-1)) != NULL) {
                    scn2scn(160,2*160,22*160);
                    locate(2,1);
                    printf("%s",cp);
                    cleareol();
                    whereat--;
               }
               break;
          case CRSRDN:
               if ((cp=getline(fp,whereat+23)) != NULL) {
                    scn2scn(2*160,160,22*160);
                    locate(2,23);
                    printf("%s",cp);
                    cleareol();
                    whereat++;
               }
               break;
          case PGUP:
               for (i=0 ; i < 22 ; i++) {
                    if ((cp=getline(fp,whereat-1)) != NULL) {
                         scn2scn(160,2*160,22*160);
                         locate(2,1);
                         printf("%s",cp);
                         cleareol();
                         whereat--;
                    }
               }
               break;
          case PGDN:
               for (i=0 ; i < 22 ; i++) {
                    if ((cp=getline(fp,whereat+23)) != NULL) {
                         scn2scn(2*160,160,22*160);
                         locate(2,23);
                         printf("%s",cp);
                         cleareol();
                         whereat++;
                    }
               }
               break;
          case ESC:
               fclose(fp);
               if (nroom > 0) {
                    free(fposs);
                    nroom=nposs=0;
               }
               return;
          }
     }
}

static CHAR *                      /*   returns pointer to text line       */
getline(                           /* get a line of text from the file     */
FILE *fp,                          /*   file pointer                       */
INT infile)
{
     static CHAR datbuf[121];
     INT len;

     if (infile >= nposs && !fpdone) {
          fseek(fp,sofar,0);
          while (infile >= nposs && !fpdone) {
               if (fgets(datbuf,sizeof(datbuf),fp) == NULL) {
                    fpdone=1;
                    inbuf=-1;
               }
               else if (datbuf[0] == ('Z'&0x1F)) {
                    nposs--;
                    fpdone=1;
                    inbuf=-1;
               }
               else {
                    if (nposs >= nroom) {
                         if (nroom == 0) {
                              nroom=100;
                              fposs=(LONG *)alcmem(nroom*sizeof(LONG));
                              fposs[0]=0L;
                              nposs=1;
                         }
                         else {
                              fposs=(LONG *)alcrsz(fposs,nroom*sizeof(LONG),
                                                   (nroom+100)*sizeof(LONG));
                              nroom+=100;
                         }
                    }
                    inbuf=nposs-1;
                    sofar=fposs[nposs++]=ftell(fp);
               }
          }
     }
     if (infile >= nposs || infile < 0) {
          return(NULL);
     }
     if (infile != inbuf) {
          fseek(fp,fposs[infile],0);
          if (fgets(datbuf,sizeof(datbuf),fp) == NULL) {
               strcpy(datbuf,"\n");
          }
          inbuf=infile;
     }
     while ((len=strlen(datbuf)) != 0) {
          switch (datbuf[len-1]) {
          case '\n':
          case '\r':
               datbuf[len-1]='\0';
               break;
          case 'Z'&0x1F:
               return(NULL);
          default:
               return(datbuf);
          }
     }
     return(datbuf);
}

static VOID
dorln(VOID)                        /* display release notes available      */
{
     INT numrln,rnCount,chosen;
     static CHAR **rlnlist=NULL;
     struct ffblk fbptr;
     static CHAR lstscn[GVIDSCNSIZ];

     rnCount=20;
     if (rlnlist == NULL) {
          rlnlist=(CHAR**)alczer(rnCount*sizeof(CHAR *));
     }
     numrln=-1;
     if (fnd1st(&fbptr,"*.rln",NULL) == TRUE) {
          numrln=0;
          do {
               if (numrln%rnCount == 0 && numrln != 0) {
                    rlnlist=(CHAR **)alcrsz(rlnlist,rnCount*sizeof(CHAR *),
                                             (rnCount+20)*sizeof(CHAR *));
                    rnCount+=20;
               }
               rlnlist[numrln++]=alcdup(fbptr.ff_name);
          } while (fndnxt(&fbptr));
     }
     if (numrln == -1) {
          catastro(".RLN removed while WGSRDRLN running!");
     }
     else {
          scn2mem(lstscn,0,GVIDSCNSIZ);
          explodeto(scntbl[1],0,0,27,16,25,4);
          nslatr=*(scntbl[1]+gvscnoff(2,1)+1);
          do {
               if ((chosen=choose(numrln,rlnlist,2,1,25,11,1)) != -ESC) {
                    nroom=nposs=0;
                    inbuf=-1;
                    sofar=0L;
                    fpdone=0;
                    scn2mem(savscn,0,GVIDSCNSIZ);
                    mem2scn(scntbl[0],0,GVIDSCNSIZ);
                    setatr(0x70);
                    printfat(8,0,"%s ",rlnlist[chosen]);
                    pupnotes(rlnlist[chosen]);
                    mem2scn(savscn,0,GVIDSCNSIZ);
               }
          } while (chosen != -ESC);
          mem2scn(lstscn,0,GVIDSCNSIZ);
     }
}
