/***************************************************************************
 *                                                                         *
 *   TLCCSTRA.CPP                                                          *
 *                                                                         *
 *   Copyright (c) 1998 Galacticomm, Inc.         All Rights Reserved      *
 *                                                                         *
 *   Teleconference Client/Server Transport Implementation                 *
 *                                                                         *
 *                                              - Phil Henning 8/14/97     *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "tlcapi.hpp"
#include "gcspsrv.h"
#include "tlccs.h"
#include "tlccstra.h"

#define FILREV "$Revision: 66 $"

MARKSOURCE(tlccstra);

CCSTransport::CCSTransport() : CTlcTransport()
{
     m_fFlags|=(TRANS_IMPLDB|TRANS_IMPLCHAT|TRANS_IMPLPRIV);
}

VOID
CCSTransport::RecvText(            // Send text to one user
CTlcUser* pUserFrom,               //   user object sending text (NULL = system)
CTlcUser* pUserTo,                 //   user object receiving text
const CHAR* pMsg,                  //   Text to send
SHORT fType,                       //   Type of text
SHORT iMsgNum,                     //   Type of event
const CHAR* ptr1,                  //   extra information
const CHAR* ptr2,                  //   extra information
const CHAR* ptr3)                  //   extra information
{
     ASSERT(pUserTo != NULL);
     if (!(pUserTo->m_fFlags&USR_INCHAN)
      && fType != RECV_TYPE_USERENTER
      && fType != RECV_TYPE_USEREXIT
      && fType != RECV_TYPE_SWITCHCHAN
      && !((pUserTo->m_fFlags&USR_CHATTING) && (fType == RECV_TYPE_CHATMSG))) {
          return;
     }
     if (fType == RECV_TYPE_CHATMSG
      && (!(pUserTo->m_fFlags&USR_CHATTING)
        || !sameas(pUserTo->GetChatUser(),pUserFrom->GetName()))) {
          return;
     }
     if (pUserFrom == NULL) {
          if (NeedFromUser(fType,iMsgNum)) {
               return;
          }
     }
     else {
          if (pUserTo->CheckForget(pUserFrom)) {
               return;
          }
          if (fType == RECV_TYPE_ACTION
           && (pUserTo->m_fFlags&USR_NOACTIONS
            || pUserTo->CheckIgnore(pUserFrom)
            || (tmpAList != NULL
             && !pUserTo->CheckAccess(tmpAList->GetConfigPtr()->seekey)))) {
               return;
          }
     }
     RecvTextLowLevel(pUserFrom,pUserTo,pMsg,fType,iMsgNum,ptr1,ptr2,ptr3);
}


VOID
CCSTransport::RecvTextLowLevel(
CTlcUser* pUserFrom,               //   user object sending text (NULL = system)
CTlcUser* pUserTo,                 //   user object receiving text
const CHAR* pMsg,
SHORT fType,
SHORT iMsgNum,
const CHAR* ptr1,
const CHAR* ptr2,
const CHAR* ptr3)
{
     GBOOL clprf=TRUE;
     INT msg;
     SHORT dpk;
     CTlcUser* pUserTemp;

     INT savnum=usrnum;
     INT unum=pUserTo->GetUsrnum();
     ASSERT(0 <= unum && unum < nterms);
     curusr(unum);

     const CHAR* pszUseridFrom=(pUserFrom == NULL ? SYSUID : pUserFrom->GetName());

     switch (fType) {
     case RECV_TYPE_WHISPER:
          ASSERT(pUserFrom != NULL);
          prfmsg(WHSTO3,colors[SEXIDX(pUserFrom->GetSex())],pszUseridFrom,pMsg);
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          dpk=DPK_WHISPER;
          break;
     case RECV_TYPE_WHISPERFR:
          ASSERT(ptr1 != NULL);
          ASSERT(pUserFrom != NULL);
          pUserTemp=sameas(ptr1, usaptr->userid) ? pUserTo
                                                 : tlcAPI->usrGetByName(ptr1);
          ASSERT(pUserTemp != NULL);
          prfmsg(WHSFRM3
                ,colors[SEXIDX(pUserFrom->GetSex())],usaptr->userid
                ,colors[SEXIDX(pUserTemp->GetSex())],ptr1
                ,pMsg);
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          dpk=DPK_WHISPER;
          break;
     case RECV_TYPE_EXIT:
          if (!NULSTR(pMsg)) {
               prfmsg(EXISKL2,pMsg);
          }
          else {
               switch (iMsgNum) {
               case EXMSG_EXT_LEFTC:
                    ASSERT(pUserFrom != NULL);
                    prfmsg(LEFTCH3
                          ,colors[SEXIDX(pUserFrom->GetSex())],pszUseridFrom);
                    break;
               case EXMSG_EXT_HUP:
                    prfmsg(TLCHUP2,pszUseridFrom);
                    break;
               case EXMSG_EXT_KICK:
                    prfmsg(KICKDO2,pszUseridFrom);
                    break;
               case EXMSG_EXT_LEAVE:
               default:
                    ASSERT(pUserFrom != NULL);
                    prfmsg(LVITLC3
                          ,colors[SEXIDX(pUserFrom->GetSex())],pszUseridFrom);
                    break;

               }
           }
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          dpk=DPK_EXIT;
          break;
     case RECV_TYPE_ENTCHAT:
          prfmsg(GONCHA,pUserFrom->GetName());
          sprintf(cssndbuf,"%s",prfbuf);
          clprf=TRUE;
          dpk=DPK_MISC;
          break;
     case RECV_TYPE_ENTRANCE:
          if (!NULSTR(pMsg)) {
               prfmsg(EXISKL2,pMsg);
          }
          else {
               ASSERT(pUserFrom != NULL);
               msg=(iMsgNum == ENMSG_ENT_TELE ? ENTTLC3 : CAMEIN3);
               prfmsg(msg,colors[SEXIDX(pUserFrom->GetSex())],pszUseridFrom);
          }
          dpk=DPK_ENT;
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          break;
     case RECV_TYPE_SWITCHCHAN:
          switch (iMsgNum) {
          case SCMSG_CHAN_DELETE:
               msg=CHNDELD2;
               break;
          case SCMSG_USER_LOGOFF:
               msg=HKICKO3;
               break;
          case SCMSG_CHAN_FORUPD:
               msg=FORCUPD;
               break;
          default:
               msg=iMsgNum;
          }
          prfmsg(msg,ptr1);
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          dpk=DPK_MISC;
          break;
     case RECV_TYPE_USERENTER:
          sprintf(cssndbuf,"%s\t%s\t%c\t%hd\t%d",pszUseridFrom
               ,curChannel->GetName(),pUserFrom->GetSex(),pUserFrom->GetAge()
               ,(pUserFrom->m_fFlags&USR_UNLIST));
          dpk=DPK_USERENTER;
          clprf=FALSE;
          break;
     case RECV_TYPE_USEREXIT:
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,curChannel->GetName());
          dpk=DPK_USEREXIT;
          clprf=FALSE;
          break;
     case RECV_TYPE_DIRECTED:
          ASSERT(ptr1 != NULL);
          ASSERT(pUserFrom != NULL);
          pUserTemp=sameas(ptr1, usaptr->userid) ? pUserTo
                                                 : tlcAPI->usrGetByName(ptr1);
          ASSERT(pUserTemp != NULL);
          prfmsg(DIRTO3,colors[SEXIDX(pUserFrom->GetSex())],pszUseridFrom
                ,colors[SEXIDX(pUserTemp->GetSex())]
                ,sameas(ptr1,usaptr->userid) ? "you" : ptr1
                ,pMsg);
          sprintf(cssndbuf,"%s\t%s\t%s",pszUseridFrom
                 ,sameas(ptr1,usaptr->userid) ? "" : ptr1
                 ,prfbuf);
          dpk=DPK_DIRECTED;
          break;
     case RECV_TYPE_INTRO:
          prfmsg(iMsgNum);
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          dpk=DPK_INTRO;
          break;
     case RECV_TYPE_USERLIST:
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          clprf=FALSE;
          dpk=DPK_USERLIST;
          break;
     case RECV_TYPE_WELCOME:
          prfmsg(iMsgNum,pMsg);
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          dpk=DPK_WELCOME;
          break;
     case RECV_TYPE_NEWTOPIC:
          prfmsg(NOWTHE2,pszUseridFrom,pMsg);
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          dpk=DPK_NEWTOPIC;
          break;
     case RECV_TYPE_ENTEREDEDIT:
          prfmsg(ENTEDT2,pszUseridFrom);
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          dpk=DPK_ENTEDIT;
          break;
     case RECV_TYPE_RETEDIT:
          prfmsg(RETEDT,pszUseridFrom);
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          dpk=DPK_RETEDIT;
          break;
     case RECV_TYPE_ACTION:
          actPrfFrame(iMsgNum,pMsg,ptr1);
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          clprf=TRUE;
          dpk=DPK_ACTION;
          break;
     case RECV_TYPE_DBTOGGLE:
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          clprf=FALSE;
          dpk=DPK_DBTOGGLE;
          break;
     case RECV_TYPE_RETCHATUSER:
          prfmsg(iMsgNum);
          sprintf(cssndbuf,"%s",prfbuf);
          clprf=TRUE;
          dpk=DPK_CHAT;
          break;
     case RECV_TYPE_RETCHAT:
          prfmsg(RETCHAT,pszUseridFrom);
          sprintf(cssndbuf,"%s",prfbuf);
          clprf=TRUE;
          dpk=DPK_MISC;
          break;
     case RECV_TYPE_CHATMSG:
          sprintf(cssndbuf,"%s",pMsg);
          clprf=FALSE;
          dpk=DPK_CHAT;
          break;
     case RECV_TYPE_DBOARDDATA:
          if (qroom(usrnum,NORMAL)) {
               senddpk(usrnum,TLCAPID,NORMAL,namtmp,STGLEN,cssndbuf,NULL);
          }
          curusr(savnum);
          return;
     case RECV_TYPE_PAGE:
     case RECV_TYPE_PRFBUF:
          sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
          clprf=FALSE;
          dpk=DPK_MISC;
          break;
     case RECV_TYPE_PUBLIC:
          ASSERT(pUserFrom != NULL);
          if (iMsgNum == 0) {
               prfmsg(TLCFRM3
                ,colors[SEXIDX(pUserFrom->GetSex())]
                ,pszUseridFrom, pMsg);
               sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
               dpk=DPK_SPEAK;
          }
          else {
               prfmsg(iMsgNum,pszUseridFrom,pMsg,ptr1,ptr2,ptr3);
               sprintf(cssndbuf,"%s\t%s",pszUseridFrom,prfbuf);
               dpk=DPK_MISC;
          }
          break;
     case RECV_TYPE_LISTCHG:
          if (pUserFrom != NULL) {
               cschgstatus(pUserTo,pUserFrom);
          }
          curusr(savnum);
          return;
#if defined(DEBUG)
     default:
          shocst("TLC DEBUGAH","Unhandled receive type: %d",fType);
          return;
#endif // DEBUG
     }
     if (qroom(usrnum,NORMAL)) {
          cnvd2s(spr("%s",tlcdpks[dpk]),namtmp);
          tlcreflow(cssndbuf);
          senddpk(usrnum,TLCAPID,NORMAL,namtmp,STGLEN,cssndbuf,NULL);
     }
#ifdef DEBUG
     else {
          shocst("TELECONFERENCE ERROR","No QueueRoom! - RecvText");
     }
#endif //DEBUG
     if (clprf) {
          clrprf();
     }
     curusr(savnum);
}

VOID
CCSTransport::Output(
CTlcUser* pUser)
{
     memset(cssndbuf,0,CSSNDBUFSIZ);
     tlcreflow(prfbuf);
     sprintf(cssndbuf,"%s",prfbuf);
     clrprf();
     prf("");
     INT savusn=usrnum;
     curusr(pUser->GetUsrnum());
     if (qroom(usrnum,NORMAL)) {
          cnvd2s(spr("%s",tlcdpks[DPK_MISC]),namtmp);
          senddpk(usrnum,TLCAPID,NORMAL,namtmp,STGLEN,cssndbuf,NULL);
     }
#ifdef DEBUG
     else {
          shocst("TELECONFERENCE ERROR","No QueueRoom! - Output");
     }
#endif // DEBUG

     curusr(savusn);
}

VOID
CCSTransport::SendTabbedDbData(
const CHAR* data,
CTlcChannel* pChannel)
{
     CTlcUser* pUser;

     strcpy(cssndbuf,data);
     strrpl(cssndbuf,'\n',0xff);
     pUser=GetFirstUser(pChannel);
     while (pUser != NULL) {
          if (pUser->m_fFlags&USR_DBOARD) {
               if (!sameas(curUser->GetName(),pUser->GetName())) {
                    VOID* SavePos=tlcAPI->usrGetPos();
                    cnvd2s(spr("sa=GALTELE;u=%s;:%s",pUser->GetName(),"snddbl"),namtmp);
                    RecvText(curUser,pUser,NULL,RECV_TYPE_DBOARDDATA,0);
                    tlcAPI->usrSetPos(SavePos);
               }
          }
          pUser=GetNextUser(pChannel);
     }
}

VOID
CCSTransport::CmdResult(
CTlcUser* pUser,
SHORT iOperation,
GBOOL bSuccess,
SHORT iReason)
{
     INT usn=pUser->GetUsrnum();
     INT savusn=usrnum;

     switch (iOperation) {
     case CMD_CHAT:
          switch (iReason) {
          case CMD_CHAT_STOPCHATTING:
          case CMD_CHAT_HANGUP:
               if (sameas(pUser->GetChatUser(),static_cast<CHAR*>(tlcwrk))) {
                    memset(cssndbuf,0,CSSNDBUFSIZ);
                    strcpy(cssndbuf,static_cast<CHAR*>(tlcwrk));
                    if (usn > -1 && qroom(usn,NORMAL)) {
                         curusr(usn);
                         cnvd2s(tlcdpks[DPK_REJCHAT],namtmp);
                         stlcpy(namtmp->usrid,pUser->GetName(),UIDSIZ);
                         senddpk(usn,TLCAPID,NORMAL,namtmp,STGLEN
                                ,cssndbuf,NULL);
                         curusr(savusn);
                    }
               }
               break;
          case CMD_CHAT_NOTIFY:
               prfmsg(CHAREQ2,curUser->GetName(),
                    curUser->GetSex() == 'F' ? "her" : "him",
                    curUser->GetName());
               sprintf(cssndbuf,"%s\t%s",curUser->GetName(),prfbuf);
               if (usn > -1 && qroom(usn,NORMAL)) {
                    curusr(usn);
                    cnvd2s(tlcdpks[DPK_REQCHAT],namtmp);
                    stlcpy(namtmp->usrid,pUser->GetName(),UIDSIZ);
                    senddpk(usn,TLCAPID,NORMAL,namtmp,STGLEN,prfbuf,NULL);
                    curusr(savusn);
               }
               clrprf();
               break;
          case CMD_CHAT_ACCEPTED:
               clrprf();
               prfmsg(ACCPCH2,pUser->GetChatUser());
               if (usn > -1 && qroom(usn,NORMAL)) {
                    curusr(usn);
                    cnvd2s(tlcdpks[DPK_STARTCHAT],namtmp);
                    stlcpy(namtmp->usrid,pUser->GetName(),UIDSIZ);
                    senddpk(usn,TLCAPID,NORMAL,namtmp,STGLEN,prfbuf,NULL);
                    curusr(savusn);
               }
               clrprf();
          case CMD_CHAT_BEGIN:
               clrprf();
               prfmsg(ENTCHA2,pUser->GetName());
               if (usn > -1 && qroom(usn,NORMAL)) {
                    curusr(usn);
                    cnvd2s(tlcdpks[DPK_STARTCHAT],namtmp);
                    stlcpy(namtmp->usrid,pUser->GetName(),UIDSIZ);
                    senddpk(usn,TLCAPID,NORMAL,namtmp,STGLEN,prfbuf,NULL);
                    curusr(savusn);
               }
               clrprf();
               break;
          default:
               CTlcTransport::CmdResult(pUser,iOperation,bSuccess,iReason);
               break;
          }
          return;
     default:
          break;
     }

     CTlcTransport::CmdResult(pUser,iOperation,bSuccess,iReason);

     switch (iOperation) {
     case CMD_JOIN:
          if (bSuccess) {
               memset(cssndbuf,0,CSSNDBUFSIZ);
               if (usn > -1 && qroom(usn,NORMAL)) {
                    curusr(usn);
                    strcpy(cssndbuf,pUser->GetChannelName());
                    cnvd2s(tlcdpks[DPK_CHANCHG],namtmp);
                    senddpk(usn,TLCAPID,NORMAL,namtmp,STGLEN,cssndbuf,NULL);
                    curusr(savusn);
               }
#ifdef DEBUG
               else {
                    shocst("TELECONFERENCE ERROR","No QueueRoom! - CmdResult");
               }
#endif // DEBUG
          }
          break;
     }
}
