/***************************************************************************
 *                                                                         *
 *   AHTRANS.CPP                                                           *
 *                                                                         *
 *   Copyright (c) 1998  Galacticomm, Inc.        All Rights Reserved      *
 *                                                                         *
 *   Active HTML Teleconference Transport Layer                            *
 *   Implementation                                                        *
 *                                               - Phil Henning 6/14/97    *
 *                                                                         *
 ***************************************************************************/

#pragma option -w-par    // fixes warning in memory.h
#include "gcomm.h"
#include "majorbbs.h"
#include "stdcomp.h"
#include "tlcapi.hpp"
#include "ahtrans.hpp"
#pragma option -w-aus
#include <deque>
#pragma option -w-aus.
#include "iterand.h"
using namespace std;
#include "tlcahusr.hpp"

#define FILREV "$Revision: 73 $"

MARKSOURCE(ahtrans)

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

VOID
CAHTransport::RecvText(
CTlcUser* pUserFrom,
CTlcUser* pUserTo,
const CHAR* pMsg,
SHORT fType,
SHORT iMsgNum,
const CHAR* ptr1,
const CHAR* ptr2,
const CHAR* ptr3)
{
     CTlcAHUser* pAHUser;
     CTlcUser* pOthUser;
     GBOOL clrpr=FALSE;
     INT msg;

     ASSERT(pUserTo != NULL);
     if (!(pUserTo->m_fFlags&USR_INCHAN)
      && !((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 (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;
          }
     }
     if (pUserFrom == NULL && NeedFromUser(fType,iMsgNum)) {
          return;
     }

     switch (fType) {
     case RECV_TYPE_WHISPER:
          ASSERT(pUserFrom != NULL);
          prfmsg(WHSTO3
                ,colors[SEXIDX(pUserFrom->GetSex())],pUserFrom->GetName()
                ,pMsg);
          clrpr=TRUE;
          break;
     case RECV_TYPE_WHISPERFR:
          ASSERT(ptr1 != NULL);
          ASSERT(pUserFrom != NULL);
          pOthUser=sameas(ptr1,pUserTo->GetName()) ? pUserTo
                                                   : tlcAPI->usrGetByName(ptr1);
          ASSERT(pOthUser != NULL);
          prfmsg(WHSFRM3
                ,colors[SEXIDX(pUserFrom->GetSex())],pUserFrom->GetName()
                ,colors[SEXIDX(pOthUser->GetSex())],ptr1
                ,pMsg);
          clrpr=TRUE;
          break;
     case RECV_TYPE_INTRO:
          prfmsg(iMsgNum);
          clrpr=TRUE;
          break;
     case RECV_TYPE_EXIT:
          if (pMsg != NULL && *pMsg != '\0') {
               prfmsg(EXISKL2,pMsg);
          }
          else {
               ASSERT(pUserFrom != NULL);
               switch (iMsgNum) {
               case EXMSG_EXT_LEFTC:
                    msg=LEFTCH3;
                    prfmsg(msg
                     ,colors[SEXIDX(pUserFrom->GetSex())]
                     ,pUserFrom->GetName());
                    break;
               case EXMSG_EXT_HUP:
                    msg=TLCHUP2;
                    prfmsg(msg,pUserFrom->GetName());
                    break;
               case EXMSG_EXT_KICK:
                    msg=KICKDO2;
                    prfmsg(msg,pUserFrom->GetName());
                    break;
               case EXMSG_EXT_LEAVE:
               default:
                    msg=LVITLC3;
                    prfmsg(msg
                     ,colors[SEXIDX(pUserFrom->GetSex())]
                     ,pUserFrom->GetName());
                    break;
               }
          }
          clrpr=TRUE;
          break;
     case RECV_TYPE_ENTRANCE:
          if (pMsg != NULL && *pMsg != '\0') {
               prfmsg(EXISKL2,pMsg);
          }
          else {
               ASSERT(pUserFrom != NULL);
               msg=(iMsgNum == ENMSG_ENT_TELE ? ENTTLC3 : CAMEIN3);
               prfmsg(msg
                     ,colors[SEXIDX(pUserFrom->GetSex())]
                     ,pUserFrom->GetName());
          }
          clrpr=TRUE;
          break;
     case RECV_TYPE_USERLIST:
          break;
     case RECV_TYPE_WELCOME:
          prfmsg(iMsgNum,pMsg);
          clrpr=TRUE;
          break;
     case RECV_TYPE_DIRECTED:
          ASSERT(ptr1 != NULL);
          ASSERT(pUserFrom != NULL);
          pOthUser=sameas(ptr1,pUserTo->GetName()) ? pUserTo
                                                   : tlcAPI->usrGetByName(ptr1);
          ASSERT(pOthUser != NULL);
          prfmsg(DIRTO3
                ,colors[SEXIDX(pUserFrom->GetSex())],pUserFrom->GetName()
                ,colors[SEXIDX(pOthUser->GetSex())]
                ,sameas(ptr1,pUserFrom->GetName()) ? "you" : ptr1
                ,pMsg);
          clrpr=TRUE;
          break;
     case RECV_TYPE_NEWTOPIC:
// HACK: need colors here!
          ASSERT(pUserFrom != NULL);
          prfmsg(NOWTHE2,pUserFrom->GetName(),pMsg);
          clrpr=TRUE;
          break;
     case RECV_TYPE_ENTEREDEDIT:
// HACK: need colors here!
          ASSERT(pUserFrom != NULL);
          prfmsg(ENTEDT2,pUserFrom->GetName());
          clrpr=TRUE;
          break;
      case RECV_TYPE_RETEDIT:
// HACK: need colors here!
          ASSERT(pUserFrom != NULL);
          prfmsg(RETEDT,pUserFrom->GetName());
          clrpr=TRUE;
          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;
               break;
          }
          prfmsg(msg,ptr1);
          clrpr=TRUE;
          break;
     case RECV_TYPE_ACTION:
//HACK: files were causing problems before; let's try again
//          if (actIsFile()) {
//              return;
//          }
          actPrfFrame(iMsgNum,pMsg,ptr1);
          clrpr=TRUE;
          break;
     case RECV_TYPE_ENTCHAT:
          prfmsg(GONCHA,pUserFrom->GetName());
          clrpr=TRUE;
          break;
     case RECV_TYPE_RETCHATUSER:
          prfmsg(iMsgNum);
          pUserFrom=NULL;
          clrpr=TRUE;
          break;
     case RECV_TYPE_RETCHAT:
          prfmsg(RETCHAT,pUserFrom->GetName());
          clrpr=TRUE;
          break;
     case RECV_TYPE_CHATMSG:
          prfmsg(OTHCHAT3,pMsg);
          clrpr=TRUE;
          break;
     case RECV_TYPE_DBTOGGLE:
          break;
     case RECV_TYPE_USERENTER:
     case RECV_TYPE_USEREXIT:
          return;
     case RECV_TYPE_PAGE:
          clrpr=TRUE;
          break;
     case RECV_TYPE_PRFBUF:
          clrpr=FALSE;
          break;
     case RECV_TYPE_PUBLIC:
          ASSERT(pUserFrom != NULL);
          if (iMsgNum == 0) {
               iMsgNum=TLCFRM3;
//HACK: naughty.. we can't do this.. no colors should be done on the
//      default case since we don't KNOW if pUserFrom is NULL or not
//      maybe SEXIDX could be made into a function that would return a
//      a default color rather then bombing all the time
//      Then again, because of squelch issues, we probably don't want to
//      display anything at all.  Boy am I confused.
//      again, a problem with passing a NULL pUserFrom, we need
//      to check in existing code where we will be passing a NULL
//      (ie SYSUID) The default case may even have to be removed totally.
//      ( or at least rethought)
               prfmsg(iMsgNum
                ,colors[SEXIDX(pUserFrom->GetSex())]
                ,pUserFrom->GetName(), pMsg);
          }
          else {
               prfmsg(iMsgNum,pUserFrom->GetName(),pMsg,ptr1,ptr2,ptr3);
          }
          clrpr=TRUE;
          break;
     case RECV_TYPE_LISTCHG:
          return;
#if defined(DEBUG)
     default:
          shocst("TLC DEBUGAH","Unhandled receive type: %d",fType);
          return;
#endif // DEBUG
     }
//HACK: another bad one.. active h needs to know who its from
//      at this point, we can reasonably assume that it didn't
//      actually come from another user.
     strcat(prfbuf,"\t");
     strcat(prfbuf,pUserFrom == NULL ? SYSUID : pUserFrom->GetName());
     strcat(prfbuf,"\t");
     if (fType == RECV_TYPE_WHISPER || fType == RECV_TYPE_WHISPERFR) {
          strcat(prfbuf,"W");
     }
     else if (fType == RECV_TYPE_CHATMSG) {
          strcat(prfbuf,"C");
     }
     else {
          strcat(prfbuf,"N");
     }
     pAHUser=dynamic_cast<CTlcAHUser*>(pUserTo);
     if (pAHUser != NULL) {
          ASSERT(pAHUser->GetTransport() == this);
          pAHUser->AddMsg(prfbuf);
          if (clrpr) {
               clrprf();
          }
     }
}

VOID
CAHTransport::SendTabbedDbData(
const CHAR* data,
CTlcChannel* pChannel)
{
     CHAR* scratchbuf=new CHAR[strlen(data)+1];
     CTlcUser* pUser;

     pUser=GetFirstUser(pChannel);
     while (pUser != NULL) {
          VOID* SavePos=tlcAPI->usrGetPos();
          CTlcAHUser* pAHUser=reinterpret_cast<CTlcAHUser*>(pUser);
          if (pAHUser != NULL && !sameas(pAHUser->GetName(),curUser->GetName())) {
               ASSERT(pAHUser->GetTransport() == this);
               strcpy(scratchbuf,data);
               strrpl(scratchbuf,'\xff','\n');
               pAHUser->AddDbData(scratchbuf);
          }
          tlcAPI->usrSetPos(SavePos);
          pUser=GetNextUser(pChannel);
     }
     delete [] scratchbuf;
}

VOID
CAHTransport::CmdResult(
CTlcUser* pUser,
SHORT iOperation,
GBOOL bSuccess,
SHORT iReason)
{
     switch (iOperation) {
     case CMD_CHAT:
          switch (iReason) {
          case CMD_CHAT_ACCEPTED:
               prfmsg(ACCPCH2,pUser->GetChatUser());
               strcat(prfbuf,spr("\t%s\tC",SYSUID));
               (dynamic_cast<CTlcAHUser*>(pUser))->AddMsg(prfbuf);
               break;
          case CMD_CHAT_BEGIN:
               prfmsg(ENTCHA2);
               strcat(prfbuf,spr("\t%s\tC",SYSUID));
               (dynamic_cast<CTlcAHUser*>(pUser))->AddMsg(prfbuf);
               break;
          case CMD_CHAT_STOPCHATTING:
               clrprf();
               strcpy(prfbuf,spr("0\n\t%s\tS",static_cast<CHAR*>(tlcwrk)));
               (dynamic_cast<CTlcAHUser*>(pUser))->AddMsg(prfbuf);
               break;
          case CMD_CHAT_NOTIFY:
               clrprf();
               strcpy(prfbuf,spr("0\n\t%s\tR",static_cast<CHAR*>(tlcwrk)));
               (dynamic_cast<CTlcAHUser*>(pUser))->AddMsg(prfbuf);
               break;
          case CMD_CHAT_HANGUP:
               clrprf();
               strcpy(prfbuf,spr("0\n\t%s\tH",static_cast<CHAR*>(tlcwrk)));
               (dynamic_cast<CTlcAHUser*>(pUser))->AddMsg(prfbuf);
               break;
          default:
               CTlcTransport::CmdResult(pUser,iOperation,bSuccess,iReason);
               break;
          }
          clrprf();
          break;
     default:
          CTlcTransport::CmdResult(pUser,iOperation,bSuccess,iReason);
          break;
     }
}


VOID
CAHTransport::Output(
CTlcUser* pUser)
{
     strcat(prfbuf,spr("\t%s\tN",SYSUID));
     (dynamic_cast<CTlcAHUser*>(pUser))->AddMsg(prfbuf);
     clrprf();
}



