/***************************************************************************
 *                                                                         *
 *   TLCAPIC.CPP                                                           *
 *                                                                         *
 *   Copyright (c) 1997, Galacticomm, Inc.        All Rights Reserver      *
 *                                                                         *
 *   Teleconference "C" API                                                *
 *                                                                         *
 *                                                - Phil Henning 9/29/97   *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "tlcapi.hpp"
#include "tlcdyntr.hpp"
#include "tlcdyncm.hpp"
#include "tlcdynch.hpp"

#define FILREV "$Revision: 49 $"
MARKSOURCE(tlcapic)

/***************************************************************************
 *   User related functions                                                *
 ***************************************************************************/

#define GETUSER(x,z)     CTlcUser* pUser;    \
                         if ((pUser=tlcAPI->usrGetByName(x)) == NULL) return(z)

LPUSRSTRUCT EXPORT
tlcUserGetInfo(
const CHAR* userid)
{
     CTlcUser* pUser;

     ASSERT(userid != NULL);
     if ((pUser=tlcAPI->usrGetByName(userid)) == NULL) {
          return(NULL);
     }
     return(pUser->GetUserStruct());
}

GBOOL EXPORT
tlcUserSetInfo(
LPUSRSTRUCT stUsr)
{
     CTlcUser* pUser;

     ASSERT(stUsr != NULL);

     if ((pUser=tlcAPI->usrGetByName(stUsr->m_pszName)) == NULL) {
          return(FALSE);
     }
     pUser->SetUserStruct(stUsr);
     return(TRUE);
}

GBOOL EXPORT
tlcUserCheckAccess(
const CHAR* userid,
const CHAR* key)
{
     GETUSER(userid,FALSE);

     return(pUser->CheckAccess(key));
}

GBOOL EXPORT
tlcUserCheckAccessM(
const CHAR* userid,
SHORT key)
{
     GETUSER(userid,FALSE);

     return(pUser->CheckAccess(rawmsg(key)));
}

GBOOL EXPORT
tlcUserSendText(
const CHAR* userid,
const CHAR* from,
const CHAR* to,
const CHAR* pMsg,
SHORT fType,
SHORT iMsgNum,
const CHAR* ptr1,
const CHAR* ptr2,
const CHAR* ptr3)
{
     GETUSER(userid,FALSE);

     UNREFERENCED(to);
     if (pUser->m_bBeingDeleted) {
         pUser=tlcAPI->usrGetNext();
     }
     if (pUser == NULL) {
         return(FALSE);
     }
     ASSERT(sameas(pUser->m_pszName,userid));
     pUser->OnRecvText(from,NULL,pMsg,fType,iMsgNum,ptr1,ptr2,ptr3);
     return(TRUE);
}

GBOOL EXPORT
tlcUserInChannel(
const CHAR* userid,
const CHAR* channel)
{
     GETUSER(userid,FALSE);

     if (sameas(pUser->GetChannelName(),channel)) {
          return(TRUE);
     }
     return(FALSE);
}

SHORT EXPORT
tlcUserSwitchChannel(
const CHAR* userid,
const CHAR* channel)
{
     CTlcChannel* pCurChannel;
     CTlcChannel* pNewChannel;

     GETUSER(userid,NOSUCHUSER);


     ASSERT(channel != NULL);
     if ((pNewChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(NOSUCHCHAN);
     }
     setmbk(msgTlc);
     if (!sameas(pUser->GetChannelName(),channel)) {
          CTlcUser* pNewUser;
          pCurChannel=tlcAPI->chanGetByName(pUser->GetChannelName());
          ASSERT(pCurChannel != NULL);
          pNewChannel->AddUser(pUser);
          pNewUser=tlcAPI->chanFindUser(pNewChannel->GetName(),pUser->GetName());
          pCurChannel->RemoveUser(pUser,LEAVE_CHANNEL);

          pNewUser->CmdResult(CMD_JOIN,TRUE,0);
          rstmbk();
          return(JOINOK);
     }
     rstmbk();
     return(ALRDYINCHAN);
}

GBOOL EXPORT
tlcUserInTlc(
const CHAR* userid)
{
     GETUSER(userid,FALSE);
     UNREF(pUser);
     return(TRUE);
}

GBOOL EXPORT
tlcUserCreate(
LPUSRSTRUCT stUsr,
INT iTrans,
const CHAR* channel)
{
     CTlcUser User;
     CTlcUser* pUser;
     CTlcChannel* pChannel;

     if (channel == NULL || (pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(FALSE);
     }
     User.SetUserStruct(stUsr);
     User.m_iSize=sizeof(CTlcUser);
     tlcTransAddUser(iTrans,stUsr);

     pUser=tlcAPI->usrAdd(&User);
     tlcUserSetTransport(pUser->GetName(),iTrans);
     pUser->m_fFlags|=USR_INCHAN;
     tlcAPI->chanAddUser(channel,pUser->GetName());
     pChannel->m_count++;

     curChannel=pChannel;
     tlcAPI->usrDelete(pUser);
     return(TRUE);
}

GBOOL EXPORT
tlcUserRemove(
const CHAR* userid,
const CHAR* channel)
{
     CTlcChannel* pChannel;
     INT trans;
     GETUSER(userid,FALSE);

     if (channel == NULL || (pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(FALSE);
     }
     if (!sameas(pUser->m_pszChannel,channel)) {
          return (FALSE);
     }
     trans=tlcTransUserIs(pUser->GetName());
     tlcTransRemoveUser(trans,pUser->GetUserStruct());
     tlcAPI->chanRemoveUser(channel,pUser->GetName());
     curChannel=pChannel;
     pChannel->m_count--;
     return(TRUE);
}

ULONG EXPORT
tlcUserFindID(
const CHAR* userid)
{
     return(tlcAPI->FindIDByUser(userid));
}

ULONG EXPORT
tlcUserCreateUniqueID(
const CHAR* userid)
{
     return(tlcAPI->CreateUniqueID(userid));
}

LPUSRSTRUCT EXPORT
tlcUserGetFirst()
{
     CTlcUser* pUser;

     pUser=tlcAPI->usrGetFirst();
     if (pUser == NULL) {
          return(NULL);
     }
     return(pUser->GetUserStruct());
}

LPUSRSTRUCT EXPORT
tlcUserGetNext()
{
     CTlcUser* pUser;

     pUser=tlcAPI->usrGetNext();
     if (pUser == NULL) {
          return(NULL);
     }
     return(pUser->GetUserStruct());
}

LPUSRSTRUCT EXPORT
tlcUserGetGT(
const CHAR* userid)
{
     CTlcUser* pUser;
     pUser=tlcAPI->usrGetGT(userid);
     if (pUser == NULL) {
          return(NULL);
     }
     return(pUser->GetUserStruct());
}

VOID EXPORT
tlcUserSetTransport(
const CHAR* userid,
INT idx)
{
     CTlcUser* pUser;
     CTlcTransport* pTransport;
     INT cnt=0;

     pUser=tlcAPI->usrGetByName(userid);
     pTransport=tlcAPI->transGetFirst();
     while (cnt < idx) {
          pTransport=tlcAPI->transGetNext();
          cnt++;
     }
     if (pTransport != NULL) {
          pUser->SetTransport(pTransport);
     }
     ASSERT(pTransport != NULL);

}

INT EXPORT
tlcUserGetTransport(
const CHAR* userid)
{
     return(tlcTransUserIs(userid));
}

GBOOL
tlcUserCheckIgnore(
const CHAR* userid,
const CHAR* chkuid)
{
     ASSERT(userid != NULL);
     ASSERT(chkuid != NULL);

     CTlcUser* pUser=tlcAPI->usrGetByName(userid);
     CTlcUser* pOthUser=tlcAPI->usrGetByName(chkuid);

     ASSERT(pUser != NULL);

     return(pUser->CheckIgnore(pOthUser));
}


GBOOL
tlcUserCheckForget(
const CHAR* userid,
const CHAR* chkuid)
{
     ASSERT(userid != NULL);
     ASSERT(chkuid != NULL);

     CTlcUser* pUser=tlcAPI->usrGetByName(userid);
     CTlcUser* pOthUser=tlcAPI->usrGetByName(chkuid);

     ASSERT(pUser != NULL);

     return(pUser->CheckForget(pOthUser));
}

const CHAR*
tlcUserGetChatUser(
const CHAR* userid)
{
     GETUSER(userid,"");

     return(pUser->GetChatUser());
}

GBOOL
tlcUserSetChatUser(
const CHAR* userid,
const CHAR* chatuser)
{
     GETUSER(userid,FALSE);

     pUser->SetChatUser(chatuser);
     return(TRUE);
}

GBOOL
tlcUserChatBegin(
const CHAR* userid,
SHORT context)
{
     GETUSER(userid,FALSE);

     pUser->ChatBegin(context);
     return(TRUE);
}

LPUSRSTRUCT
tlcUserSetContext(
const CHAR* userid)
{
     GETUSER(userid,NULL);

     curUser=pUser;
     return(tlcUserGetContext());
}

LPUSRSTRUCT
tlcUserGetContext()
{
     if (curUser != NULL) {
          return(curUser->GetUserStruct());
     }
     return(NULL);
}


/***************************************************************************
 *   Channel related functions                                                *
 ***************************************************************************/

SHORT EXPORT
tlcChannelCreateCustom(
LPCHANINFO pChanInfo,
LPCHFUNCPTRS pFuncs)
{
     SHORT retval;
     CDynamicChannel Chan(tlcAPI,pFuncs);

     ASSERT(pChanInfo != NULL);
     Chan.m_iCrConsumptionRate=pChanInfo->m_iCrConsumptionRate;
     if ((retval=Chan.Create(pChanInfo)) != CHAN_CREATE_OK) {
          return(retval);
     }
     if (tlcAPI->chanRegister(&Chan) == NULL) {
          retval=CHAN_API_CREATE_ERR;
     }
     return(retval);
}

SHORT EXPORT
tlcChannelCreateLocal(
LPCHANDSK pChanDsk,
GBOOL persist)
{
     SHORT retval;
     CHANINFO chanInfo;
     CTlcLocPublicChannel Chan(tlcAPI);

     ASSERT(pChanDsk != NULL);
     memset(&chanInfo,0,sizeof(CHANINFO));
     memmove(&chanInfo,pChanDsk,sizeof(CHANDSK));
     if ((retval=Chan.Create(&chanInfo)) != CHAN_CREATE_OK) {
          return(retval);
     }
     if (persist) {
          Chan.Save();
     }

     Chan.m_iCrConsumptionRate=tlcAPI->m_iTlcSur;
     if (tlcAPI->chanRegister(&Chan) == NULL) {
          retval=CHAN_API_CREATE_ERR;
     }
     return(retval);
}

SHORT EXPORT
tlcChannelCreatePrivate(
const CHAR* owner,
LPCHANDSK pChanDsk)
{
     SHORT retval;
     CHANINFO chanInfo;
     CTlcPrivateChannel Chan(tlcAPI);

     memset(&chanInfo,0,sizeof(CHANINFO));
     if (pChanDsk == NULL) {
          stlcpy(chanInfo.m_strName,tlcPrivateFromUser(owner),CHAN_MAX_SIZE);
          stlcpy(chanInfo.m_actList1,tlcAPI->m_actListP,LISTSIZ);
          stlcpy(chanInfo.m_actList2,tlcAPI->m_actListS,LISTSIZ);
     }
     else {
          memmove(&chanInfo,pChanDsk,sizeof(CHANDSK));
     }
     if ((retval=Chan.Create(&chanInfo)) != CHAN_CREATE_OK) {
          return(retval);
     }
     Chan.SetOwner(owner);
     Chan.m_iCrConsumptionRate=tlcAPI->m_iTlcSur;
     dfaSetBlk(dfaTlcUser);
     if (dfaAcqEQ(NULL,owner,0)) {
          Chan.SetTopic(((LPUSRDSK)dfaTlcUser->data)->m_pszPrivateTopic);
     }
     dfaRstBlk();
     if (tlcAPI->chanRegister(&Chan) == NULL) {
          retval=CHAN_API_CREATE_ERR;
     }
     return(retval);
}

VOID EXPORT
tlcChannelDelete(
LPCHANINFO pChanInfo)
{
     tlcChannelMoveAllUsers(pChanInfo->m_strName,dftchan
                           ,CHAN_SWITCH_DELETED,SCMSG_CHAN_DELETE);
     tlcChannelRemove(pChanInfo->m_strName);
}

CHAR* EXPORT
tlcChannelFindUser(
const CHAR* channel,
const CHAR* pszSearch,
INT* num,
LPUSRSTRUCT* ppUser)
{
     CTlcChannel* pChannel=tlcAPI->chanGetByName(channel);
     CHAR* rv;

     CTlcUser* pUser=NULL;
     if (channel != NULL) {
          rv=pChannel->FindUser(pszSearch,num,&pUser);
     }
     else {
          rv=tlcAPI->FindUserMsg(pszSearch,num,&pUser);
     }
     if (pUser != NULL) {
          *ppUser=dynamic_cast<LPUSRSTRUCT>(pUser);
     }
     else {
          *ppUser=NULL;
     }
     return(rv);
}


VOID EXPORT
tlcChannelMoveAllUsers(
const CHAR* channel,
const CHAR* to,
SHORT reason,
SHORT msg)
{
     tlcAPI->chanMoveAllUsers(channel,to,reason,msg);
}

VOID EXPORT
tlcChannelRemove(
const CHAR* channel)
{
     tlcAPI->chanRemoveByName(channel);
}

VOID EXPORT
tlcChannelRemoveUser(
const CHAR* channel,
const CHAR* userid,
SHORT reason)
{
     CTlcChannel* pChannel;
     CTlcUser* pUser;

     if ((pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return;
     }
     if ((pUser=tlcAPI->chanFindUser(channel,userid)) == NULL) {
          return;
     }
     pChannel->RemoveUser(pUser,reason);
}

LPUSRSTRUCT EXPORT
tlcChannelGetFirstUser(
const CHAR* channel)
{
     CTlcUser* pUser;

     pUser=tlcAPI->usrGetFirst();
     while (pUser != NULL) {
          if (sameas(pUser->GetChannelName(),channel)) {
               return(pUser->GetUserStruct());
          }
          pUser=tlcAPI->usrGetNext();
     }
     return(NULL);
}

LPUSRSTRUCT EXPORT
tlcChannelGetNextUser(
const CHAR* channel)
{
     CTlcUser* pUser;

     pUser=tlcAPI->usrGetNext();
     while (pUser != NULL) {
          if (sameas(pUser->GetChannelName(),channel)) {
               return(pUser->GetUserStruct());
          }
          pUser=tlcAPI->usrGetNext();
     }
     return(NULL);
}

LPUSRSTRUCT EXPORT
tlcChannelGetUserGT(
const CHAR* channel,
const CHAR* userid)
{
     CTlcUser* pUser;

     pUser=tlcAPI->usrGetGT(userid);
     while (pUser != NULL) {
          if (sameas(pUser->GetChannelName(),channel)) {
               return(pUser->GetUserStruct());
          }
          pUser=tlcAPI->usrGetNext();
     }
     return(NULL);
}

LPCHANINFO EXPORT
tlcChannelGetInfo(
const CHAR* channel)
{
     CTlcChannel* pChannel;

     if ((pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(NULL);
     }
     return(pChannel->GetConfig());
}

GBOOL EXPORT
tlcChannelSetInfo(
LPCHANINFO pChanInfo)
{
     CTlcChannel* pChannel;

     if ((pChannel=tlcAPI->chanGetByName(pChanInfo->m_strName)) == NULL) {
          return(FALSE);
     }
     return(pChannel->Update(pChanInfo));
}

GBOOL EXPORT
tlcChannelPublicSend(
const CHAR* channel,
const CHAR* pszUseridFrom,
const CHAR* pszUseridTo,
const CHAR* pMsg,
SHORT fType,
SHORT iMsgNum,
const CHAR* ptr1,
const CHAR* ptr2,
const CHAR* ptr3)
{
     CTlcChannel* pChannel;

     if ((pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(FALSE);
     }
     pChannel->PublicSend(pszUseridFrom,pszUseridTo,pMsg,fType,
                          iMsgNum,ptr1,ptr2,ptr3);
     return(TRUE);
}

GBOOL EXPORT
tlcChannelPublicSendBut(
const CHAR* channel,
const CHAR* pszUseridFrom,
const CHAR* pszUseridTo,
const CHAR* pMsg,
SHORT fType,
SHORT iMsgNum,
const CHAR* ptr1,
const CHAR* ptr2,
const CHAR* ptr3,
const CHAR* pszUseridNot1,
const CHAR* pszUseridNot2)
{
     CTlcChannel* pChannel;

     if ((pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(FALSE);
     }
     pChannel->PublicSendBut(pszUseridFrom,pszUseridTo,pMsg,fType,
                          iMsgNum,ptr1,ptr2,ptr3,pszUseridNot1,pszUseridNot2);
     return(TRUE);
}

GBOOL EXPORT
tlcChannelPrivateSend(
const CHAR* channel,
const CHAR* pszUseridFrom,
const CHAR* pszUseridTo,
const CHAR* pMsg,
SHORT fType,
SHORT iMsgNum,
const CHAR* ptr1,
const CHAR* ptr2,
const CHAR* ptr3)
{
     CTlcChannel* pChannel;

     if ((pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(FALSE);
     }
     return(pChannel->PrivateSend(pszUseridFrom,pszUseridTo,pMsg,fType,
                          iMsgNum,ptr1,ptr2,ptr3));
}

GBOOL EXPORT
tlcPrivateChannelIsInvited(
const CHAR* channel,
const CHAR* userid)
{
     CTlcChannel* pChannel;
     CTlcPrivateChannel* pPrivate;
     CTlcUser* pUser;

     if (channel == NULL || (pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(FALSE);
     }
     if (!(pChannel->GetType()&CHAN_TYPE_PRIVATE)) {
          return(TRUE);
     }
     if (userid == NULL || (pUser=tlcAPI->usrGetByName(userid)) == NULL) {
          return(FALSE);
     }
     pPrivate=dynamic_cast<CTlcPrivateChannel*>(pChannel);
     return(pPrivate->CheckInvite(pUser));
}

GBOOL EXPORT
tlcPrivateChannelInvite(
const CHAR* channel,
const CHAR* userid)
{
     CTlcChannel* pChannel;
     CTlcPrivateChannel* pPrivate;
     CTlcUser* pUser;

     if (channel == NULL || (pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(FALSE);
     }
     if (!(pChannel->GetType()&CHAN_TYPE_PRIVATE)) {
          return(TRUE);
     }
     if (userid == NULL || (pUser=tlcAPI->usrGetByName(userid)) == NULL) {
          return(FALSE);
     }
     pPrivate=dynamic_cast<CTlcPrivateChannel*>(pChannel);
     return(pPrivate->ToggleInvite(pUser));
}

LPCHANINFO EXPORT
tlcChannelGetFirst(VOID)
{
     CTlcChannel* pChannel;

     pChannel=tlcAPI->chanGetFirst();
     if (pChannel != NULL) {
          return(pChannel->GetConfig());
     }
     return(NULL);
}

LPCHANINFO EXPORT
tlcChannelGetNext(VOID)
{
     CTlcChannel* pChannel;

     pChannel=tlcAPI->chanGetNext();
     if (pChannel != NULL) {
          return(pChannel->GetConfig());
     }
     return(NULL);
}

LPCHANINFO EXPORT
tlcChannelGetGT(
const CHAR* channel)
{
     CTlcChannel* pChannel;

     pChannel=tlcAPI->chanGetGT(channel);
     if (pChannel != NULL) {
          return(pChannel->GetConfig());
     }
     return(NULL);
}

INT EXPORT
tlcChannelGetNumberUsers(
const CHAR* channel)
{
     CTlcChannel* pChannel;

     if (channel == NULL || (pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(-1);
     }
     return(pChannel->GetNumUsers());
}

GBOOL EXPORT
tlcChannelRegisterCmd(
const CHAR* channel,
LPCMDSTRUCT pCmdSt)
{
     CTlcChannel* pChannel;
     CTlcCommand* pCmd;

     if (channel == NULL || (pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(FALSE);
     }
     if (pChannel->m_pfxCmds == NULL) {
          CTlcCmdList *pCList;
          pCList=new CTlcCmdList;
          pChannel->SetCommandList(pCList);
     }
     pCmd=new CDynamicCommand(pCmdSt);
     return(pChannel->cmdRegister(pCmd));
}

VOID EXPORT
tlcPublicSendAllChannels(
const CHAR* pszUseridFrom,
const CHAR* pszUseridTo,
const CHAR* pMsg,
SHORT fType,
SHORT iMsgNum,
const CHAR* ptr1,
const CHAR* ptr2,
const CHAR* ptr3)
{
     CTlcTransport* pTransport;

     pTransport=tlcAPI->transGetFirst();
     while (pTransport != NULL) {
          pTransport->SendAll(pszUseridFrom,pszUseridTo,pMsg,
                              fType,NULL,iMsgNum,ptr1,ptr2,ptr3);
          pTransport=tlcAPI->transGetNext();
     }
}


LPUSRSTRUCT EXPORT
tlcChannelGetUser(
const CHAR* channel,
const CHAR* userid)
{
     return(tlcAPI->chanFindUser(channel,userid));
}

LPCHANINFO
tlcChannelSetContext(
const CHAR* channel)
{
     curChannel=tlcAPI->chanGetByName(channel);
     return(tlcChannelGetContext());
}

LPCHANINFO
tlcChannelGetContext()
{
     if (curChannel != NULL) {
          return(curChannel->GetConfig());
     }
     return(NULL);
}

/***************************************************************************
 *   Action API functions                                                  *
 ***************************************************************************/

VOID EXPORT
actListCreate(
LPACTLST liststr)
{
     tlcAPI->actCreate(liststr);
}

VOID EXPORT
actListDelete(
const CHAR* listname)
{
     tlcAPI->actRemove(listname);
}

CHAR* EXPORT
actListGetFirst(VOID)
{
     CTlcAList* pList;

     pList=tlcAPI->actGetFirst();
     if (pList != NULL && !pList->m_delTag) {
          return(pList->m_name);
     }
     return(NULL);
}

CHAR* EXPORT
actListGetNext(VOID)
{
     CTlcAList* pList;

     pList=tlcAPI->actGetNext();
     if (pList != NULL && !pList->m_delTag) {
          return(pList->m_name);
     }
     return(NULL);
}

CHAR* EXPORT
actListGetCurrent(VOID)
{

     if (tmpAList != NULL && !tmpAList->m_delTag) {
          return((CHAR*)(tmpAList->GetName()));
     }
     return(NULL);
}

VOID EXPORT
actListResetCurrent(VOID)
{
     tmpAList=NULL;
}


LPACTLST EXPORT
actListGetConfig(
const CHAR* list)
{
     CTlcAList* pList;

     pList=tlcAPI->actGetByName(list);
     if (pList == NULL) {
          return(NULL);
     }
     return(pList->GetConfigPtr());
}

GBOOL EXPORT
actListSetConfig(
const CHAR* list,
LPACTLST config)
{
     CTlcAList* pList;

     pList=tlcAPI->actGetByName(list);
     if (pList == NULL) {
          return(FALSE);
     }
     pList->SetConfig(config);
     return(TRUE);
}

GBOOL EXPORT
actListIsDeleted(
const CHAR* list)
{
     CTlcAList* pList;

     pList=tlcAPI->actGetByName(list);
     if (pList == NULL) {
          return(TRUE);
     }
     return(pList->IsDeleted());
}


const CHAR* EXPORT
actWordGetFirst(
const CHAR* list)
{
     CTlcAList* pList;

     pList=tlcAPI->actGetByName(list);
     if (pList == NULL) {
          return(NULL);
     }
     return(pList->wordGetFirst());
}

const CHAR* EXPORT
actWordGetNext(
const CHAR* list)
{
     CTlcAList* pList;

     pList=tlcAPI->actGetByName(list);
     if (pList == NULL) {
          return(NULL);
     }
     return(pList->wordGetNext());
}

GBOOL EXPORT
actWordExists(
const CHAR* list,
const CHAR* word)
{
     CTlcAList* pList;

     pList=tlcAPI->actGetByName(list);
     if (pList == NULL) {
          return(NULL);
     }
     return(pList->wordExists(word));
}

LPACTION EXPORT
actWordGetGT(
const CHAR* list,
const CHAR* word)
{
     CTlcAList* pList;

     pList=tlcAPI->actGetByName(list);
     if (pList == NULL) {
          return(NULL);
     }
     if (pList->wordGetGT(word)) {
          return(pList->actionGetCurrentPtr());
     }
     return(NULL);
}

LPACTION EXPORT
actWordInfoGetCurrent(
const CHAR* list)
{
     CTlcAList* pList;

     pList=tlcAPI->actGetByName(list);
     if (pList == NULL) {
          return(NULL);
     }
     return(pList->actionGetCurrentPtr());
}

const CHAR* EXPORT
actGetLastDirected(VOID)
{
     return(actTmpTo);
}

GBOOL
actIsSecret(VOID)
{
    return(actSecret);
}

GBOOL
actIsFile(VOID)
{
    return(actHasFile);
}




/***************************************************************************
 *   Transport functions                                                   *
 ***************************************************************************/

INT EXPORT
tlcTransRegister(
const CHAR* name,
LPTFUNCPTRS funcptr)
{
     CDynamicTransport* trans;

     if (funcptr == NULL) {
          trans=new CDynamicTransport;
     }
     else {
          trans=new CDynamicTransport(funcptr);
          trans->m_fFlags=funcptr->flags;
     }
     return(tlcAPI->transRegister(name,trans));
}

INT EXPORT
tlcTransGetNumber(VOID)
{
     return(tlcAPI->transGetNumber());
}

LPUSRSTRUCT EXPORT
tlcTransGetFirstUser(
INT idx,
const CHAR* channel)
{
     CTlcTransport* pTrans;
     CTlcChannel* pChannel=NULL;

     pTrans=tlcAPI->transGetAt(idx);
     if (pTrans != NULL) {
          if (channel != NULL) {
               pChannel=tlcAPI->chanGetByName(channel);
          }
          return(pTrans->GetFirstUser(pChannel));
     }
     return(NULL);
}

LPUSRSTRUCT EXPORT
tlcTransGetNextUser(
INT idx,
const CHAR* channel)
{
     CTlcTransport* pTrans;
     CTlcChannel* pChannel=NULL;

     pTrans=tlcAPI->transGetAt(idx);
     if (pTrans != NULL) {
          if (channel != NULL) {
               VOID* SavePos=tlcAPI->chanGetPos();
               pChannel=tlcAPI->chanGetByName(channel);
               tlcAPI->chanSetPos(SavePos);
          }
          return(pTrans->GetNextUser(pChannel));
     }
     return(NULL);
}

GBOOL EXPORT
tlcTransAddUser(
INT idx,
LPUSRSTRUCT stUsr)
{
     if (stUsr != NULL) {
          CTlcUser* pUser;
          CHAR* channel=stUsr->m_pszChannel;
          if ((pUser=tlcAPI->chanFindUser(channel,stUsr->m_pszName)) != NULL) {
               CTlcTransport* pTransport;
               if ((pTransport=tlcAPI->transGetAt(idx)) != NULL) {
                    pUser->SetTransport(pTransport);
                    pTransport->AddUser(pUser);
                    return(TRUE);
               }
          }
     }
     return(FALSE);
}

GBOOL EXPORT
tlcTransRemoveUser(
INT idx,
LPUSRSTRUCT stUsr)
{
     if (stUsr != NULL) {
          CTlcUser* pUser;
          CHAR* channel=stUsr->m_pszChannel;
          if ((pUser=tlcAPI->chanFindUser(channel,stUsr->m_pszName)) != NULL) {
               CTlcTransport* pTransport;
               if ((pTransport=tlcAPI->transGetAt(idx)) != NULL) {
                    pTransport->RemoveUser(pUser);
                    return(TRUE);
               }
          }
     }
     return(FALSE);
}

GBOOL EXPORT
tlcTransOutput(
INT idx,
LPUSRSTRUCT stUsr)
{
     if (stUsr != NULL) {
          CTlcUser* pUser;
          CHAR* channel=stUsr->m_pszChannel;
          if ((pUser=tlcAPI->chanFindUser(channel,stUsr->m_pszName)) != NULL) {
               CTlcTransport* pTransport;
               if ((pTransport=tlcAPI->transGetAt(idx)) != NULL) {
                    pTransport->Output(pUser);
                    return(TRUE);
               }
          }
     }
     return(FALSE);
}

GBOOL EXPORT
tlcTransSendAll(
INT idx,
const CHAR* pszUseridFrom,
const CHAR* pszUseridTo,
const CHAR* pMsg,
SHORT fType,
const CHAR* channel,
SHORT iMsgNum,
const CHAR* ptr1,
const CHAR* ptr2,
const CHAR* ptr3)
{
    return( tlcTransSendAllKey(idx, pszUseridFrom, pszUseridTo,
                                    pMsg, fType, channel, iMsgNum,
                                    ptr1, ptr2, ptr3, NULL)         );
}

GBOOL EXPORT
tlcTransSendAllKey(
INT idx,
const CHAR* pszUseridFrom,
const CHAR* pszUseridTo,
const CHAR* pMsg,
SHORT fType,
const CHAR* channel,
SHORT iMsgNum,
const CHAR* ptr1,
const CHAR* ptr2,
const CHAR* ptr3,
const CHAR* key)
{
     CTlcTransport* pTransport;
     CTlcChannel* pChannel;
     if (channel == NULL || (pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(FALSE);
     }
     if ((pTransport=tlcAPI->transGetAt(idx)) != NULL) {
          pTransport->SendAllKey(pszUseridFrom,pszUseridTo,pMsg,fType,pChannel,
                              iMsgNum,ptr1,ptr2,ptr3,key);
          return(TRUE);
     }
     return(FALSE);
}



GBOOL EXPORT
tlcTransSendAllBut(
INT idx,
const CHAR* pszUseridFrom,
const CHAR* pszUseridTo,
const CHAR* pMsg,
SHORT fType,
const CHAR* channel,
SHORT iMsgNum,
const CHAR* ptr1,
const CHAR* ptr2,
const CHAR* ptr3,
const CHAR* pszUseridNot1,
const CHAR* pszUseridNot2)
{
     CTlcTransport* pTransport;
     CTlcChannel* pChannel;
     if (channel == NULL || (pChannel=tlcAPI->chanGetByName(channel)) == NULL) {
          return(FALSE);
     }
     if ((pTransport=tlcAPI->transGetAt(idx)) != NULL) {
          pTransport->SendAllBut(pszUseridFrom,pszUseridTo,pMsg,fType,pChannel,
                              iMsgNum,ptr1,ptr2,ptr3,pszUseridNot1,pszUseridNot2);
          return(TRUE);
     }
     return(FALSE);
}

GBOOL EXPORT
tlcTransCmdResult(
INT idx,
LPUSRSTRUCT stUsr,
SHORT iOperation,
GBOOL bSuccess,
SHORT iReason)
{
     if (stUsr != NULL) {
          CTlcUser* pUser;
          CHAR* channel=stUsr->m_pszChannel;
          if ((pUser=tlcAPI->chanFindUser(channel,stUsr->m_pszName)) != NULL) {
               CTlcTransport* pTransport;
               if ((pTransport=tlcAPI->transGetAt(idx)) != NULL) {
                    setmbk(msgTlc);
                    pTransport->CmdResult(pUser,iOperation,bSuccess,iReason);
                    rstmbk();
                    return(TRUE);
               }
          }
     }
     return(FALSE);
}

INT EXPORT
tlcTransUserIs(
const CHAR* userid)
{
     CTlcUser* pUser;
     CTlcTransport* pTransport;
     INT cnt=0;
     GBOOL found=FALSE;

     pUser=tlcAPI->usrGetByName(userid);
     if (pUser == NULL) {
          return(0);
     }
     pTransport=tlcAPI->transGetFirst();
     do {
          if (pTransport == pUser->GetTransport()) {
               found=TRUE;
               break;
          }
          cnt++;
          pTransport=tlcAPI->transGetNext();
     } while (pTransport != NULL);

     return(found == TRUE ? cnt : 0);
}

/***************************************************************************
 *   Comamnd functions                                                *
 ***************************************************************************/

GBOOL
tlcCommandRegister(
LPCMDSTRUCT st)
{
     GBOOL success;

     ASSERT(st != NULL);
     CDynamicCommand* newCmd = new CDynamicCommand(st);
     success=tlcAPI->cmdRegister(newCmd);
     if (!success) {
          delete newCmd;
     }
     return(success);
}

SHORT
tlcCommandIssue(
const CHAR* cmdName,
VOID* param)
{
     ASSERT(cmdName != NULL);

     CTlcCommand* pCmd=tlcAPI->cmdGetFirst();
     while (pCmd != NULL) {
          if (sameas(pCmd->m_pszCmd,cmdName)
           || sameas(pCmd->m_pszAbbr,cmdName)) {
               return(pCmd->DoCmd(static_cast<LPCMDPARAM>(param)));
          }
          pCmd=tlcAPI->cmdGetNext();
     }
     return(0);
}

/***************************************************************************
 *   Misc utility functions                                                *
 ***************************************************************************/

CHAR* EXPORT
tlcPrivateFromUser(
const CHAR* userid)
{
     static CHAR str[TLCUIDSIZ+2];

     memset(str,0,TLCUIDSIZ+2);
     strcpy(str,userid);
     strcat(str,"'s");
     return(str);
}

VOID EXPORT
tlcSetDefaultChannel(
const CHAR* channel)
{
      stlcpy(dftchan,channel,CHAN_MAX_SIZE);
}

CHAR*
tlcGetDefaultChannel(VOID)
{
      static CHAR channel[CHAN_MAX_SIZE];

      stlcpy(channel,dftchan,CHAN_MAX_SIZE);
      return(channel);
}

VOID EXPORT
tlcOutputFinished(VOID)
{
     tlcAPI->OutputFinished();
}



