// This code is a part of the Telephony Framework C++ Library.
// Copyright (C) 1997 Chris Sells. All rights reserved.
// tRequestList.cpp: CtRequestList class implementation

#include "stdafx.h"
#include "tRequestList.h"
#include "tRepTarg.h"

CtRequestList::~CtRequestList()
{
    RemoveAllRequests();
}

void CtRequestList::AddRequest(
    TREQUEST        nRequestID,
    CtReplyTarget*  pTarget,
    DWORD           nRequestType)
{
    m_listRequests.AddTail(new AsyncRequest(nRequestID, pTarget, nRequestType));
}

BOOL CtRequestList::IsRequestPending(
    TREQUEST    nRequestID,           // = 0
    DWORD*      pnRequestType) const  // = 0
{
    // Are we looking for a specific request?
    if( nRequestID )
    {
        AsyncRequest*   par;
        if( FindRequest(nRequestID, &par, 0) )
        {
            if( pnRequestType )
            {
                *pnRequestType = par->nType;
            }
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
    // Are we looking for just any request?
    else
    {
        // Assume 0 is UNKNOWN
        if( pnRequestType ) *pnRequestType = 0;

        return (m_listRequests.IsEmpty() ? FALSE : TRUE);
    }
}

BOOL CtRequestList::IsRequestTypePending(
    DWORD                   nRequestType,
    const CtReplyTarget*    pTarget) const  // = 0
{
    AsyncRequest*   par;
    POSITION        pos = m_listRequests.GetHeadPosition();
    while( pos &&
           (par = (AsyncRequest*)m_listRequests.GetNext(pos)) )
    {
        if( par->nType == nRequestType &&
            (!pTarget || pTarget == par->pTarget) )
        {
            return TRUE;
        }
    }

    return FALSE;
}

BOOL CtRequestList::FindRequest(
    TREQUEST        nRequestID,
    AsyncRequest**  ppar,       // = 0
    POSITION*       ppos) const // = 0
{
    AsyncRequest*   par;
    POSITION        posOld;
    POSITION        pos = m_listRequests.GetHeadPosition();
    while( (posOld = pos) &&
           (par = (AsyncRequest*)m_listRequests.GetNext(pos)) )
    {
        if( par->nID == nRequestID )
        {
            if( ppar )
            {
                *ppar = par;
            }

            if( ppos )
            {
                *ppos = posOld;
            }

            return TRUE;
        }
    }

    return FALSE;
}

BOOL CtRequestList::RemoveRequest(
    TREQUEST        nRequestID,
    CtReplyTarget** ppTarget,       // = 0
    DWORD*          pnRequestType)  // = 0
{
    POSITION        pos;
    AsyncRequest*   par;

    if( FindRequest(nRequestID, &par, &pos) )
    {
        if( ppTarget )
        {
            *ppTarget = par->pTarget;
        }

        if( pnRequestType )
        {
            *pnRequestType = par->nType;
        }

        delete par;
        m_listRequests.RemoveAt(pos);

        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

void CtRequestList::RemoveAllRequests(
    CtReplyTarget*  pTarget)    // = 0
{
    // Walk list, remove pending requests
    // for the requested reply target or all reply targets
    AsyncRequest*   par;
    POSITION        posOld;
    POSITION        pos = m_listRequests.GetHeadPosition();
    while( (posOld = pos) &&
           (par = (AsyncRequest*)m_listRequests.GetNext(pos)) )
    {
        if( !pTarget || pTarget == par->pTarget )
        {
            m_listRequests.RemoveAt(posOld);
            delete par;
        }
    }
}

