/****************************************************************************
 *
 * ftlist.h
 *
 *   Generic list support for FreeType (specification).
 *
 * Copyright (C) 1996-2019 by
 * David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * This file is part of the FreeType project, and may only be used,
 * modified, and distributed under the terms of the FreeType project
 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
 * this file you indicate that you have read the license and
 * understand and accept it fully.
 *
 */


  /**************************************************************************
   *
   * This file implements functions relative to list processing.  Its data
   * structures are defined in `freetype.h`.
   *
   */


#ifndef FTLIST_H_
#define FTLIST_H_


#include <ft2build.h>
#include FT_FREETYPE_H

#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif


FT_BEGIN_HEADER


  /**************************************************************************
   *
   * @section:
   *   list_processing
   *
   * @title:
   *   List Processing
   *
   * @abstract:
   *   Simple management of lists.
   *
   * @description:
   *   This section contains various definitions related to list processing
   *   using doubly-linked nodes.
   *
   * @order:
   *   FT_List
   *   FT_ListNode
   *   FT_ListRec
   *   FT_ListNodeRec
   *
   *   FT_List_Add
   *   FT_List_Insert
   *   FT_List_Find
   *   FT_List_Remove
   *   FT_List_Up
   *   FT_List_Iterate
   *   FT_List_Iterator
   *   FT_List_Finalize
   *   FT_List_Destructor
   *
   */


  /**************************************************************************
   *
   * @function:
   *   FT_List_Find
   *
   * @description:
   *   Find the list node for a given listed object.
   *
   * @input:
   *   list ::
   *     A pointer to the parent list.
   *   data ::
   *     The address of the listed object.
   *
   * @return:
   *   List node.  `NULL` if it wasn't found.
   */
  FT_EXPORT( FT_ListNode )
  FT_List_Find( FT_List  list,
                void*    data );


  /**************************************************************************
   *
   * @function:
   *   FT_List_Add
   *
   * @description:
   *   Append an element to the end of a list.
   *
   * @inout:
   *   list ::
   *     A pointer to the parent list.
   *   node ::
   *     The node to append.
   */
  FT_EXPORT( void )
  FT_List_Add( FT_List      list,
               FT_ListNode  node );


  /**************************************************************************
   *
   * @function:
   *   FT_List_Insert
   *
   * @description:
   *   Insert an element at the head of a list.
   *
   * @inout:
   *   list ::
   *     A pointer to parent list.
   *   node ::
   *     The node to insert.
   */
  FT_EXPORT( void )
  FT_List_Insert( FT_List      list,
                  FT_ListNode  node );


  /**************************************************************************
   *
   * @function:
   *   FT_List_Remove
   *
   * @description:
   *   Remove a node from a list.  This function doesn't check whether the
   *   node is in the list!
   *
   * @input:
   *   node ::
   *     The node to remove.
   *
   * @inout:
   *   list ::
   *     A pointer to the parent list.
   */
  FT_EXPORT( void )
  FT_List_Remove( FT_List      list,
                  FT_ListNode  node );


  /**************************************************************************
   *
   * @function:
   *   FT_List_Up
   *
   * @description:
   *   Move a node to the head/top of a list.  Used to maintain LRU lists.
   *
   * @inout:
   *   list ::
   *     A pointer to the parent list.
   *   node ::
   *     The node to move.
   */
  FT_EXPORT( void )
  FT_List_Up( FT_List      list,
              FT_ListNode  node );


  /**************************************************************************
   *
   * @functype:
   *   FT_List_Iterator
   *
   * @description:
   *   An FT_List iterator function that is called during a list parse by
   *   @FT_List_Iterate.
   *
   * @input:
   *   node ::
   *     The current iteration list node.
   *
   *   user ::
   *     A typeless pointer passed to @FT_List_Iterate.  Can be used to point
   *     to the iteration's state.
   */
  typedef FT_Error
  (*FT_List_Iterator)( FT_ListNode  node,
                       void*        user );


  /**************************************************************************
   *
   * @function:
   *   FT_List_Iterate
   *
   * @description:
   *   Parse a list and calls a given iterator function on each element.
   *   Note that parsing is stopped as soon as one of the iterator calls
   *   returns a non-zero value.
   *
   * @input:
   *   list ::
   *     A handle to the list.
   *   iterator ::
   *     An iterator function, called on each node of the list.
   *   user ::
   *     A user-supplied field that is passed as the second argument to the
   *     iterator.
   *
   * @return:
   *   The result (a FreeType error code) of the last iterator call.
   */
  FT_EXPORT( FT_Error )
  FT_List_Iterate( FT_List           list,
                   FT_List_Iterator  iterator,
                   void*             user );


  /**************************************************************************
   *
   * @functype:
   *   FT_List_Destructor
   *
   * @description:
   *   An @FT_List iterator function that is called during a list
   *   finalization by @FT_List_Finalize to destroy all elements in a given
   *   list.
   *
   * @input:
   *   system ::
   *     The current system object.
   *
   *   data ::
   *     The current object to destroy.
   *
   *   user ::
   *     A typeless pointer passed to @FT_List_Iterate.  It can be used to
   *     point to the iteration's state.
   */
  typedef void
  (*FT_List_Destructor)( FT_Memory  memory,
                         void*      data,
                         void*      user );


  /**************************************************************************
   *
   * @function:
   *   FT_List_Finalize
   *
   * @description:
   *   Destroy all elements in the list as well as the list itself.
   *
   * @input:
   *   list ::
   *     A handle to the list.
   *
   *   destroy ::
   *     A list destructor that will be applied to each element of the list.
   *     Set this to `NULL` if not needed.
   *
   *   memory ::
   *     The current memory object that handles deallocation.
   *
   *   user ::
   *     A user-supplied field that is passed as the last argument to the
   *     destructor.
   *
   * @note:
   *   This function expects that all nodes added by @FT_List_Add or
   *   @FT_List_Insert have been dynamically allocated.
   */
  FT_EXPORT( void )
  FT_List_Finalize( FT_List             list,
                    FT_List_Destructor  destroy,
                    FT_Memory           memory,
                    void*               user );

  /* */


FT_END_HEADER

#endif /* FTLIST_H_ */


/* END */
