// This code is a part of the Telephony Framework C++ Library.
// Copyright (C) 1997 Chris Sells. All rights reserved.
// tCall.h: CtCall class interface

#ifndef TCALL_H
#define TCALL_H

#include "tRepTarg.h"   // CtReplyTarget
#include "tCallSink.h"  // CtCallSink
#include "tLine.h"      // CtLine
#include "TFXSTL.h"

/////////////////////////////////////////////////////////////////////////////
// Call Requests

// NOTE: Change the CtCall::OnReplay() implementation when adding values here
// CALLREQUEST_UNKNOWN == ADDRREQUEST_UNKNOWN == LINEREQUEST_UNKNOWN
#define CALLREQUEST_UNKNOWN         0
#define CALLREQUEST_ACCEPT          1
#define CALLREQUEST_ANSWER          2
#define CALLREQUEST_DIAL            3
#define CALLREQUEST_DROP            4
#define CALLREQUEST_GENERATEDIGITS  5
#define CALLREQUEST_MAKECALL        6

class CtCall : public CtReplyTarget
{
public:
    // Operations
    CtCall(CtLine* pLine);
    CtCall(CtLine* pLine, HCALL hCall, CtCallSink* pInitialSink = 0);
    virtual ~CtCall();

    CtLine* GetLine() const;
    HCALL   GetHandle() const;
    HCALL   Attach(HCALL hCall, CtCallSink* pInitialSink = 0);
    HCALL   Detach();

    // Can have multiple sinks per object and they stay around for the
    // life of the object (which may be different than the life of the handle).
    void    AddSink(CtCallSink* pSink);
    void    RemoveSink(CtCallSink* pSink);

    BOOL    IsRequestPending(TREQUEST nRequestID = 0,
                             DWORD* pnRequestType = 0) const;
    BOOL    IsRequestTypePending(DWORD nRequestType) const;

    static CtCall*  FromHandle(HCALL hCall);

    // TAPI wrappers
    tfxasync TRESULT    Accept(LPCSTR psUserUserInfo = 0, DWORD nSize = 0);
    tfxasync TRESULT    Answer(LPCSTR psUserUserInfo = 0, DWORD nSize = 0);
    tfxasync TRESULT    Dial(LPCSTR szDestAddress, DWORD dwCountryCode = 0);
    tfxasync TRESULT    Drop(LPCSTR psUserUserInfo = 0, DWORD nSize = 0);
    tfxasync TRESULT    GenerateDigits(LPCSTR szDigits, DWORD nDuration = 0,
                                       DWORD nDigitMode = LINEDIGITMODE_DTMF);

    TRESULT GenerateTone(DWORD nToneMode, DWORD nDuration,
                         DWORD nCustomTones = 0, LINEGENERATETONE* pCustomTones = 0);
    TRESULT Deallocate();

    TRESULT GatherDigits(LPSTR pszDigits, DWORD nDigits,
                         LPCSTR pszTerminationDigits = 0,
                         DWORD nFirstDigitTimeout = 5000,
                         DWORD nInterDigitTimeout = 5000,
                         DWORD nDigitModes = LINEDIGITMODE_DTMF);
                                     
    TRESULT Handoff(LPCSTR szFileName);
    TRESULT Handoff(DWORD nMediaMode);

    tfxasync TRESULT    MakeCall(LPCSTR szDestAddress = 0, DWORD nCountryCode = 0,
                                 CtCallSink* pInitialSink = 0, LINECALLPARAMS* pCallParams = 0);
    
    TRESULT MonitorDigits(DWORD dwDigitModes = LINEDIGITMODE_DTMF);

    // Call Events
    void    OnInfo(DWORD nCallInfo);
    void    OnState(DWORD nCallState, DWORD dwParam2, DWORD nCallPriviledge);
    void    OnGatherDigits(DWORD nGatherTerm);
    void    OnGenerate(DWORD nGenerateTerm);
    void    OnMonitorDigits(char cDigit, DWORD nDigitMode);
    void    OnMonitorMedia(DWORD nMediaMode);
    void    OnMonitorTone(DWORD dwAppSpecific);

    // CtReplyTarget event
    void    OnReply(TREQUEST nRequestID, TRESULT nResult, DWORD nRequestType);

protected:
    static void AddToCalls(CtCall* pCall);
    static void RemoveFromCalls(CtCall* pCall);

private:
    static CPointerList s_listCalls;

    HCALL       m_hCall;
    CtLine*     m_pLine;

    // Use an array instead of a list to allow
    // removing sinks during event handling
    CPointerArray   m_rgSinks; 
};

#endif  // TCALL_H