
/*
 * linklist.h:
 *      header file for linklist.c.
 *
 *      This file is new with V0.81 and contains all the
 *      declarations with respect to linked lists that
 *      used to be in helpers.h.
 *
 *      Copyright (C) 1997-99 Ulrich M”ller.
 *      This file is part of the XFolder source package.
 *      XFolder is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published
 *      by the Free Software Foundation, in version 2 as it comes in the
 *      "COPYING" file of the XFolder main distribution.
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 */

#if __cplusplus
extern "C" {
#endif

#ifndef LINKLIST_HEADER_INCLUDED
    #define LINKLIST_HEADER_INCLUDED

    #ifndef OS2_INCLUDED
        typedef unsigned long BOOL;
        #define TRUE (BOOL)1
        #define FALSE (BOOL)0
    #endif

    typedef struct LIST_STRUCT {
        struct LIST_STRUCT   *pNext, *pPrevious;
        unsigned long        ulSize;
    } LISTITEM, *PLISTITEM;

    typedef signed short (FNSORTLIST)(void*, void*, void*);
    typedef FNSORTLIST *PFNSORTLIST;

    /*
     * lstAppendItem:
     *      this will create an item for a linked list starting at
     *      *ppFirst; this must be a pointer to a pointer to the
     *      first list item; if *ppFirst is NULL (= list is empty),
     *      *ppFirst will be adjusted so that it points to the new
     *      item. If ppLast == NULL, the list is assumed to be
     *      a "one-way" list, otherwise it must point to a pointer
     *      for the last list item, which will be adjusted.
     *      This function returns the address of the new list item.
     */

    PLISTITEM lstAppendItem(PLISTITEM *ppFirst, // first list item
                PLISTITEM *ppLast,              // last list item (or NULL)
                PLISTITEM pNewItem);            // item to insert

    /*
     * lstInsertItemAt:
     *      does just the same, but does not append the new item
     *      at the end of the list, but BEFORE the specified index
     *      lIndex. If lIndex is larger than the number of items
     *      on the list or == -1, the new item will be appended.
     */

    PLISTITEM lstInsertItemAt(PLISTITEM *ppFirst, // first list item
                PLISTITEM *ppLast,              // last list item (or NULL)
                PLISTITEM pNewItem,             // item to insert
                long lIndex);                   // insert at (>= 0)

    /*
     * lstRemoveItem:
     *      reversely, this will remove a given pRemoveItem from
     *      the linked list beginning at *ppFirst. Returns TRUE if
     *      successful, FALSE if pRemoveItem was not found.
     */

    BOOL lstRemoveItem(PLISTITEM *ppFirst,      // first list item
                PLISTITEM *ppLast,              // last list item (or NULL)
                PLISTITEM pRemoveItem);         // item to remove

    /*
     * lstSwapItems:
     *      this will swap the items ppItem1 and ppItem2 in the linked
     *      list starting at *ppFirst; useful for sorting.
     *      Note that this function will not only adjust the pNext
     *      and pPrevious pointers of the LISTITEMs, but also
     *      swap the *ppItem1 and *ppItem2 pointers.
     */

    BOOL lstSwapItems(PLISTITEM *ppFirst,       // first list item
                PLISTITEM *ppLast,              // last list item (or NULL)
                PLISTITEM *ppItem1, PLISTITEM *ppItem2);// items to swap

    /*
     * lstQuickSort:
     *      this will sort the list starting at *ppFirst using the
     *      sort function pfnSort, which works similar to those of the
     *      container sorts, i.e. it must be declared as a
     *          SHORT EXPENTRY fnSort(PVOID pItem1, PVOID pItem1, PVOID pStorage)
     *      These sort functions need to return the following:
     *          0   pItem1 == pItem2
     *         -1   pItem1 <  pItem2
     *         +1   pItem1 >  pItem2
     *      This function uses the "quick sort" algorithm, which is one of
     *      the fastest sort algorithms available. However, this is an
     *      "instable" sort algorithm, meaning that list items considered
     *      equal by pfnSort do _not_ retain their position, but might be
     *      changed. If you need these to remain where they are, use
     *      lstBubbleSort.
     */

    BOOL lstQuickSort(PLISTITEM *ppFirst,       // first list item
                PLISTITEM *ppLast,              // last list item (or NULL)
                PFNSORTLIST pfnSort,            // comparison func
                void* pStorage);                // param for comp. func

    /*
     * lstBubbleSort:
     *      this will sort the list starting at *ppFirst using the
     *      sort function pfnSort, which works similar to those of the
     *      container sorts, i.e. it must be declared as a
     *          SHORT EXPENTRY fnSort(PVOID pItem1, PVOID pItem1, PVOID pStorage)
     *      These sort functions need to return the following:
     *          0   pItem1 == pItem2
     *         -1   pItem1 <  pItem2
     *         +1   pItem1 >  pItem2
     *      This function uses the "bubble sort" algorithm, which will cause a
     *      lot of calls to pfnSort and which is really ineffective for lists
     *      with more than 100 items.
     */

    BOOL lstBubbleSort(PLISTITEM *ppFirst,      // first list item
                PLISTITEM *ppLast,              // last list item (or NULL)
                PFNSORTLIST pfnSort,            // comparison func
                void* pStorage);                // param for comp. func

    /*
     * lstCountItems:
     *      this will count the number of items from pFirst;
     *      returns 0 if error occured.
     */

    unsigned long lstCountItems(PLISTITEM pFirst);

    /*
     * lstItemFromIndex:
     *      returns the list item with a given ulIndex
     *      (counting from 0), or NULL if ulIndex is too large
     */

    PLISTITEM lstItemFromIndex(PLISTITEM pFirst,
                unsigned long ulIndex);                 // item to find (>= 0)

    /*
     * lstClear:
     *      this will free the whole list starting
     *      at *ppFirst and set *ppFirst/*ppLast to NULL
     */

    void lstClear(PLISTITEM *ppFirst,           // first list item
                PLISTITEM *ppLast);             // last list item (or NULL)

#endif

#if __cplusplus
}
#endif

