// tDialString.h: CtDialString declaration

#ifndef TDIALSTRING_H
#define TDIALSTRING_H

//#include "tWave.h"  // CtWave
#include "tDtmf.h"  // CtDtmf
#include "Timer.h"  // Timer
#include "tstring.h" // tstring (string or wstring)

using namespace std;

struct CtDialStringSink
{
    virtual void OnDialDone() {}
    virtual void OnDialError() {}
};

class CtDialString : private CtWaveSink,
                     private TimerSink
{
public:
    CtDialString(CtDialStringSink* pSink = 0, const TCHAR* pszDigits = 0);
    ~CtDialString();

    CtDialString& operator=(const TCHAR* pszDigits);
    operator const TCHAR*();

    // The Stuff
    bool Dial(UINT nWaveOut, UINT nDigitDuration, UINT nCommaDelay);
    void Cancel();

private:
    enum { INTERDIGIT_DELAY = 50 }; // Silence between digits

    enum DialState
    {
        dsStopped,
        dsPausing,
        dsPlaying,
    };

    size_t              m_nIndex;
    tstring             m_sDigits;
    CtDtmf              m_dtmf;
    UINT                m_nDigitDuration;
    UINT                m_nCommaDelay;
    UINT                m_nWaveOut;
    Timer               m_timer;
    CtDialStringSink*   m_pSink;
    DialState           m_state;

    // Play a digit
    bool PlayDigit();

    // Handle timer messages
    virtual void OnTimer();

    // Handle wave events
    virtual void OnWaveOutOpen();
    virtual void OnWaveOutDone();
};

// Inline implementations

#pragma warning(disable:4355)   // 'this' : used in base member initializer list

inline
CtDialString::CtDialString(CtDialStringSink* pSink, const TCHAR* pszDigits)
    :
    m_sDigits(pszDigits ? pszDigits : ""),
    m_dtmf(this),
    m_timer(this),
    m_nIndex(0),
    m_pSink(pSink),
    m_state(dsStopped)
{}

inline
CtDialString::~CtDialString()
{ Cancel(); }

inline
CtDialString& CtDialString::operator=(const TCHAR* pszDigits)
{
    m_sDigits = (pszDigits ? pszDigits : "");
    return *this;
}

inline
CtDialString::operator const TCHAR*()
{
    return m_sDigits.c_str();
}

#endif  // TDIALSTRING_H
