//------------------------------------------------------------------------------
// File: AList.cpp
//
// Desc: DirectShow sample code - implementation of AListItem and AList
//       classes.
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------

#include <windows.h>
#include "alist.h"


LONG AListItem::GetCount(void) const
{
    LONG l;
    const AListItem *li;

    for(l=0,li=this; li!=NULL ; li=li->m_pNext,++l);

    return l;
}

AListItem* AListItem::Cat(AListItem *pItem)
{
    AListItem *li;

    if(this==NULL)
        return pItem;

    for(li=this ; li->m_pNext!=NULL ; li=li->m_pNext);

    li->m_pNext=pItem;
    return this;
}

//////////////////////////////////////////////////////////////////////
// AListItem::Remove

AListItem* AListItem::Remove(AListItem *pItem)
{
    AListItem *li,*prev;

    //treat remove(NULL) same as item not found in list
    if (pItem==NULL) 
        return this;
    if(pItem==this)
        return m_pNext;

    prev=NULL;
    for(li=this; li!=NULL && li!=pItem ; li=li->m_pNext)
        prev=li;

    if(li==NULL)     // item not found in list
        return this;

    //  here it is guaranteed that prev is non-NULL since we checked for
    //  that condition at the very beginning

    prev->SetNext(li->m_pNext);
    li->SetNext(NULL);

    // SetNext on pItem to NULL
    pItem->SetNext(NULL);

    return this;
}

AListItem* AListItem::GetPrev(AListItem *pItem) const
{
    const AListItem *li,*prev;

    prev=NULL;
    for(li=this ; li!=NULL && li!=pItem ; li=li->m_pNext)
        prev=li;

    return (AListItem*)prev;
}

AListItem * AListItem::GetItem(LONG index)
{
    AListItem *scan;
    for (scan = this; scan!=NULL && index; scan = scan->m_pNext) 
        index--;

    return (scan);
}

void AList::InsertBefore(AListItem *pItem,AListItem *pInsert)
{
    AListItem *prev = GetPrev(pItem);
    pInsert->SetNext(pItem);

    if (prev) 
        prev->SetNext(pInsert);
    else 
        m_pHead = pInsert;
}

void AList::AddTail(AListItem *pItem)
{
    if (m_pHead == NULL)
        AddHead(pItem);
    else
        m_pHead = m_pHead->AddTail(pItem);
}

void AList::Reverse()

{
    AList Temp;
    AListItem *pItem;
    while ((pItem = RemoveHead()) != 0)
    {
        Temp.AddHead(pItem);
    }
    Cat(Temp.GetHead());
}

