/***************************************************************************
 *                                                                         *
 *   GALFXP.C                                                              *
 *                                                                         *
 *   Copyright (c) 1992-1996 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   This is the offline utility to edit the phone number prefix file.     *
 *                                                                         *
 *                               - C. Robert and B. Stephens  12/16/92     *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "excphand.h"
#include "majorbbs.h"
#include "galfax.h"

#define FILREV "$Revision: 1.3 $"

#define   FXPCHK    20             /* chunks to allocate pfxlst in         */
#define   NCHINW    13             /* number of choices in window          */

extern SHORT curchc,fstchc;

extern CHAR scntbl[][GVIDSCNSIZ];  /* array of screens                     */

static CHAR dosscn[GVIDSCNSIZ],    /* saved DOS screen image               */
            savscn[GVIDSCNSIZ];    /* generic saved screen                 */

static CHAR savbdy[160];           /* saved chunk of screen for "(more)"   */

INT numpfx=0;                      /* number of prefixes now in memory     */
struct faxpfx *pfxlst;             /* in-memory list of prefixes           */
INT numalc=0;                      /* room in in-memory list allocated for */

CHAR **namlst;                     /* list of prefix names (ptrs to pfxlst)*/

static VOID inipfx(VOID);
static VOID our2chc(INT fc);
static VOID bldlst(VOID);
static VOID dsppfx(INT pfxnum);
static VOID edtpfx(INT pfxnum);
static VOID addpfx(INT pos);
static VOID delpfx(INT pfxnum);
static GBOOL valphon(INT c);
static VOID wrtpfx(VOID);
static GBOOL chknal(INT dftyes);
static GBOOL chkabt(VOID);
static VOID wrapup(VOID);

VOID
main(VOID)                         /* main program loop                    */
{
     INT c,fst,curc;
     GBOOL changed=FALSE;

TRY
     initvid();
     scn2mem(dosscn,0,GVIDSCNSIZ);
     monorcol();
     inipfx();
     cvtscn(scntbl[0]);
     cvtscn(scntbl[1]);
     cvtscn(scntbl[2]);
     explode(scntbl[0],0,0,79,24);
     proff(0,0);
     cursiz(GVIDNOCURS);
     selatr=0x7E;
     nslatr=0x1F;
     scn2mem(savbdy,gvscnoff(2,18+1),FAXPSZ*2);
     supchc(numpfx,namlst,2,6,25,18,0);
     while (TRUE) {
          dspchc();
          cursiz(GVIDNOCURS);
          do {
               dsppfx(curc=curchc);
               if ((c=getchc()) == ALT_H) {
                    scn2mem(savscn,0,GVIDSCNSIZ);
                    explode(scntbl[1],0,0,79,24);
                    proff(0,0);
                    getchc();
                    mem2scn(savscn,0,GVIDSCNSIZ);
               }
               else if (c == ALT_A) {
                    addpfx(curc=(curc+1 > numpfx ? numpfx : curc+1));
                    mem2scn(savbdy,gvscnoff(2,18+1),FAXPSZ*2);
                    fst=fstchc;
                    supchc(numpfx,namlst,2,6,25,18,0);
                    fstchc=fst;
                    our2chc(curc);
                    dspchc();
                    dsppfx(curc);
                    edtpfx(curc);
                    if (pfxlst[curc].prefix[0] == '\0') {
                         delpfx(curc);
                         mem2scn(savbdy,gvscnoff(2,18+1),FAXPSZ*2);
                         fst=fstchc;
                         supchc(numpfx,namlst,2,6,25,18,0);
                         fstchc=fst;
                         our2chc(min(curc,numpfx-1));
                    }
                    else {
                         changed=TRUE;
                    }
                    dspchc();
                    dsppfx(curc);
               }
               else if (c == ALT_D) {
                    if (numpfx > 0) {
                         delpfx(curc);
                         mem2scn(savbdy,gvscnoff(2,18+1),FAXPSZ*2);
                         fst=fstchc;
                         supchc(numpfx,namlst,2,6,25,18,0);
                         curc=max(min(curc,numpfx-1),0);
                         if (numpfx-curc < 13 && numpfx >= 13
                          && fst > numpfx-13) {
                              fstchc=numpfx-13;
                         }
                         else {
                              fstchc=fst;
                         }
                         our2chc(curc);
                         dspchc();
                         dsppfx(curc);
                         changed=TRUE;
                    }
               }
               else if (c == ALT_X) {
                    wrtpfx();
                    wrapup();
                    exit(0);
               }
               else if (c == ESC && (!changed || chkabt())) {
                    wrapup();
                    exit(0);
               }
               cursiz(GVIDNOCURS);
          } while (numpfx == 0 || (curc=hdlchc(c)) == numpfx);
          edtpfx(curc);
          changed=TRUE;
     }
EXCEPT
}

static VOID
inipfx(VOID)                       /* initialize the fax prefix list       */
{
     INT i=0;
     FILE *fp;
     CHAR tmpbuf[150];

     if ((fp=fopen("galfxp.lst",FOPRA)) == NULL) {
          numpfx=0;
          numalc=FXPCHK;
          pfxlst=(struct faxpfx *)alczer(numalc*sizeof(struct faxpfx));
          namlst=(CHAR **)alcmem(numalc*sizeof(CHAR *));
          return;
     }
     while (fgets(tmpbuf,149,fp) != NULL) {
          numpfx++;
     }
     numalc=numpfx;
     pfxlst=(struct faxpfx *)alczer(numpfx*sizeof(struct faxpfx));
     rewind(fp);
     while (fgets(tmpbuf,149,fp) != NULL) {
          stzcpy(pfxlst[i].prefix,tmpbuf,FAXPSZ);
          unpad(pfxlst[i].prefix);
          stzcpy(pfxlst[i].rplcwt,&tmpbuf[FAXPSZ],FAXPSZ);
          unpad(pfxlst[i].rplcwt);
          stzcpy(pfxlst[i].keyreq,&tmpbuf[FAXPSZ+FAXPSZ],KEYSIZ);
          unpad(pfxlst[i].keyreq);
          sscanf(&tmpbuf[FAXPSZ+FAXPSZ+KEYSIZ],"%ld/%ld",&pfxlst[i].baschg,
                 &pfxlst[i].addchg);
          i++;
     }
     fclose(fp);
     namlst=(CHAR **)alcmem(numpfx*sizeof(CHAR *));
     bldlst();
}

static VOID
bldlst(VOID)                       /* build list of prefix names           */
{
     INT i;

     for (i=0 ; i < numpfx ; i++) {
          namlst[i]=pfxlst[i].prefix;
     }
}

static VOID
our2chc(                           /* our jump to a choice                 */
INT fc)
{
     curchc=fc;
     if (curchc < fstchc || curchc >= fstchc+NCHINW) {
          fstchc=max(0,curchc-NCHINW+1);
     }
}

static VOID
dsppfx(                            /* display fax prefix info in window    */
INT pfxnum)                        /*   prefix number to display           */
{
     if (pfxnum < numpfx) {
          setatr(0x1F);
          locate(53,8);
          printf("%-24s",pfxlst[pfxnum].prefix);
          locate(53,10);
          printf("%-24s",pfxlst[pfxnum].rplcwt);
          locate(53,12);
          printf("%-15s",pfxlst[pfxnum].keyreq);
          locate(53,14);
          printf("%-6s",spr("%ld",pfxlst[pfxnum].baschg));
          locate(53,16);
          printf("%-6s",spr("%ld",pfxlst[pfxnum].addchg));
     }
     else {
          setatr(0x1F);
          locate(53,8);
          printf("%-24s","");
          locate(53,10);
          printf("%-24s","");
          locate(53,12);
          printf("%-15s","");
          locate(53,14);
          printf("%-6s","");
          locate(53,16);
          printf("%-6s","");
     }
}

static VOID
edtpfx(                            /* edit a fax prefix entry now          */
INT pfxnum)                        /*   prefix number to edit              */
{
     CHAR lngval[7];
     struct faxpfx tmppfx;

     movmem(&pfxlst[pfxnum],&tmppfx,sizeof(struct faxpfx));
     cursiz(GVIDLILCURS);
     do {
          if (!edtval(53,8,FAXPSZ,tmppfx.prefix,valphon,0)) {
               return;
          }
     } while (tmppfx.prefix[0] == '\0' && printf("\7"));
     if (chknal(sameas(tmppfx.rplcwt,NOTALW))) {
          strcpy(tmppfx.rplcwt,NOTALW);
          tmppfx.keyreq[0]='\0';
          tmppfx.baschg=tmppfx.addchg=0L;
     }
     else {
          if (sameas(tmppfx.rplcwt,NOTALW)) {
               tmppfx.rplcwt[0]='\0';
          }
          if (!edtval(53,10,FAXPSZ,tmppfx.rplcwt,valphon,0)) {
               return;
          }
          if (!edtval(53,12,KEYSIZ,tmppfx.keyreq,istxvc,ALLCAPS)) {
               return;
          }
          if (tmppfx.baschg == 0L) {
               lngval[0]='\0';
          }
          else {
               stzcpy(lngval,l2as(tmppfx.baschg),7);
          }
          if (!edtval(53,14,7,lngval,validig,0)) {
               return;
          }
          tmppfx.baschg=atol(lngval);
          if (tmppfx.addchg == 0L) {
               lngval[0]='\0';
          }
          else {
               stzcpy(lngval,l2as(tmppfx.addchg),7);
          }
          if (!edtval(53,16,7,lngval,validig,0)) {
               return;
          }
          tmppfx.addchg=atol(lngval);
     }
     movmem(&tmppfx,&pfxlst[pfxnum],sizeof(struct faxpfx));
     bldlst();
}

static VOID
addpfx(                            /* add a prefix entry to the list       */
INT pos)                           /*   position to add to                 */
{
     if (numpfx+1 > numalc) {
          pfxlst=(struct faxpfx *)alcrsz(pfxlst,numalc*sizeof(struct faxpfx),
                                         (numalc+FXPCHK)*sizeof(struct faxpfx));
          namlst=(CHAR **)alcrsz(namlst,numalc*sizeof(CHAR *),
                                 (numalc+FXPCHK)*sizeof(CHAR *));
          numalc+=FXPCHK;
     }
     movmem(&pfxlst[pos],&pfxlst[pos+1],
            sizeof(struct faxpfx)*(numpfx-pos));
     setmem(&pfxlst[pos],sizeof(struct faxpfx),0);
     numpfx++;
     bldlst();
}

static VOID
delpfx(                            /* delete a prefix entry                */
INT pfxnum)                        /*   entry number to delete             */
{
     movmem(&pfxlst[pfxnum+1],&pfxlst[pfxnum],
             sizeof(struct faxpfx)*(numpfx-pfxnum-1));
     numpfx--;
     bldlst();
}

static GBOOL
valphon(                           /* is this a valid phone # character?   */
INT c)                             /*   character to validate              */
{
     return(c == '+' || c == ',' || (c <= 255 && isdigit(c)));
}

static VOID
wrtpfx(VOID)                       /* write out the prefix file            */
{
     INT i;
     FILE *fp;

     if (numpfx == 0) {
          unlink("galfxp.lst");
     }
     else {
          if ((fp=fopen("galfxp.lst",FOPWA)) == NULL) {
               catastro("CAN'T WRITE TO \"GALFXP.LST\"!");
          }
          for (i=0 ; i < numpfx ; i++) {
               fprintf(fp,"%-24s %-24s %-15s %ld/%ld\n",
                       pfxlst[i].prefix,pfxlst[i].rplcwt,pfxlst[i].keyreq,
                       pfxlst[i].baschg,pfxlst[i].addchg);
          }
          fclose(fp);
     }
}

static GBOOL
chknal(                            /* check to see if prefix is allowed    */
INT dftyes)                        /*   default to yes? (1 or 0)           */
{
     INT retval;
     CHAR stg[7];

     scn2mem(savscn,0,GVIDSCNSIZ);
     explodeto(scntbl[2],5,13,73,15,5,10);
     proff(0,0);
     strcpy(stg,dftyes ? "Yes" : "No");
     retval=(edtval(69,11,4,stg,validyn,MCHOICE) && tolower(stg[0]) == 'y');
     mem2scn(savscn,0,GVIDSCNSIZ);
     return(retval);
}

static GBOOL
chkabt(VOID)                       /* check and make sure of abort command */
{
     INT retval;
     CHAR stg[7];

     scn2mem(savscn,0,GVIDSCNSIZ);
     explode(scntbl[2],13,10,64,12);
     proff(0,0);
     strcpy(stg,"No");
     retval=(edtval(60,11,4,stg,validyn,MCHOICE) && tolower(stg[0]) == 'y');
     mem2scn(savscn,0,GVIDSCNSIZ);
     return(retval);
}

static VOID
wrapup(VOID)                       /* wrap things up before exiting        */
{
     setatr(0x07);
     printf(" ");
     locate(0,24);
     mem2scn(dosscn,0,GVIDSCNSIZ);
     cursiz(GVIDLILCURS);
     clsvid();
}
