#ifndef _apl_containers_dlistapi_h_
#define _apl_containers_dlistapi_h_
/*----------------------------------------------------------------------------
** SUMMARY: Intrusive Double Linked List (IDLIST)
**
** DESCRIPTION:
**  This file provides a TYPELESS (i.e. NOT type-safe) interface for
**  a double-linked list of data structures.  All items contained in the
**  list must be of "type" ILNODE.  See apl/containers/nodeapi.h for details.
**
**  MEMORY:
**  -------
**  The list mechanism is "intrusive", which means that the items being
**  queued/contained must have foreknowledge of the fact there are going
**  to be a list.  This is because the items provide the memory for the
**  list's link field(s).  This is somewhat cumbersome, BUT its advantage is 
**  that NO dynamic memory allocation is needed/used by the list.
**
**
** CONFIGURATION 
** -------------
**  COMPILE:     none.
**
**  APPLICATION: none.
**
**  PLATFORM:    none.
**
**
**  NOTES:
**  1. For efficency/optimization some methods are 'inlined'.  The inlining
**     is done by using the preprocessor/macros.  The application should
**     treat all methods as function calls and not rely on the fact they may
**     be currently defined as macros.
----------------------------------------------------------------------------*/

#include "apl/types/types.h"        /* For: basic types */

#ifdef __cplusplus
extern "C" {
#endif


/*-------------- TYPES -----------------------------------------------------*/
/** List structure */
typedef struct AplDlist_tag
    {
    void* _head;
    void* _tail;
    } AplDList;

/** Handle to a Single-Linked List */
#define AplDListHdl                         AplDList*


/*-------------- INLINE IMPLEMENTATION -------------------------------------*/
#include "apl/containers/dlist.h"           /* For: inline implementation */


/*-------------- PUBLIC/PUBLISHED API --------------------------------------*/
/** This method initializes the list.  This method must be called BEFORE
    any other operation are called on the list. The application must provide 
    an actual List INSTANCE (i.e. a reference to actual memory) to the list  
    being initialized.

    Prototype:
        void Apl_dlistInitialize( AplDList* listToInitialize );
 */
#define Apl_dlistInitialize                 _Apl_dlistInitialize

/** This method moves the entire content of the source-list to the
    the destination list. The source-list will be empty after this 
    operation.  Any previous contents of the destination-list are
    lost.

    Prototype:
        void Apl_dlistMove( AplDListHdl src, AplDListHdl dst );
 */
#define Apl_dlistMove                       _Apl_dlistMove

/** This method empties the list.  All references to the item(s) in the
    list are lost.

    Prototype:
        void Apl_dlistClear( AplDListHdl list );
 */
#define Apl_dlistClear                      _Apl_dlistClear


/*-------------- PUBLIC/PUBLISHED API --------------------------------------*/
/*
** The following methods "view" the list a FIFO.
*/

/** This method removes the first item in the FIFO.  Returns 0 if the FIFO
    is empty.

    Prototype
        void* Apl_dlistGet( AplDListHdl fifo );
     */
#define Apl_dlistGet                        _Apl_dlistGet

/** This methods adds the item as the last item in the FIFO
    
    Prototype:
        void Apl_dlistPut( AplSlistHdl fifo, void* newitem );
 */
#define Apl_dlistPut                        _Apl_dlistPut 
	
/** This method returns a pointer to the first item in the FIFO. The returned 
    item remains in the FIFO.  Returns 0 if the FIFO is empty.

    Prototype:
        void* Apl_dlistHead( AplDListHdl fifo );
 */
#define Apl_dlistHead                       _Apl_dlistHead

/** This method returns a pointer to the last item in the FIFO. The returned 
    item remains in the FIFO.  Returns 0 if the FIFO is empty.

    Prototype:
        void* Apl_dlistTail( AplDListHdl fifo );
 */
#define Apl_dlistTail                       _Apl_dlistTail


/*-------------- PUBLIC/PUBLISHED API --------------------------------------*/
/*
** The following methods "view" the list a Stack
*/

/** This method removes the top element from stack and return a pointer to
    it as a result. Returns 0, if the stack is empty.

    Prototype:
        void* Apl_dlistPop( AplDListHdl stack );
 */
#define Apl_dlistPop                        _Apl_dlistPop

/** This method adds the item to top of the stack.

    Prototype:
        void Apl_dlistPush( AplDListHdl stack, void* itemToPush );    
 */
#define Apl_dlistPush                       _Apl_dlistPush

/** This method returns a pointer to the top item in the stack. The returned 
    item remains in the queue.  Returns 0 if the stack is empty.

    Prototype:
        void* Apl_dlistTop( AplDListHdl stack );
 */
#define Apl_dlistTop                        _Apl_dlistTop


/*-------------- PUBLIC/PUBLISHED API --------------------------------------*/
/*
** The following methods "view" the list an Ordered List.
*/

/** This method removes the first item in the list.  Returns 0 if the list
    is empty.

    Prototype:
        void* Apl_dlistGetFirst( AplDListHdl list );
 */
#define Apl_dlistGetFirst                   _Apl_dlistGetFirst 

/** This method removes the last item in the list.  Returns 0 if the list
    is empty.

    Prototype:
        void* Apl_dlistGetLast( AplDListHdl list );
 */
#define Apl_dlistGetLast                    _Apl_dlistGetLast

/** This method adds the item as the first item in the list.

    Prototype:
        void Apl_dlistPutFirst( AplDListHdl list, void* itemToAdd );
 */
#define Apl_dlistPutFirst                   _Apl_dlistPutFirst
	
/** This method adds the item as the last item in the list.
    Prototype:
        void Apl_dlistPutLast( AplDListHdl list, void* itemToAdd );
 */
#define Apl_dlistPutLast                    _Apl_dlistPutLast
	
/** This method removes specified element from the list. Assumes that the 
    item is actually in the LIST!

    Prototype:
        void Apl_dlistRemove( AplDListHdl list, void* itemToRemove );
 */
#define Apl_dlistRemove                     _Apl_dlistRemove

/** This method inserts the specified item into the list behind the 'after' 
    element.  If 'after' is 0, then the item is added to the head of the 
    list. It is ASSUMED that the 'after' element is in the list if it is 
    not 0.

    Prototype:
        void Apl_dlistInsertAfter( AplDListHdl list, void* itemToAdd, void* afterItem );
 */
#define Apl_dlistInsertAfter                _Apl_dlistInsertAfter

/** This method inserts the specified item into the list ahead the 'before' 
    element.  If 'before' is 0, then the item is added to the tail of the 
    list. It is ASSUMED that the 'before' element is in the list if it is 
    not 0.

    Prototype:
        void Apl_dlistInsertBefore( AplDListHdl list, void* itemToAdd, void* beforeItem );
 */
#define Apl_dlistInsertBefore               _Apl_dlistInsertBefore

/** This method returns non-zero (true) of the specified item is already in
    the list, else 0 (false) is returend.

    Prototype:
        AplBool Apl_dlistFind( AplDListHdl list, void* itemToSearchFor );
 */
#define Apl_dlistFind                       _Apl_dlistFind

/** This method returns a pointer to the first item in the list. The returned 
    item remains in the list.  Returns 0 if the list is empty.

    Prototype:
        void* Apl_dlistFirst( AplDListHdl list );
 */
#define Apl_dlistFirst                      _Apl_dlistFirst 

/** This method returns a pointer to the last item in the list. The returned 
    item remains in the list.  Returns 0 if the list is empty.

    Prototype:
        void* Apl_dlistLast( AplDListHdl list );
 */
#define Apl_dlistLast                       _Apl_dlistLast

/** This method returns a pointer to the item after 'currentItem' Both 
    items remain in the list.  Returns 0 when the end-of-list is reached.
    This method is used to traverse/walk the list.

    Prototype:
        void* Apl_dlistNext( void* currentItem );
 */
#define Apl_dlistNext                       _Apl_dlistNext 

/** This method returns a pointer to the item before 'currentItem'. Both 
    items remain in the list.  Returns 0 when the head-of-list is reached.
    This method is used to traverse/walk the list.

    Prototype:
        void* Apl_dlistPrevious( void* currentItem );
 */
#define Apl_dlistPrevious                   _Apl_dlistPrevious



#ifdef __cplusplus
}
#endif
/*--------------------------------------------------------------------------*/
#endif  /* end _apl_containers_dlistapi_h_ */

