/***************************************************************************
 *                                                                         *
 *   TLCFUNC.CPP                                                           *
 *                                                                         *
 *   Copyright (c) 1997 Galacticomm, Inc.         All Rights Reserved      *
 *                                                                         *
 *   Misc. Teleconference Functions                                        *
 *   Implementation                                                        *
 *                                               - Phil Henning 7/10/97    *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "tlcapi.hpp"
#include "gcspsrv.h"
#include "tlctm.h"
#include "tlccs.h"
#include "ahtrans.hpp"
#undef NOSUCH
#include "wgsmajor.h"

#define FILREV "$Revision: 50 $"

extern CAHTransport transAH;

static VOID
ExitChatUtil(                      // exit from chat utility
CTlcUser* pUser,                   //   primary user being removed
bool didleave,                     //   is this the user who left?
bool hangup);                      //   did the other user hang up?

// function definitions start here //

MARKSOURCE(tlcfunc);

VOID
RemoveInvite(
CTlcUser* pUser)
{
     CTlcChannel* pChannel;

     if ((pChannel=tlcAPI->chanGetFirst()) != NULL) {
          do {
               if (pChannel->GetType()&CHAN_TYPE_PRIVATE) {
                    CTlcPrivateChannel* pPrivate;
                    pPrivate=dynamic_cast<CTlcPrivateChannel*>(pChannel);
                    if (pPrivate->CheckInvite(pUser)) {
                         pPrivate->ToggleInvite(pUser);
                    }
               }
               pChannel=tlcAPI->chanGetNext();
          } while (pChannel != NULL);
     }
}

VOID EXPORT
RemoveInviteNUM(
ULONG user,
USHORT board)
{
     CTlcChannel* pChannel;

     if ((pChannel=tlcAPI->chanGetFirst()) != NULL) {
          do {
               if (pChannel->GetType()&CHAN_TYPE_PRIVATE) {
                    CTlcPrivateChannel* pPrivate;
                    pPrivate=dynamic_cast<CTlcPrivateChannel*>(pChannel);
                    if (pPrivate->CheckInviteNUM(user,board)) {
                         pPrivate->ToggleInviteNUM(user,board);
                    }
               }
               pChannel=tlcAPI->chanGetNext();
          } while (pChannel != NULL);
     }
}


VOID
RemoveForget(
CTlcUser* pUser)
{
     CHAR name[TLCUIDSIZ];
     CTlcUser* pCurUser;

     stzcpy(name,pUser->GetName(),TLCUIDSIZ);
     if ((pCurUser=tlcAPI->usrGetFirst()) != NULL) {
          do {
               if (pCurUser->CheckForget(pUser)) {
                    pCurUser->ToggleForget(pUser);
               }
               pCurUser=tlcAPI->usrGetNext();
          } while (pCurUser != NULL);
     }
}

VOID EXPORT
RemoveForgetNUM(
ULONG user,
USHORT board)
{
     CTlcUser* pCurUser;
     if ((pCurUser=tlcAPI->usrGetFirst()) != NULL) {
          do {
               if (pCurUser->CheckNUM(user,board,LIST_FORGET)) {
                    pCurUser->ToggleNUM(user,board,LIST_FORGET);
               }
               pCurUser=tlcAPI->usrGetNext();
          } while (pCurUser != NULL);
     }
}


GBOOL
IsUserInvis(
CTlcUser* pUser)
{
     if (pUser->m_fFlags&USR_INVISB) {
          return(TRUE);
     }
     return(FALSE);
}

VOID
chgnot(
const CHAR* userid,
const CHAR* type)                 // write enter/exit/image email
{
     static struct message tlcmsg;
     CHAR *cp;

     setmbk(msgTlc);
     if (strlen(rawmsg(EINUSR)) == 0) {
          rstmbk();
          return;
     }
     INT saveLingo=clingo;
     clingo=0;
     clrprf();
     prfmsg(EINOTC,userid,type);
     stpans(prfbuf);
     if (strlen(prfbuf) >= TXTLEN) {
          prfbuf[TXTLEN-1]='\0';
     }
     for (cp=prfbuf ; *cp != '\0' ; cp++) {
          if (*cp == '\n') {
               *cp='\r';
          }
          else if (*cp == '\a') {
               *cp=' ';
          }
     }
     memset(&tlcmsg,0,sizeof(struct message));
     stlcpy(tlcmsg.to,rawmsg(EINUSR),MAXADR);
     stlcpy(tlcmsg.from,userid,MAXADR);
     stlcpy(tlcmsg.topic,rawmsg(EITOPC),TPCSIZ);
     simpsnd(&tlcmsg,prfbuf,NULL);
     clrprf();
     clingo=saveLingo;
     rstmbk();
}

bool
chkalph(
const CHAR* stg)
{
     if (NULSTR(stg)) {
          return(FALSE);
     }
     while (isalpha(*stg)) {
          ++stg;
     }
     return(*stg == '\0');
}

VOID
logcrd(
const CHAR* user,
LONG credits)
{
     shocst("TELECONFERENCE CREDIT CHARGE","Userid: %s Credits: %ld",user,credits);
}

CTlcUser*
UserStructToClass(
LPUSRSTRUCT st)
{
     if (st == NULL) {
          return (NULL);
     }
     return(tlcAPI->chanFindUser(st->m_pszChannel,st->m_pszName));
}


CHAR
tlchat(INT chan, INT ch)
{
     INT oth;
     CHAR c;

     oth=aachat[chan].chatch;
     c=((CHAR)ch)&eurmsk;
     switch (c) {
     case '\r':
          chiinp(oth,c);
          chiout(oth,c);
          chiout(oth,'\n');
          return(c);
     case '\b':
          chiinp(oth,c);
          chiout(oth,c);
          chiout(oth,' ');
          chiout(oth,c);
          return(c);
     default:
          if (c >= 32) {
               if (!(aachat[chan].flags&TYPING)) {
                    if (uacoff(oth)->ansifl&ANSON) {
                         chious(oth,"\33[32m");
                    }
                    if (uacoff(chan)->ansifl&ANSON) {
                         chious(chan,"\33[33m");
                    }
                    aachat[chan].flags|=TYPING;
                    aachat[oth].flags&=~TYPING;
               }
               chiinp(oth,c);
               chiout(oth,c);
               return(c);
          }
     }
     return(0);
}

VOID
ExitChat(                          // exit from chat
GBOOL hangup,                      //   one of the users disconnected
const CHAR* userid,                //   current user
GBOOL didleave)                    //   is the user the one who is gone?
{

     CTlcUser* pUser=tlcAPI->usrGetByName(userid);
     ASSERT(pUser != NULL);
     CTlcUser* pOthUser=tlcAPI->usrGetByName(pUser->GetChatUser());

     curChannel=tlcAPI->chanGetByName(pUser->GetChannelName());
     ExitChatUtil(pOthUser,!didleave,hangup);
     ExitChatUtil(pUser,didleave,hangup);
}

static VOID
ExitChatUtil(                       // exit from chat utility
CTlcUser* pUser,                    //   primary user being removed
bool didleave,                      //   is this the guy who hungup?
bool hangup)                        //   are we exiting because of disconnect?
{
     INT savusn=usrnum;

     if (pUser == NULL || (didleave && hangup)) {
          return;
     }
     if (pUser->GetUsrnum() >= 0) {
          curusr(pUser->GetUsrnum());
     }
     else {
          clingo=0;
     }
     stlcpy((CHAR*)tlcwrk,pUser->GetChatUser(),TLCUIDSIZ);
     pUser->CmdResult(CMD_CHAT,FALSE,hangup ? CMD_CHAT_HANGUP
                                            : CMD_CHAT_STOPCHATTING);
     pUser->m_fFlags&=~USR_CHATTING;
     if (didleave && !hangup) {
          pUser->OnRecvText(pUser->GetChatUser(),NULL,NULL
                              ,RECV_TYPE_RETCHATUSER, EXICH3);
     }
     else if (!didleave && hangup) {
          pUser->OnRecvText(pUser->GetChatUser(),NULL,NULL
                              ,RECV_TYPE_RETCHATUSER, ECHHP3);
     }
     pUser->SetChatUser(NULL);
     curusr(savusn);
}

SHORT
chk4pfn(VOID)                      // check input for profanity
{
     SHORT retval=PFN_NONE;

     if (!(curChannel->m_flags&CHAN_FLAG_PROFOK)) {
          if (curUser->m_pfnacc > MAXPFN) {
               retval=PFN_HANGUP;
          }
          else if (pfnlvl >= 2 && curUser->m_pfnacc > WRNPFN) {
               prfmsg(RAUNCH2);
               retval=PFN_WARNED;
          }
          else if (pfnlvl >= 2) {
               prfmsg(PFNWRD2);
               retval=PFN_WARNED;
          }
          if (usrptr->usrcls == ACTUSR) {
               curUser->m_pfnacc=usrptr->pfnacc;
          }
          else {
               curUser->m_pfnacc+=pfnlvl;
          }
     }
     return(retval);
}

VOID
tlcusrson(VOID)                          /* display-users-online utility    */
{
     INT res;
     CTlcUser* pUser;

     setmbk(mjrmb);
     prfmsg(ULSHDR);
     curUser->GetTransport()->Output(curUser);
     for (othusn=0 ; othusn < nterms ; othusn++) {
          othusp=usroff(othusn);
          if ((res=incusr(othusn,TRUE,FALSE)) > VACANT) {
               othuap=uacoff(othusn);
               switch (res) {
               case ONLINE:
                    prfmsg(ULSLIN,channel[othusn],"(log-on)","");
                    break;
               case SUPIPG:
                    prfmsg(ULSLIN,channel[othusn],"(sign-up)","");
                    break;
               default:
                    prfmsg(ULSLIN,channel[othusn],othuap->userid,
                    module[othusp->state]->descrp);
               }
               curUser->GetTransport()->Output(curUser);
          }
     }
     setmbk(msgTlc);
     if ((pUser=transAH.GetFirstUser(NULL)) != NULL) {
          do {
               if (!onsysn(pUser->GetName(),1)) {
                    prfmsg(ULSLINA2,"AH",pUser->GetName(),tlcmod.descrp);
                    curUser->GetTransport()->Output(curUser);
               }
          } while ((pUser=transAH.GetNextUser(NULL)) != NULL);
     }
     rstmbk();
     prfmsg(ULSTRL);
     curUser->GetTransport()->Output(curUser);
     rstmbk();
}

VOID
csnotaddchan(
CTlcChannel* pChannel,
INT unum)
{
     int start=unum;

     if (pChannel->m_flags&CHAN_FLAG_NOLIST) {
          return;
     }
     *cssndbuf='\0';
     strcat(cssndbuf,pChannel->GetName());
     strcat(cssndbuf,spr("\t%s",pChannel->GetTopic()));
     if (start < 0) {
          start=0;
     }
     for (int i=start ; i < nterms ; i++) {
          if (usroff(i)->usrcls == ACTUSR && usroff(i)->flags&ISGCSU) {
               CTlcUser* pUser=tlcAPI->usrGetByName(uacoff(i)->userid);
               if (pUser != NULL && pUser->GetUsrnum() == i) {
                    if (pChannel->GetType()&CHAN_TYPE_PRIVATE) {
                         CTlcPrivateChannel* pPrivate=dynamic_cast<CTlcPrivateChannel*>(pChannel);
                         if (!(pPrivate->CheckInvite(pUser))
                          && !(pUser->IsTypeOf(USR_OPERATOR))
                          && !(sameas(pUser->GetName(),pPrivate->GetOwner()))) {
                              if (unum > -1) {
                                   break;
                              }
                              continue;
                         }
                    }
                    if (pChannel->CanAccess(pUser,CHAN_AXS_SEE) && qroom(i,NORMAL)) {
                         INT savusn=usrnum;
                         curusr(i);
                         cnvd2s(tlcdpks[DPK_ADDCHAN],namtmp);
                         stlcpy(namtmp->usrid,uacoff(i)->userid,UIDSIZ);
                         senddpk(i,TLCAPID,NORMAL,namtmp,STGLEN,cssndbuf,NULL);
                         curusr(savusn);
                    }
               }
          }
          if (unum > -1) {
               break;
          }
     }
}

VOID
csnotdelchan(
CTlcChannel* pChannel,
INT unum)
{
     int start=unum;
     INT savusn;

     if (pChannel->m_flags&CHAN_FLAG_NOLIST) {
          return;
     }
     *cssndbuf='\0';
     strcpy(cssndbuf,pChannel->GetName());
     if (start < 0) {
          start=0;
     }
     for (int i=start ; i < nterms ; i++) {
          if (usroff(i)->usrcls == ACTUSR && usroff(i)->flags&ISGCSU) {
               CTlcUser* pUser=tlcAPI->usrGetByName(uacoff(i)->userid);
               if (pUser != NULL && pUser->GetUsrnum() == i) {
                    if (qroom(i,NORMAL)) {
                         savusn=usrnum;
                         curusr(i);
                         cnvd2s(tlcdpks[DPK_DELCHAN],namtmp);
                         stlcpy(namtmp->usrid,uacoff(i)->userid,UIDSIZ);
                         senddpk(i,TLCAPID,NORMAL,namtmp,STGLEN,cssndbuf,NULL);
                         curusr(savusn);
                    }
               }
          }
          if (unum > -1) {
               break;
          }
     }
}

VOID
cschgstatus(
CTlcUser* thisUser,
CTlcUser* changedUser)
{
     INT unum=-1;

     if (thisUser != NULL) {
          if ((unum=thisUser->GetUsrnum()) < 0) {
               return;
          }
     }
     INT maxloop=(unum < 0) ? nterms : unum+1;
     unum=(unum < 0) ? 0 : unum;
     for (int i=unum ; i < maxloop; i++) {
          if (usroff(i)->flags&ISGCSU) {
               CTlcUser* pUser=tlcAPI->usrGetByName(uacoff(i)->userid);
               if (pUser != NULL) {
                    strcpy(cssndbuf,changedUser->GetName());
                    strcat(cssndbuf,"\t");
                    strcat(cssndbuf,thisUser->CheckInvite(changedUser) ? "1" : "0");
                    strcat(cssndbuf,"\t");
                    strcat(cssndbuf,changedUser->m_fFlags&USR_SQUELCH ? "1" : "0");
                    strcat(cssndbuf,"\t");
                    strcat(cssndbuf,thisUser->CheckForget(changedUser) ? "1" : "0");
                    strcat(cssndbuf,"\t");
                    strcat(cssndbuf,thisUser->CheckIgnore(changedUser) ? "1" : "0");
                    strcat(cssndbuf,"\t");
                    strcat(cssndbuf,changedUser->m_fFlags&USR_UNLIST ? "1" : "0");
                    if (qroom(i,NORMAL)) {
                         INT savusn=usrnum;
                         curusr(i);
                         cnvd2s(tlcdpks[DPK_USERSTAT],namtmp);
                         stlcpy(namtmp->usrid,uacoff(i)->userid,UIDSIZ);
                         senddpk(i,TLCAPID,NORMAL,namtmp,STGLEN,cssndbuf,NULL);
                         curusr(savusn);
                    }
               }
          }
     }
}


GBOOL
teleIsLocal(
CTlcUser* pUser)
{
     if (pUser->m_uiTlcBoardNum == 0) {
          return(TRUE);
     }
     return (FALSE);
}
