/***************************************************************************
 *                                                                         *
 *   BBSINTRO.C                                                            *
 *                                                                         *
 *   Copyright (c) 1988-1997 Galacticomm, Inc.  All Rights Reserved.       *
 *                                                                         *
 *   Introductory menu.                                                    *
 *                                                                         *
 *                                                 RNStein  October 1988   *
 *                                             && S. Brinker  April 1991   *
 *                                             && T. Stryker February 1992 *
 *                                             && R. Stein   February 1993 *
 *                                             && R. Stein   April 1993    *
 *                                                                         *
 ***************************************************************************/

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

#define FILREV "$Revision: 24 $"

/***************************************************************************

     ERRORLEVEL return values (for use by batch files):
     --------------------------------------------------
     0    "Exit System" option picked
     10   hardware setup picked
     20   design menu tree picked
     30   accounting/security picked
     40   general setup option picked
     50   Go Online! picked
     60   edit text blocks picked
     70   offline utility menu picked
     200  fatal startup error

***************************************************************************/

#define NEEDFH  80                         /* number of file handles needed */
#define NSCNS    4                         /* number of screens in scntbl[] */


extern CHAR scntbl[NSCNS][GVIDSCNSIZ]; /* table of mem-resident CRT screens */

struct option {                                 /* Data on each menu option */
     CHAR stroke;                                    /* keystroke to invoke */
     INT x,y;                          /* position on screen of menu option */
     CHAR u,d,l,r;                               /* connects for arrow keys */
     CHAR *title;                                         /* name of option */
} options[] = {
     {'0',55,20,'7','1','5','3',"Exit System"},
     {'1', 4,12,'0','2','6','4',"Hardware Setup"},
     {'2', 4,16,'1','3','7','5',"Design Menu Tree"},
     {'3', 4,20,'2','4','0','5',"Security and \n   Accounting"},
     {'4',31,14,'3','5','1','6',"General Setup"},
     {'5',31,18,'4','6','2','7',"Go Online!"},
     {'6',55,12,'5','7','4','1',"Edit Text Blocks"},
     {'7',55,16,'6','0','5','2',"Offline Utilities"}
};

INT helpx=12,helpy=23;                              /* location of help box */
INT exicode=-1;                          /* exit code for ERRORLEVEL in DOS */
struct option *cursor;                                    /* options cursor */

CHAR *help[]={                             /* help messages for each option */
     "Exit from " SVR_NAME " to the operating system.",
     "Configure your modems, LAN ports, X.25 circuits, etc.",
     "Set up the \"tree\" of menus presented to your users.",
     "Configure locks & keys, online charges, demo lines, etc.",
     "Modify options such as server name, ANSI detection, etc.",
     "Run " SVR_NAME ": begin taking calls and serving users.",
     "Modify the built-in blocks of text seen by users online.",
     "Choose from a menu of utilities...",
};


GBOOL mjrup(VOID);
GBOOL anychg(GBOOL firsttime);     /* (from ANYCHG.C)                      */
VOID rdymnu(VOID);

static GBOOL mcvdif(VOID);
static VOID draw(INT hilite);
static VOID newpos(CHAR ch,INT cleanup);
static INT fhtest(CHAR *fname);
static VOID omp(VOID);

INT
main(
INT argc,
CHAR *argv[])
{
TRY
     INT i,c;         /*01234567*/ /* where you're starting from           */
     static CHAR fwd[]="12345670"; /* where to go after PgDn, etc.         */
     static CHAR rev[]="70123456"; /* where to go after PgUp, etc.         */

     initvid();
     for (i=0 ; i < NSCNS ; i++) {
          cvtscn(scntbl[i]);
     }
     mem2scn(scntbl[0],0,GVIDSCNSIZ);
     setatr(0x1f);
     printfat(37,7,BBSVERSTG);
     cursiz(GVIDLILCURS);
     switch (argc) {
     case 1:
          if (fhtest("wgsintro.exe") < NEEDFH) {
               explodeto(scntbl[2],0,0,68,20,6,3);
               cursiz(GVIDNOCURS);
               getchc();
               rstcur();
               setatr(0x07);
               printfat(0,24," \b");
               return(200);
          }
          if (mjrup()) {
               mem2scn(scntbl[0],0,GVIDSCNSIZ);
               setatr(0x1f);
               printfat(37,7,BBSVERSTG);
               locate(25,23);
               setatr(0x3E);
               printf(".........................................");
          }
          if (mcvdif()) {
               system("wgsmsx");
          }
          if (anychg(TRUE)) {
               system("wgsint");
               if (anychg(FALSE)) {     /* in case Install: line in an .MDF */
                    system("wgsint");   /* makes a change (ETL did this)    */
               }
          }
          else if (isfile(MISSREQ)) {
               system("wgsint/w");
          }
          rdymnu();
          newpos('5',0);
          break;
     case 2:
          if (isdigit(*argv[1])) {
               newpos(*argv[1],0);
               break;
          }
          newpos('5',0);
          break;
     }
     cursiz(GVIDNOCURS);
     while (exicode < 0) {
          c=getchc();
          if (c == '\r') {
               c=cursor->stroke;
          }
          switch (c) {
          case F1:
          case F2:
          case F3:
          case F4:
          case F5:
          case F6:
          case F7:
               c=((c-F1)>>8)+'1';
          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
          case '0':
               newpos(c,1);
               exicode=(c-'0')*10;
               if (c >= '1' && c <= '6') {   // option 7 doesn't need omp()
                    omp();
               }
               break;
          case F10:
          case ESC:
               newpos('0',1);
               exicode=0;
               break;
          case CRSRUP:
               newpos(cursor->u,1);
               break;
          case CRSRDN:
               newpos(cursor->d,1);
               break;
          case CRSRLF:
               newpos(cursor->l,1);
               break;
          case CRSRRT:
               newpos(cursor->r,1);
               break;
          case ' ':
          case '\t':
          case PGDN:
          case END:
               newpos(fwd[cursor->stroke-'0'],1);
               break;
          case '\b':
          case BAKTAB:
          case PGUP:
          case HOME:
               newpos(rev[cursor->stroke-'0'],1);
               break;
          }
     }
     cursiz(GVIDLILCURS);
     setatr(0x07);
     printfat(0,24," \b");
     return(exicode);
EXCEPT
#ifdef GCWINNT
     setatr(0x07);
     cursiz(GVIDLILCURS);
     printfat(0,24," \b");
     return(exicode);
#endif // GCWINNT
}

GBOOL
mcvdif(VOID)                       /* any .MSG / .MCV inconsistencies?     */
{
     struct ffblk msgfb,mcvfb;
     CHAR buf[GCMAXPTH];

     if (fnd1st(&msgfb,"*.msg",0)) {
          do {
               fileparts(GCPART_FILE,msgfb.ff_name,buf,sizeof(buf));
               if (!fndfile(&mcvfb,spr("%s.mcv",buf),0)
                 || mcvfb.ff_fdate != msgfb.ff_fdate
                 || mcvfb.ff_ftime != msgfb.ff_ftime) {
                    return(TRUE);
               }
          } while (fndnxt(&msgfb));
     }
     return(FALSE);
}

VOID
draw(                                             /* show an option */
INT hilite)
{
     locate(cursor->x,cursor->y);
     setatr(hilite ? 0x0F : 0x70);
     printf(" %c ",cursor->stroke);
     locate(cursor->x+5,cursor->y);
     setatr(hilite ? 0x70 : 0x1F);
     setwin(0L,cursor->x+5,0,79,24,0);
     printf(" %s ",cursor->title);
     rstwin();
}

VOID
newpos(                                /* point to a new option */
CHAR ch,
INT cleanup)
{
     if (cleanup) {
          draw(0);
     }
     cursor=options+ch-'0';
     draw(1);
     locate(helpx,helpy);
     setatr(0x3E);
     printf("%-57s",help[ch-'0']);
}

VOID
omp(VOID)                                     /* say "One moment please..." */
{
     locate(helpx,helpy);
     setatr(0x3E);
     printf("One moment please");
     printf("...%36s","");
}

INT
fhtest(                                           /* File handle test */
CHAR *fname)
{
     FILE *fh[NEEDFH];
     INT i,n;

     locate(25,23);
     setatr(0x3E);
     for (n=0 ; n < NEEDFH ; n++) {
          if ((fh[n]=fopen(fname,"rb")) == NULL) {
               break;
          }
          if (n&1) {
               printf(".");
          }
     }
     for (i=0 ; i < n ; i++) {
          fclose(fh[i]);
     }
     return(n);
}

