/***************************************************************************
 *                                                                         *
 *   TLC.CPP                                                               *
 *                                                                         *
 *   Copyright (c) 1997  Galacticomm, Inc.        All Rights Reserved      *
 *                                                                         *
 *   Teleconference Mainline                                               *
 *                                                                         *
 *                                               - Phil Henning 5/14/97    *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "tlcapi.hpp"
#include "tlcdynch.hpp"
#include "tlctm.h"
#include "tlccs.h"
#include "tlccmdm.h"

#define FILREV "$Revision: 82 $"

#define CHANFILE    "GALTEL.DAT"
#define MAINCHAN    "MAIN"

UINT iMale,
     iFemale;

CHAR colors[MAXANSI][ANSISIZ]={
        "\33[0;31m",   "\33[0;34m",   "\33[0;32m",   "\33[0;33m",
        "\33[0;35m",   "\33[0;36m",   "\33[0;37m",   "\33[0;1;31m",
        "\33[0;1;34m", "\33[0;1;32m", "\33[0;1;33m", "\33[0;1;35m",
        "\33[0;1;36m", "\33[0;1;37m"
};

CHAR dftchan[CHAN_MAX_SIZE];
CHAR* mainchan=MAINCHAN;
CHAR dirchr;
CHAR intdirchr[2];
SHORT* teltimes;
GBOOL* msgchanged;

INT tinpsz;
DFAFILE* dfaChan;
DFAFILE* dfaTlcUser;
HMCVFILE msgTlc;

CTlcAPI* tlcAPI;
VOID* tlcwrk;
SYSUSREDT tlcsysedt;               // Sysop user profile editor info
LPCHATINFO aachat;
SHORT n2inv,n2fgt,n2ign;

CTlcUser* curUser;
CTlcChannel* curChannel;
VOID (*oldInvisRou)(INT unum);

static VOID tlcDeleteUserHook(CHAR* userid);
static VOID tlcShutdownHook(VOID);
static VOID tlcInitChan(VOID);
static VOID tlcInitSecurity(VOID);
static GBOOL tlcCreateMain(VOID);
static VOID initapi(VOID);
static VOID InvisRou(INT unum);

MARKSOURCE(tlc)

VOID EXPORT
init__galtele()
{
     static GBOOL isinit=FALSE;
     if (isinit) {
          return;
     }
     isinit=TRUE;

     msgTlc=opnmsg("galtele.mcv");

     if ((iMale=tokopt(GUYCOL, "RED", "BLUE", "GREEN", "YELLOW", "MAGENTA"
                   ,"CYAN", "WHITE", "B_RED", "B_BLUE", "B_GREEN", "B_YELLOW"
                   ,"B_MAGENTA", "B_CYAN", "B_WHITE", NULL)) == 0) {
          catastro("Message Option \"GUYCOL\" is not set in message file \
           \"GALTELE.MSG\".");
     }
     iMale--;
     if ((iFemale=tokopt(GIRLCOL, "RED", "BLUE", "GREEN", "YELLOW", "MAGENTA"
                   ,"CYAN", "WHITE", "B_RED", "B_BLUE", "B_GREEN", "B_YELLOW"
                   ,"B_MAGENTA", "B_CYAN", "B_WHITE", NULL)) == 0) {
          catastro("Message Option \"GIRLCOL\" is not set in message file \
           \"GALTELE.MSG\".");
     }
     iFemale--;

     dfaChan=dfaOpen(CHANFILE,sizeof(CHANDSK),NULL);
     dfaTlcUser=dfaOpen(USERFILE,sizeof(USRDSK),NULL);
     tinpsz=numopt(TINPSZ,1,255);
     dirchr=chropt(DIRCHR);
     stlcpy(intdirchr,spr("%c",dirchr),2);
     tlcwrk=alczer(WRKBUFSIZ);
     aachat=static_cast<LPCHATINFO>(alczer(nterms*sizeof(CHATINFO)));
     msgchanged=static_cast<GBOOL*>(alczer(nterms*sizeof(GBOOL)));
     teltimes=static_cast<SHORT*>(alczer(nterms*sizeof(SHORT)));
     tlcSetDefaultChannel(mainchan);
     tlcAPI=new CTlcAPI;

     // really should disentangle this
     size_t chanSize=sizeof(CTlcLocPublicChannel);
     chanSize=max(sizeof(CTlcPrivateChannel),chanSize);
     chanSize=max(sizeof(CDynamicChannel),chanSize);
     size_t userSize=sizeof(CTlcUser);
     tlcAPI->DeclareObjSize(userSize,chanSize);

     // (VDA should be tm-only, some other things use vdatmp, though
     // tlcdcmd.cpp uses vdatmp but doesn't need to
     // tlcact.cpp needs to declare ABFSIZ

     n2fgt=(SHORT)numopt(N2FGT,8,64);
     n2inv=(SHORT)numopt(N2INV,8,64);
     n2ign=(SHORT)numopt(N2IGN,8,64);

     oldInvisRou=tlcInvisRou;
     tlcInvisRou=InvisRou;
     chanActionUpdateHook=dftchanActionUpdateHook;
     iniact();
     initpal();
     tlcInitTM();
     tlcInitCS();
#ifdef GCWINNT
     if (ynopt(USEAHTML)) {
          initactiveh();
          initActiveHLite();
          initahpag();
     }
#endif // GCWINNT

     hook_startup(initapi);        // give add-ons chance to DeclareObjSize
     hook_delacct(tlcDeleteUserHook);
     hook_shutdown(tlcShutdownHook);
}

static VOID
initapi(VOID)                      // delayed initialization
{
     setmbk(msgTlc);
     // finalize and create the user and channel smbs
     tlcInitSecurity();
     tlcAPI->Init();
     tlcInitChan();
     initForumChannels();
     rstmbk();
}

static VOID
InvisRou(                          // tele invisibility toggle handler
INT unum)
{
     CTlcUser* pUser;

     if ((pUser=tlcAPI->usrGetByName(uacoff(unum)->userid)) != NULL
      && pUser->GetUsrnum() >= 0) {
          if (usroff(unum)->flags&INVISB) {
               pUser->m_fFlags|=USR_INVISB;
          }
          else {
               pUser->m_fFlags&=~USR_INVISB;
          }
     }

     /*  This should not have to be done, but the exported function  */
     /*  Pointer in majorbbs.c was pointing to NULL instead of a     */
     /*  Blank stub function.  It is going to be fixed there, but    */
     /*  this was left for backwards compatability                   */
     if (oldInvisRou != NULL) {
          oldInvisRou(unum);
     }
}

static VOID
tlcDeleteUserHook(                 // hook for when system deletes User-ID
CHAR* userid)
{
     ASSERT(dfaTlcUser != NULL);

     dfaSetBlk(dfaTlcUser);
     if (dfaAcqEQ(NULL,userid,0)) {
          dfaDelete();
     }
     dfaRstBlk();
}

static VOID
tlcShutdownHook(VOID)              // hook for system shutdown
{
     ASSERT(dfaTlcUser != NULL);

     dwnForumChannels();
     if (dfaTlcUser != NULL) {
          dfaClose(dfaTlcUser);
          dfaTlcUser=NULL;
     }
     if (dfaChan != NULL) {
          dfaClose(dfaChan);
          dfaChan=NULL;
     }
     clsact();
     if (tlcAPI != NULL) {
          delete tlcAPI;
          tlcAPI=NULL;
     }
     tlcTMdwn();
     tlcCSdwn();

//HACK: shouldn't Active HTML have a shutdown, too?
}

static VOID
tlcInitChan(VOID)                  // load up pre-defined channels
{
     CHANDSK chanDsk;

     ASSERT(dfaChan != NULL);
     dfaSetBlk(dfaChan);

     // find or create main channel
     if (dfaAcqEQ(&chanDsk,MAINCHAN,0)) {
          tlcChannelCreateLocal(&chanDsk,TRUE);
     }
     else {
          tlcCreateMain();
     }

     // load up everything else
     if (dfaQueryLO(0)) {
          do {
               dfaAbsRec(&chanDsk,0);
               if (!sameas(MAINCHAN,chanDsk.m_strName)) {
                    tlcChannelCreateLocal(&chanDsk,TRUE);
               }
          } while (dfaQueryNX());
     }

     dfaRstBlk();
}

static GBOOL
tlcCreateMain()                    // create main channel
{
     CHANINFO chanInfo;

     memset(&chanInfo,0,sizeof(CHANINFO));
     stlcpy(chanInfo.m_strName,MAINCHAN,CHAN_MAX_SIZE);
     stlcpy(chanInfo.m_actList1,tlcAPI->m_actListP,LISTSIZ);
     stlcpy(chanInfo.m_actList2,tlcAPI->m_actListS,LISTSIZ);
     chanInfo.m_flags=CHAN_FLAG_PROFOK;
     stlcpy(chanInfo.m_keyJoin,getmsg(UNLKEY),KEYSIZ);
     stlcpy(chanInfo.m_keySpeak,getmsg(UNLKEY),KEYSIZ);
     stlcpy(chanInfo.m_keyMod,getmsg(TLCOPKY),KEYSIZ);
     stlcpy(chanInfo.m_keyByPass,getmsg(TLCOPKY),KEYSIZ);
     return(tlcChannelCreateLocal(&chanInfo,TRUE) == CHAN_CREATE_OK);
}

static VOID
tlcInitSecurity(VOID)
{
     tlcAPI->keySetSys(stgopt(TSYSKEY));      // Tele-Sysop key
     tlcAPI->keySetUnl(stgopt(UNLKEY));       // Unlimited use key

     tlcAPI->m_actListP=stgopt(DEFALST);
     tlcAPI->m_actListS=stgopt(DEFALST2);

     tlcAPI->m_iEtlpst=numopt(TELPOST,0,9999);
     tlcAPI->m_iTlcSur=numopt(TELCCR,-32767,32767);

     /* init yes-no options */
     tlcAPI->m_bWhs2Pag=ynopt(WHS2PAG);
     tlcAPI->m_bEMsgChg=ynopt(OKTOCG);
     tlcAPI->m_iEMsgChg=numopt(MSGCHG,1,32767);
     tlcAPI->m_bLogEMsg=ynopt(DISPAD);

     tlcAPI->m_bSwitFor=ynopt(SWTFOR);
     tlcAPI->m_bForSameChg=ynopt(TELCOV);

     tlcAPI->m_npaymx=numopt(NPAYMX,0,32767);
     tlcAPI->m_iSpeakThres=static_cast<USHORT>(numopt(SPTHRE,0,100));
     tlcAPI->m_iSpeedDrop=static_cast<USHORT>(numopt(SPDROP,0,10));
     tlcAPI->m_iSwitchThres=static_cast<USHORT>(numopt(NSWCHX,1,32767));
}

