/***************************************************************************
 *                                                                         *
 *   GALFILKW.C                                                            *
 *                                                                         *
 *   Copyright (c) 1993-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   File Library - Offline Utility to rebuild GALFILK2.DAT,               *
 *                  the keyword database                                   *
 *                                                                         *
 *                                                  -D. Pitchford  9/28/93 *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "filexfer.h"
#include "reserve.h"
#include "galfilh.h"
#include "excphand.h"

#define FILREV "$Revision: 9 $"

static CHAR dosscn[GVIDSCNSIZ];

extern CHAR scntbl[][GVIDSCNSIZ];

INT gohome(INT);
VOID dobuild(VOID);
INT makwdlst(const CHAR *,const CHAR *);
VOID darsdesc(INT,CHAR);
VOID strcrep(CHAR *,CHAR,CHAR);
CHAR *cutpunc(CHAR *);
VOID bubkwds(VOID);
INT dskchek(VOID);

DFAFILE *newfiles;
DFAFILE *newkwd;

CHAR *descedit;

INT dargc;

CHAR *dargv[MAXKWDS];

CHAR *nonkwds="\
. MOST TEXT COMPUTER FILE NICE DISK YOUR REQUIRES GOOD VERSION RAM MEG MEGS .\
. LATEST LITTLE SOFTWARE DURING ALL BEST .\
. ABLE ABOUT ABOVE ACCEPT ACCESS ACROSS ACTUAL ACTUALLY ADD AFTER AGAIN .\
. AGO AGREE AGREES AHEAD AIN AINT ALL ALLOW ALLOWED ALLOWS ALMOST ALONE .\
. ALONG ALREADY ALRIGHT ALSO ALWAYS AND ANOTHER ANSWER ANSWERS ANY .\
. ANYONE ANYTHING ANYTIME ANYWAY ANYWHERE APPLIES APPLY ARE AREN ARENT .\
. AROUND ASK ASKED ASKING ASKS ATTACH ATTACHED AVE AWAIT AWAITED AWAITING .\
. AWAY BACK BARE BARELY BE BECAME BECAUSE BECOME BECOMES BEEN BEFORE BEGAN .\
. BEGIN BEGINS BEGUN BEING BETTER BOTH BREAK BRING BRINGS BUSY BUT CALL .\
. CALLED CALLING CAN CANNOT CARE CAUSES CHANCE CHANGE CHANGED CHANGES .\
. CHANGING CHOICES CLEARLY CLOSELY COME COMES COMING COULD COULDN COVER .\
. CURRENT DID DOES DOESN DOING DON DURING EACH ELSE ENJOY ENOUGH ENTIRE .\
. ENTIRELY EVEN EVER EVERY EVERYONE EXCEPT FEEL FILL FILLED FILLS FIND FINDS .\
. FOR FORTH FROM FULL FULLY GAVE GET GETS GETTING GIVE GIVEN GIVES GIVING .\
. GOES GOING GONE GOT HAD HAS HAVE HAVEN HER HERE HERS HERSELF HEY HIM HIMSELF .\
. HIS HISELF HIT HITS HOPE HOW INSTEAD INTO ISN ISSUE ISSUES ISSUING ITS .\
. ITSELF JUST KEEP KEEPING KEPT KIND KINDS KNOW LET LETS LETTING LIKE LIKED .\
. LIKELY LOT LOTS MAKE MAKES MAKING MANY MAY MAYBE MIGHT MINE MORE MOVE MOVES .\
. MOVING MRS MUCH MUST NEED NEEDS NEVER NEW NONE NONETHELESS NORMALLY NOT .\
. NOTHING NOW OCCUR OFF OFFER OFFERING OFFERS OFTEN ONCE ONE ONLY OTHER .\
. OTHERS OUR OUT OVER OWN PER PLACE PLACED PULL PUT PUTS PUTTING QUITE READY .\
. REST SAID SAME SAY SAYING SAYS SEE SEE SEEING SEEM SEEMED SEEN SEES SEND .\
. SENDING SENT SEVERAL SHALL SHE SHOULD SHOULDN SINCE SOME SOON SUCH SURE .\
. TAKE TAKEN TAKING TELL TELLING TELLS THAN THAT THATS THE THEIR THEM .\
. THEMSELVES THEN THERE THESE THEY THING THINGS THIS THOSE THROW THRU TOLD .\
. TOO TOWARD TOWARDS TRIED TRY TRYING UNLIKE UNTIL UPON USE USES USUAL VARY .\
. VERY WANT WANTED WANTS WAS WASN WAY WAYS WELL WENT WERE WEREN WHAT WHEN .\
. WHERE WHICH WHILE WHO WHOEVER WHOM WHY WILL WITH WITHIN WITHOUT WON WOULD .\
. YET YOU YOUR YOURS .";

static INT cc=4,rr=7;

INT
main(                         /* main program loop                         */
INT argc,
CHAR *argv[])
{
TRY
     INT ec;

     (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 ((ec=setjmp(disaster)) != 0) {
          return(gohome(ec));
     }
     cursiz(GVIDNOCURS);
     scn2mem(dosscn,0,GVIDSCNSIZ);
     monorcol();
     if (!dskchek()) {
          return(gohome(ec));
     }
     explodeto(cvtscn(scntbl[0]),0,0,70,10,cc,rr);
     setatr(0x1E);
     setwin(NULL,cc+2,rr+3,cc+70-1,rr+10-1,1);
     locate(cc+2,rr+3);
     descedit=(CHAR *)alczer(DESCSIZ);
     dfaMode(RONLBV);
     newfiles=dfaOpen("galfilf2.dat",FLFILREC+DESCSIZ,NULL);
     dfaMode(ACCLBV);
     newkwd=dfaOpen("galfilk2.dat",FLKEYREC,NULL);
     dfaSetBlk(newkwd);
     printf("Deleting old keywords...\n");
     while (dfaAcqLO(NULL,0)) {
          dfaDelete();
     }
     printf("Inserting new keywords...\n");
     dobuild();
     dfaClose(newfiles);
     dfaClose(newkwd);
     return(gohome(ec));
EXCEPT
#ifdef GCWINNT
     return(1);
#endif
}

INT
gohome(                            /* get ready to go back to DOS now      */
INT errc)
{
     setatr(0x07);
     if (errc == 0) {
          printf(" ");
          mem2scn(dosscn,0,GVIDSCNSIZ);
     }
     locate(0,24);
     cursiz(GVIDLILCURS);
     clsvid();
     return(errc);
}


VOID
dobuild(VOID)                      /* primary operations loop              */
{
     struct flfile ff;
     struct key2 kwdy;
     INT loop;
     CHAR *a,*b;

     setmem(&ff,sizeof(struct flfile),0);
     dfaSetBlk(newfiles);
     while (dfaAcqGT(&ff,ff.libname,1)) {
          if (makwdlst(ff.desc,ff.filname)) {
               printf("%c%s/%s%c%c",13,ff.libname,ff.filname,13,10);
               stzcpy(kwdy.libkey,ff.libname,FLNAMESZ);
               stzcpy(kwdy.filname,ff.filname,FLFILENM);
               dfaSetBlk(newkwd);
               b="";
               for (loop=0 ; loop < dargc ; loop++) {
                    a=dargv[loop];
                    if (!sameas(a,b) && !samein(spr(" %s ",a),nonkwds)) {
                         stzcpy(kwdy.keyword,dargv[loop],FLKEYSIZ);
                         dfaInsert(&kwdy);
                         printf("%c               %c%s%c",13,13,dargv[loop],
                                                          13);
                    }
                    b=a;
               }
               dfaSetBlk(newfiles);
          }
     }
}

INT
makwdlst(                          /* make keyword list                    */
const CHAR *stg,
const CHAR *filname)
{
     CHAR filnmem[FLFILENM],*ext;

     descedit[0]='\0';
     stzcpy(filnmem,filname,FLFILENM);
     ext=strchr(strupr(filnmem),'.');
     if (ext != NULL) {
          *ext++='\0';
          if (strlen(ext) == 3) {
               strcat(descedit,ext);
               strcat(descedit," ");
          }
     }
     if (strlen(filnmem) > 2) {
          strcat(descedit,filnmem);
          strcat(descedit," ");
     }
     stzcat(descedit,stg,DESCSIZ);
     strcrep(descedit,'\r',' ');
     strupr(descedit);
     darsdesc(MAXKWDS,' ');
     bubkwds();
     return(dargc > 0);
}

VOID
darsdesc(                          /* parsin() on descedit                 */
INT limit,
CHAR chr)
{
     CHAR *sptr;
     INT loop;

     sptr=descedit;
     dargc=0;
     for (loop=0 ; loop < limit ; loop++) {
          dargv[loop]=sptr;
          if (sptr[0] != '\0') {
               sptr=strchr(sptr,chr);
               if (sptr == NULL) {
                    sptr=&descedit[strlen(descedit)];
               }
               else {
                    *sptr='\0';
                    sptr++;
               }
               dargc++;
          }
     }
}

VOID
bubkwds(VOID)                      /* edit and sort keywords               */
{
     CHAR *current,*newarg;
     INT loop,loop2;

     for (loop=0 ; loop < dargc ; loop++) {
          cutpunc(dargv[loop]);              /* cut symbols                */
          loop2=strlen(dargv[loop]);
          if (loop2 > FLKEYSIZ-1) {          /* shorten long words         */
               dargv[loop][FLKEYSIZ-1]='\0';
          }
          else if (loop2 < 3) {              /* cut really short words     */
               dargc--;
               if (loop != dargc) {
                    dargv[loop--]=dargv[dargc];
               }
          }
     }
     for (loop=0 ; loop < (dargc-1) ; loop++) { /* sort them now           */
          current=dargv[loop];
          for (loop2=(loop+1) ; loop2 < dargc ; loop2++) {
               newarg=dargv[loop2];
               if (stricmp(current,newarg) > 0) {
                    dargv[loop2]=current;
                    current=dargv[loop]=newarg;
               }
          }
     }
     for (loop=0 ; loop < dargc-1 ; loop++) { /* eliminate duplicates      */
          if (stricmp(dargv[loop],dargv[loop+1]) == 0) {
               for (loop2=loop+1 ; loop2 < dargc-1 ; loop2++) {
                    dargv[loop2]=dargv[loop2+1];
               }
               dargc--;
               loop--;
          }
     }
}

CHAR *
cutpunc(                           /* cuts words at punctuation            */
CHAR *stg)
{
     INT loop,l;
     CHAR *s;

     l=strlen(stg);
     for (loop=0 ; loop < l ; loop++) {
          s=&stg[loop];
          if ((*s < '0') || ((*s > '9') && (*s < 'A')) || (*s > 'Z')) {
               if (*s < '€') {
                    *s='\0';
                    if (strlen(++s) && (dargc < (MAXKWDS-1))) {
                         dargv[dargc++]=s;
                    }
                    loop=l;
               }
          }
     }
     return(stg);
}

VOID
strcrep(                           /* replace a char in a string w/ a char */
CHAR *stg,
CHAR from,
CHAR to)
{
     INT loop,s;

     s=strlen(stg);
     for (loop=0 ; loop < s ; loop++) {
          if (*stg == from) {
               *stg=to;
          }
          stg++;
     }
}

INT
dskchek(VOID)                      /* check disk space                     */
{
     struct ffblk fb;
     LONG xdatsz=0L,fre;

     fre=dskfre(".");
     if (fndfile(&fb,"galfilk2.dat",0)) {
          xdatsz=fb.ff_fsize;
     }
     fre+=xdatsz;
     if (fndfile(&fb,"galfilf2.dat",0)) {
          xdatsz=fb.ff_fsize*5L/2L;
          if ((xdatsz/1024L) > fre) {
               explodeto(cvtscn(scntbl[1]),0,0,70,10,cc,rr);
               setatr(0x4E);
               setwin(NULL,cc+2,rr+3,cc+70-1,rr+10-1,1);
               locate(cc+30,rr+1);
               printf("WARNING");
               locate(cc+2,rr+3);
               printf("You may not have enough hard drive space to rebuild your keyword");
               locate(cc+2,rr+4);
               printf("database.  Exit this program, free up a minimum of %s bytes,",l2as(xdatsz-fre));
               locate(cc+2,rr+5);
               printf("and try again, or continue by typing 'C'.");
               cursiz(GVIDNOCURS);
               do {
                    if (kbhit()) {
                         switch(getch()) {
                         case ESC:
                              return(0);
                         case 'C':
                         case 'c':
                              return(1);
                         }
                    }
               } while (1);
          }
     }
     return(1);
}
