/***************************************************************************
 *                                                                         *
 *  GALRFC.C                                                               *
 *                                                                         *
 *  Copyright (c) 1993-1997 Galacticomm, Inc.  All rights reserved.        *
 *                                                                         *
 *  Combine RIP files into single file for viewing as a file page.         *
 *                                           - Bill Hyatt  6/15/93         *
 *  Heavy modifications for 6.20.                                          *
 *                                           - Bill Hyatt  12/15/93        *
 *                                                                         *
 ***************************************************************************/

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

#define FILREV "$Revision: 8 $"

#define EDTLEN 63+1                /* length of file name fields           */
#define YNLEN  3+1                 /*   "    "  yes/no fields              */
#define MXBFSZ 255                 /* max length for buffered file reads   */
#define MXRPLN 76+1                /* max len of RIP line on MBBS, w/ '\n' */
#define MAXRNM 3                   /* max # of RIP_NO_MORE's to end RIP par*/
#define CLRCHR 12                  /* "pause" char to insert between scenes*/

#define RPLNBG "!|"                /* standard beginning of a RIP line     */
#define RTXWCM "|w0000000000"      /* RIP command to make inv. text window */

#define IFSTT  0                   /* editing input file name state        */
#define OFSTT  1                   /* editing output file name state       */
#define ARWSTT 2                   /* add RIP_RESET_WINDOWS yes/no state   */
#define ITWSTT 3                   /* invis. text windows yes/no state     */
#define APCSTT 4                   /* add pause char. yes/no state         */
#define APSSTT 5                   /* add pause scene yes/no state         */
#define PSSTT  6                   /* editing pause scene file name state  */
#define PACSTT 7                   /* proceed and combine yes/no state     */
#define CMBSTT 8                   /* combining RIP files state            */

extern CHAR scntbl[][GVIDSCNSIZ];/* table of pre-OBJ'd screen files      */

CHAR dosscn[GVIDSCNSIZ];               /* save current DOS screen              */

CHAR inflnm[EDTLEN],               /* input file name                      */
     outflnm[EDTLEN],              /* output file name                     */
     psflnm[EDTLEN],               /* pause scene file name                */
     arwyn[YNLEN],                 /* add RIP_RESET_WINDOWS answer string  */
     itwyn[YNLEN],                 /* invis. text windows answer string    */
     apcyn[YNLEN],                 /* add pause char. answer string        */
     apsyn[YNLEN],                 /* add pause scene answer string        */
     pacyn[YNLEN];                 /* proceed and create answer string     */

FILE *infil,                       /* input file                           */
     *outfil,                      /* output file                          */
     *psefil;                      /* pause scene file                     */

INT rfcstt=IFSTT,                  /* current user state                   */
    addrst=1,                      /* add RIP_RESET_WINDOWS?               */
    ivstxt=1,                      /* invis. text windows?                 */
    addpch=1,                      /* add pause character?                 */
    addpsn=1,                      /* add pause scene?                     */
    savx,                          /* \                                    */
    savy,                          /*  > save current DOS cursor coords & s*/
    scur;                          /* /                                    */

/* GALRFC.C 15/12/93 23.34.10 */
VOID init (VOID);
INT gonstt (INT upstt, INT dnstt, INT lfstt, INT rtstt);
INT cmbfls (VOID);
INT chkfls (VOID);
INT gtfnam (CHAR *ripfnm, FILE *infil);
INT opnfil (FILE **ripfil, CHAR *ripfnm);
VOID addfil (FILE *ripfil, CHAR *ripfnm);
INT lenok (CHAR *riplin, CHAR *ripfnm, FILE *ripfil);
VOID stptwn (CHAR *riplin);
INT cntrnm (CHAR *riplin);
VOID endrip (VOID);
GBOOL vldpth (INT c, CHAR *sval);
GBOOL myvldyn (INT c, CHAR *stg);
VOID shwhlp (VOID);

INT
main(                            /* main program entry point               */
INT argc,
CHAR *argv[])
{
TRY

#ifdef GCWINNT
     if (!canRunUtil()) {
          MessageBox(NULL,NOPROCEED,
                    argv[0],MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
          return(1);
     }
#else
     (VOID)argv;
#endif // GCWINNT
     (VOID)argc;
     initvid();
     init();
     while (edtvalc != ESC) {
          switch (rfcstt) {
       case IFSTT:
               if (edtval(15,2,EDTLEN,inflnm,vldpth,
                 needupc() ? MULTIEX+ALLCAPS : MULTIEX)) {
                    rfcstt=gonstt(PACSTT,OFSTT,PACSTT,OFSTT);
               }
               break;
       case OFSTT:
               if (edtval(15,3,EDTLEN,outflnm,vldpth,
                 needupc() ? MULTIEX+ALLCAPS : MULTIEX)) {
                    rfcstt=gonstt(IFSTT,ARWSTT,IFSTT,ARWSTT);
               }
               break;
          case ARWSTT:
               if (edtval(25,4,YNLEN,arwyn,myvldyn,MCHOICE+MULTIEX)) {
                    addrst=(arwyn[0] == 'Y');
                    rfcstt=gonstt(OFSTT,APCSTT,OFSTT,ITWSTT);
               }
               break;
          case ITWSTT:
               if (edtval(57,4,YNLEN,itwyn,myvldyn,MCHOICE+MULTIEX)) {
                    ivstxt=(itwyn[0] == 'Y');
                    rfcstt=gonstt(OFSTT,APSSTT,ARWSTT,APCSTT);
               }
               break;
          case APCSTT:
               if (edtval(25,5,YNLEN,apcyn,myvldyn,MCHOICE+MULTIEX)) {
                    addpch=(apcyn[0] == 'Y');
                    rfcstt=gonstt(ARWSTT,addpsn ? PSSTT : PACSTT,
                                  ITWSTT,APSSTT);
               }
               break;
          case APSSTT:
               if (edtval(57,5,YNLEN,apsyn,myvldyn,MCHOICE+MULTIEX)) {
                    addpsn=(apsyn[0] == 'Y');
                    rfcstt=gonstt(ITWSTT,addpsn ? PSSTT : PACSTT,
                                  APCSTT,addpsn ? PSSTT : PACSTT);
               }
               break;
          case PSSTT:
               if (edtval(15,6,EDTLEN,psflnm,vldpth,MULTIEX+ALLCAPS)) {
                    rfcstt=gonstt(APCSTT,PACSTT,APSSTT,PACSTT);
               }
               break;
          case PACSTT:
               if (edtval(22,8,YNLEN,pacyn,myvldyn,MCHOICE+MULTIEX)) {
                    if (edtvalc == '\r' && pacyn[0] == 'Y') {
                         rfcstt=CMBSTT;
                    }
                    else {
                         rfcstt=gonstt(addpsn ? PSSTT : APSSTT,IFSTT,
                                       addpsn ? PSSTT : APSSTT,IFSTT);
                    }
               }
               break;
          case CMBSTT:
               rfcstt=(cmbfls() ? IFSTT : PACSTT);
               break;
          }
     }
     mem2scn(dosscn,0,GVIDSCNSIZ);
     locate(savx,savy);
     cursiz(scur);
     ansion(1);
     printf("\33[0m");
     clsvid();
     return(0);
EXCEPT
#ifdef GCWINNT
     return(1);
#endif // GCWINNT
}

VOID
init(VOID)                       /* initialize, set up things              */
{
     scn2mem(dosscn,0,GVIDSCNSIZ);
     savx=curcurx();
     savy=curcury();
     scur=curcurs();
     cvtscn(scntbl[0]);
     cvtscn(scntbl[1]);
     explode(scntbl[0],0,0,79,24);
     proff(0,0);
     setatr(0x1B);
     prat(15,2,"%s"," ");
     prat(15,3,"%s"," ");
     strcpy(arwyn,"Yes");
     prat(25,4,"%s",arwyn);
     strcpy(itwyn,"Yes");
     prat(57,4,"%s",itwyn);
     strcpy(apcyn,"Yes");
     prat(25,5,"%s",apcyn);
     strcpy(apsyn,"Yes");
     prat(57,5,"%s",apsyn);
     strcpy(pacyn,"Yes");
     prat(22,8,"%s",pacyn);
     strcpy(psflnm,"GALRFC.RIP");
     prat(15,6,"%s",psflnm);
     setatr(0x1E);
     prat(28,8,"%s","(Hit RETURN to start)");
     edtvalc=0;
}

INT
gonstt(upstt,dnstt,lfstt,rtstt)  /* return state to transition to          */
INT upstt;                       /*    state if hit CRSRUP                 */
INT dnstt;                       /*    state if hit CRSRDN                 */
INT lfstt;                       /*    state if hit CRSRLF or BAKTAB       */
INT rtstt;                       /*    state if hit \r, CRSRRT, TAB or othr*/
{
     switch (edtvalc) {
     case CRSRUP:
          return(upstt);
     case CRSRDN:
          return(dnstt);
     case CRSRLF:
     case BAKTAB:
          return(lfstt);
     case '\r':
     case CRSRRT:
     case TAB:
     default:
          return(rtstt);
     }
}

INT
cmbfls(VOID)                     /* combine the RIP files                  */
{
     CHAR ripfnm[FNMSIZ];
     FILE *ripfil;

     setwin(NULL,2,10,77,23,1);
     proff(0,0);
     setatr(0x1F);
     printf("\f");
     if (!chkfls()) {
          return(0);
     }
     printf("Combining files...");
     while (gtfnam(ripfnm,infil)) {
          if (opnfil(&ripfil,ripfnm)) {
               addfil(ripfil,ripfnm);
          }
     }
     fclose(infil);
     fclose(outfil);
     if (addpsn) {
          fclose(psefil);
     }
     printf("\nFiles combined into %s!",outflnm);
     return(1);
}

INT                              /* make sure flds are filled in, and all  */
chkfls(VOID)                     /*    files are present                   */
{
     CHAR chkbuf[MXBFSZ];

     if (strlen(inflnm) == 0) {
          printf("\7No input file name specified!",inflnm);
          return(0);
     }
     if (!isfile(inflnm)) {
          printf("\7Unable to find input file %s!",inflnm);
          return(0);
     }
     if ((infil=fopen(inflnm,FOPRA)) == NULL) {
          printf("\7Can't open \"%s\" for input!",inflnm);
          return(0);
     }
     if (strlen(outflnm) == 0) {
          printf("\7No output file name specified!",outflnm);
          fclose(infil);
          return(0);
     }
     if ((outfil=fopen(outflnm,FOPWA)) == NULL) {
          printf("\7Can't open \"%s\" for output!",outflnm);
          fclose(infil);
          return(0);
     }
     if (addpsn) {
          if (strlen(psflnm) == 0) {
               printf("\7No pause scene file name specified!",psflnm);
               addpsn=0;
               fclose(infil);
               fclose(outfil);
               return(0);
          }
          if (!isfile(psflnm)) {
               printf("\7Unable to find pause scene file %s!",psflnm);
               addpsn=0;
               fclose(infil);
               fclose(outfil);
               return(0);
          }
          if ((psefil=fopen(psflnm,FOPRA)) == NULL) {
               printf("\7Can't open \"%s\" for input!",psflnm);
               addpsn=0;
               fclose(infil);
               fclose(outfil);
               return(0);
          }
          while (fgets(chkbuf,MXBFSZ,psefil) != NULL) {
               if (strlen(chkbuf) > MXRPLN) {
                    printf("\7ERROR: File %s must be saved in RIPaint with",
                            psflnm);
                    printf("\nFile Width of %d or less!",MXRPLN-1);
                    printf("\nUnable to use this file.");
                    addpsn=0;
                    fclose(infil);
                    fclose(outfil);
                    fclose(psefil);
                    return(0);
               }
          }
     }
     return(1);
}

INT
gtfnam (ripfnm,infil)            /* get a file name out of input file      */
CHAR *ripfnm;                    /*    where to put the name               */
FILE *infil;                     /*    file to read it from                */
{
     CHAR *cp;

     if (fgets(ripfnm,MXBFSZ,infil) == NULL) {
         return(0);
     }
     if (*(cp=ripfnm+strlen(ripfnm)-1) == '\n') {
          *cp='\0';
     }
     return(1);
}

INT
opnfil (ripfil,ripfnm)           /* try to open file from input file list  */
FILE **ripfil;                   /*    pointer to file if we can open it   */
CHAR *ripfnm;                    /*    name of file to open                */
{
     if ((*ripfil=fopen(ripfnm,FOPRA)) != NULL) {
          return(1);
     }
     printf("\7\nERROR: Couldn't open %s for input - ",ripfnm);
     printf("skipping this file.\nHit any key...");
     getchc();
     return(0);
}

VOID
addfil (ripfil,ripfnm)           /* add RIP file to combine file           */
FILE *ripfil;                    /*    file to add                         */
CHAR *ripfnm;                    /*    name of file to add                 */
{
     INT ripend=0,nrnm=0,fstlin=1;
     CHAR riplin[MXBFSZ];
     CHAR altrbg1[3]={1,'|','\0'},
          altrbg2[3]={2,'|','\0'};

     printf("\nAdding %s...",ripfnm);
     while (fgets(riplin,MXBFSZ,ripfil) != NULL) {
          if (ripend) {
               fprintf(outfil,"%s",riplin);
          }
          else {
               if (!lenok(riplin,ripfnm,ripfil)) {
                    break;
               }
               if (fstlin && addrst) {
                    if (sameto(RPLNBG,riplin) || samein(altrbg1,riplin)
                        || samein(altrbg2,riplin)) {
                         if (!samein(RIP_RESET_WINDOWS,riplin)) {
                              fprintf(outfil,"!%s\n",RIP_RESET_WINDOWS);
                         }
                         fstlin=0;
                    }
               }
               if (ivstxt) {
                    stptwn(riplin);
               }
               if (!samein(RIP_NO_MORE,riplin)) {
                    fprintf(outfil,"%s",riplin);
               }
               else {
                    ripend=((nrnm+=cntrnm(riplin)) >= MAXRNM);
                    if (!sameto(RIP_NO_MORE,riplin+1)) {
                         *(strstr(riplin,RIP_NO_MORE))='\0';
                         fprintf(outfil,"%s\n",riplin);
                    }
                    if (ripend) {
                         endrip();
                    }
               }
          }
     }
     fclose(ripfil);
     if (addpch) {
          fprintf(outfil,"%c\n",CLRCHR);
     }
}

INT
lenok (riplin,ripfnm,ripfil)     /* make sure len of RIP line is acceptable*/
CHAR *riplin;                    /*    line to test                        */
CHAR *ripfnm;                    /*    name of file it came from           */
FILE *ripfil;                    /*    file it came from                   */
{
     if (strlen(riplin) <= MXRPLN) {
          return(1);
     }
     printf("\7\nERROR: File %s must be saved in RIPaint with",ripfnm);
     printf("\nFile Width of %d or less.",MXRPLN-1);
     printf("\nUnable to use the rest of this file.  Hit any key...");
     getchc();
     fclose(ripfil);
     endrip();
     return(0);
}

VOID
stptwn (riplin)                  /* strip RIP_TEXT_WINDOW cmds from rip lin*/
CHAR *riplin;                    /*    RIP line to process                 */
{
     CHAR *cp,*cp2;

     cp=riplin;
     while ((cp2=strstr(cp,RIP_TEXT_WINDOW)) != NULL) {
          while (strncmp(cp2,RIP_TEXT_WINDOW,TWSIZ) == 0) {
               movmem(cp2+RTWSIZ,cp2,strlen(cp2+RTWSIZ)+1);
          }
          cp=cp2+1;
     }
}

INT
cntrnm (riplin)                  /* cnt # of RIP_NO_MORE's in a RIP line   */
CHAR *riplin;                    /*    RIP line to process                 */
{
     CHAR *cp,*cp2;
     register INT i;

     for (i=0,cp=riplin ; ((cp2=strstr(cp,RIP_NO_MORE)) != NULL)
                        ; i++,cp=cp2+1) {
     }
     return(i);
}

VOID                             /* place needed RIP commands at end of    */
endrip(VOID)                     /*    current scene, b4 ANSI part.        */
{
     CHAR buf[MXBFSZ];

     if (ivstxt) {
          fprintf(outfil,"!%s\n",RTXWCM);
     }
     if (addpsn) {
          rewind(psefil);
          while (fgets(buf,MXBFSZ,psefil) != NULL) {
               fprintf(outfil,"%s",buf);
          }
     }
     else {
          fprintf(outfil,"!%s\n",RNMOR3);
     }
}

GBOOL                            /* make sure we get valid file/path names,*/
vldpth(                          /*    plus display help is requested      */
INT c,                           /*      current input                     */
CHAR *sval)                      /*      buffer so far                     */
{
     if (c == F1) {
          shwhlp();
          return(FALSE);
     }
     return((isvalds(c) || isfiln(c,sval)) ? TRUE : FALSE);
}

GBOOL                         /* my flavor of validyn(), with provision to */
myvldyn(                      /*    display help if requested              */
INT c,                        /*      current input                        */
CHAR *stg)                    /*      buffer so far                        */
{
     if (c == F1) {
          shwhlp();
          return(FALSE);
     }
     if (tolower(c) == 'y') {
          strcpy(stg,"Yes");
     }
     else if (tolower(c) == 'n') {
          strcpy(stg,"No");
     }
     else {
          strcpy(stg,(stg[0] == 'Y' ? "No" : "Yes"));
     }
     if (rfcstt == APSSTT) {
          if (stg[0] == 'Y') {
               setatr(0x1E);
               prat(2,6,"%s","Pause Scene:");
               setatr(0x1B);
               prat(15,6,"%s",psflnm);
          }
          else {
               setatr(0x17);
               prat(2,6,"%s","Pause Scene:");
               setatr(0x13);
               prat(15,6,"%s",psflnm);
         }
     }
     else if (rfcstt == PACSTT) {
          setatr(0x1E);
          if (stg[0] == 'Y') {
               prat(28,8,"%s","(Hit RETURN to start)");
          }
          else {
               prat(28,8,"%22s","");
          }
     }
     return(FALSE);
}

VOID
shwhlp(VOID)                     /* show help screen to user               */
{
     CHAR savscn[GVIDSCNSIZ];
     INT savcur;

     scn2mem(savscn,0,GVIDSCNSIZ);
     savcur=curcurs();
     cursiz(GVIDNOCURS);
     explode(scntbl[1],0,0,79,24);
     getchc();
     mem2scn(savscn,0,GVIDSCNSIZ);
     cursiz(savcur);
}
