/***************************************************************************
 *                                                                         *
 *   LINGO.C                                                               *
 *                                                                         *
 *   Copyright (c) 1993-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   Multilingual information gathering and storage, based on info in      *
 *   the MJRBBS.CFG file.                                                  *
 *                                                                         *
 *   Used by CNF, WGSMTREE, WGSMSX, MSGUTL, etc.                           *
 *                                                                         *
 *                                    - Robert N. Stein 1/7/93             *
 *                                                                         *
 ***************************************************************************/

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

#define FILREV "$Revision: 4 $"

                                   /*--- variables set by inilingo() ---   */
INT nlingo=0;                      /* number of languages                  */
INT clingo=0;                      /* current language                     */
struct lingo **languages=NULL; /* dyn array of pointers to lingo structures*/
struct lingo *lnghead=NULL,*lngtail;     /* linked list of lingo structures*/
VOID (*msghdl)(CHAR *msgnam)=NULL;/* application-specific msg file handler */
                                   /* called by inilingo() if non-NULL     */
                     /* caution, may give you duplicate core MSG file names*/
                                   /* default user-language info structure */

static INT algstt;                 /* internal state for alg1st()/algnxt() */
static INT alglgo;                 /* original lingo for alg1st()/algnxt() */

VOID
inilingo(VOID)                     /* read and construct lingo info array  */
{
     INT ilingo=0;
     struct lingo *lngptr=NULL;

     if (languages != NULL) {
          return;
     }
     if (tfsopn(LINGOFILE) != 1) {
          catastro("CANNOT FIND "LINGOFILE);
     }
     while (tfsrdl() != TFSDUN) {
          if (tfstate == TFSLIN && tfspfx("NLingo=")) {
               nlingo=atoi(tfspst);
               alclng();
               break;
          }
     }
     if (languages == NULL) {
          catastro(LINGOFILE" IS MISSING THE \"NLingo=\" LINE");
     }
     while (tfsrdl() != TFSDUN) {
          if (tfstate == TFSLIN && tfspfx("LNG")) {
               tfsdpr();
               if (tfspfx("=")) {
                    if (ilingo >= nlingo) {
                         catastro("MORE THAN NLINGO \"LNG=\" LINES IN "LINGOFILE);
                    }
                    languages[ilingo]=lngptr=(struct lingo *)
                                       alczer(sizeof(struct lingo));
                    stzcpy(lngptr->name,tfspst,LNGSIZ);
                    ilingo++;
               }
               else if (lngptr == NULL) {
                    catastro("FIRST LNGXXX= OPTION IN "LINGOFILE
                    " MUST BE LNG=");
               }
               else if (tfspfx("DSC=")) {
                    stzcpy(lngptr->desc,tfspst,LNGDSC);
               }
               else if (tfspfx("EXT=")) {
                    stfext(lngptr,tfspst);
               }
               else if (tfspfx("EDT=")) {
                    stzcpy(lngptr->editor,tfspst,LNGEDT);
               }
               else if (tfspfx("YES=")) {
                    stzcpy(lngptr->yes,tfspst,LNGYN);
               }
               else if (tfspfx("NO=")) {
                    stzcpy(lngptr->no,tfspst,LNGYN);
               }
          }
     }
     if (ilingo != nlingo) {
          catastro("LESS THAN NLINGO \"LNG=\" LINES IN "LINGOFILE);
     }
}

VOID
stfext(                            /* put exts into .ANS, .ASC, .IBM fields*/
struct lingo *lp,                  /*   destination structure              */
CHAR *exts)                        /*   extentions                         */
{
     CHAR *extans,*extasc,*extibm;

     extans=strtok(exts,DELIMS);
     if (extans == NULL) {
          extans="";
     }
     extasc=strtok(NULL,DELIMS);
     extibm=strtok(NULL,DELIMS);
     stzcpy(lp->extans,extans,LNGEXT);
     stzcpy(lp->extasc,extasc == NULL ? extans : extasc,LNGEXT);
     stzcpy(lp->extibm,extibm == NULL ? extans : extibm,LNGEXT);
}

VOID
alclng(VOID)                       /* allocate *languages[] array of ptrs  */
{
     languages=(struct lingo **)alczer(nlingo*sizeof(struct lingo *));
}

INT                                /*   rets idx 0..nlingo-1 or -1=not fnd */
lngfnd(                            /* find a language by name              */
CHAR *lngnam)                      /*   name to search for                 */
{
     INT i,ilingo,found;

     found=0;
     for (i=0 ; i < nlingo ; i++) {
          if (sameto(lngnam,languages[i]->name)) {
               if (sameas(lngnam,languages[i]->name)) {
                    return(i);
               }
               found++;
               ilingo=i;
          }
     }
     return(found == 1 ? ilingo : -1);
}

INT                                /*   rets idx 0..nlingo-1 or -1=not fnd */
chgspk(                            /* determine if there is an alt. lang   */
INT lgo,                           /*   lingo                              */
CHAR *spoken)                      /*   change lang to this                */
{
     INT pslash;
     CHAR lngbuf[LNGSIZ+40];

     if ((pslash=findstg("/",languages[lgo]->name)) == 0) {
          return(-1);
     }
     strcpy(lngbuf,spoken);
     strcat(lngbuf,languages[lgo]->name+pslash-1);
     lngbuf[LNGSIZ]='\0';
     return(lngfnd(lngbuf));
}

INT                                /*   rets idx 0..nlingo-1 or -1=not fnd */
chgprt(                            /* determine if an alt. protocol exists */
INT lgo,                           /*   lingo                              */
CHAR *protoc)                      /*   change protocol to this            */
{
     INT pslash;
     CHAR lngbuf[LNGSIZ+40];

     if ((pslash=findstg("/",languages[lgo]->name)) == 0) {
          return(-1);
     }
     stzcpy(lngbuf,languages[lgo]->name,pslash+1);
     strcat(lngbuf,protoc);
     return(lngfnd(lngbuf));
}

VOID
alg1st(                            /* prepare to seek alternate languages  */
INT lgo)                           /*   lingo to begin with                */
{
     alglgo=lgo;
     algstt=0;
}

INT                                /*   rets idx 0..nlingo-1 or 0=not fnd  */
algnxt(VOID)                       /* seek alternate languages             */
{
     INT i;

     switch(algstt) {
     case 0:                             /* try changing protocol to DFTPRT */
          if ((i=chgprt(alglgo,DFTPRT)) != -1 && i != alglgo) {
               algstt=1;
               return(i);
          }
     case 1:                             /* try changing language to DFTSPK */
          if ((i=chgspk(alglgo,DFTSPK)) != -1 && i != alglgo) {
               algstt=2;
               return(i);
          }
     }
     return(0);                                      /* give up, use DFTLNG */
}
