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

#ifndef TPHONE_H
#define TPHONE_H

#include "tRepTarg.h"       // CtReplyTarget
#include "tPhoneSink.h"     // CtPhoneSink
#include "tAppSink.h"       // CtAppSink
#include "tRequestList.h"   // CtRequestList
#include "TFXSTL.h"

/////////////////////////////////////////////////////////////////////////////
// Phone Requests

#define PHONEREQUEST_UNKNOWN 0

class CtPhone : public CtReplyTarget
{
public:
    // Operations
    CtPhone();
    virtual ~CtPhone();

    HPHONE  GetHandle() const;
    DWORD   GetDeviceID() const;

    void    AddSink(CtPhoneSink* pSink);
    void    RemoveSink(CtPhoneSink* pSink);

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

    static CtPhone*     FromHandle(HPHONE hPhone);
    static DWORD        GetNumDevs();
    static HPHONEAPP    GetAppHandle();
	static DWORD	    GetAppVersion();
    static void         SetAppVersion(DWORD dwLoVersion, DWORD dwHiVersion);
    static DWORD        GetApiVersion(DWORD nLineID);

    // Static TAPI wrappers
    static TRESULT  Initialize(CtAppSink* pAppSink, LPCSTR szAppName, HINSTANCE hInst);
    static TRESULT  Shutdown();
    static TRESULT  GetIcon(DWORD nPhoneID, LPHICON phicon, LPCSTR pszDeviceClass);

    // TAPI wrappers
    TRESULT Open(DWORD nLineID, CtPhoneSink* pInitialSink = 0,
                 DWORD dwPriviledges = PHONEPRIVILEGE_OWNER);
    TRESULT Close();
    TRESULT SetHookSwitch(DWORD dwHookSwitchDevs, DWORD nHookSwitchMode);

protected:
    // Versions negotiation
    static void NegotiateApiVersions();

    // Phone manager
    static void AddToPhones(CtPhone* pPhone);
    static void RemoveFromPhones(CtPhone* pPhone);

    // Static CtPhone events
    static void OnCreate(DWORD nPhoneID);

    // CtPhone event manager
    virtual void    OnEvent(DWORD hDevice, DWORD nMsg, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3);
    
    // CtPhone events
    void    OnButton(DWORD nButtonOrLampID, DWORD nButtonMode, DWORD nButtonState);
    void    OnClose();
    void    OnDevSpecific(DWORD dwDevice, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3);
    void    OnState(DWORD dwPhoneStates, DWORD dwPhoneStateDetails);

#if (TAPI_CURRENT_VERSION >= 0x00020000)
    void    OnRemove(DWORD dwDeviceID);
#endif

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

    // Telephony event callback
    friend void CALLBACK
    TfxPhoneCallback(DWORD dwDevice, DWORD nMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3);

private:
    static CPointerList     s_listPhones;
    static HPHONEAPP    s_hPhoneApp;
    static DWORD        s_dwLoVersion;
    static DWORD        s_dwHiVersion;
    static DWORD        s_nNumDevs;
    static CtAppSink*   s_pAppSink;
    static DWORD*       s_aApiVersions;

    HPHONE          m_hPhone;
    CPointerArray       m_rgSinks;
    DWORD           m_nPhoneID;
    CtRequestList   m_listRequests;

    // For our own use
    void AddRequest(TREQUEST nRequestID, CtReplyTarget* pTarget,
                    DWORD dwRequestType);
    void RemoveAllRequests(CtReplyTarget* pTarget = 0);

    // Copy constructor and operator= not allowed
private:
    CtPhone(const CtPhone&);
    CtPhone& operator=(const CtPhone&);
};

#endif  // TPHONE_H
