
/** @file  psArray.h
 *
 *  @brief Contains basic array definitions and operations
 *
 *  This file defines the basic type for a array struct and functions useful
 *  in manupulating arrays.
 *
 *  @ingroup Array
 *
 *  @author Robert DeSonia, MHPCC
 *  @author Ross Harman, MHPCC
 *
 *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
 *  @date $Date: 2005-02-09 01:04:01 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
 */

#ifndef PS_ARRAY_H
#define PS_ARRAY_H

#include "psType.h"
#include "psCompare.h"

/// @addtogroup Array
/// @{

/** An array to support primitive types.
 *
 * Struct for maintaining an array of frequently used primitive types.
 *
 */
typedef struct
{
    psU32 nalloc;        ///< Total number of elements available.
    psU32 n;             ///< Number of elements in use.
    psPtr* data;                ///< An Array of pointer elements
}
psArray;

/*****************************************************************************/

/* FUNCTION PROTOTYPES                                                       */

/*****************************************************************************/

/** Allocate an array.
 *
 * Uses psLib memory allocation functions to create an array collection of 
 * data
 *
 * @return psArray* : Pointer to psArray.
 *
 */
psArray* psArrayAlloc(
    psU32 nalloc                       ///< Total number of elements to make available.
);

/** Reallocate an array.
 *
 * Uses psLib memory allocation functions to reallocate an array collection 
 * of data. 
 *
 * @return psArray* : Pointer to psArray.
 *
 */
psArray* psArrayRealloc(
    psArray* psArr,                    ///< array to reallocate.
    psU32 nalloc                       ///< Total number of elements to make available.
);

/** Add an element to the end the array, expanding the array storage if
 *  necessary.
 *
 *  @return psArray*        The array with the element added
 */
psArray* psArrayAdd(
    psArray* psArr,                    ///< array to operate on
    int delta,
    ///< the amount to expand array, if necessary.  If less than one, 10 will be used.
    psPtr data                         ///< the data pointer to add to psArray
);

/** Remove an element from the array
 *
 *  Finds and removes the specified data pointer from the list.  
 *
 * @return bool:  TRUE if the specified data pointer was found and removed, 
 *                otherwise FALSE.
 *
 */
psBool psArrayRemove(
    psArray* psArr,                    ///< array to operate on
    psPtr data                         ///< the data pointer to remove from psArray
);

/** Deallocate/Dereference elements of an array.
 *
 * Uses psLib memory allocation functions to deallocate/dereference elements 
 * of a array of void pointers.  The array psArr is not freed, and its elements
 * will all be set to NULL.
 *
 */
void psArrayElementFree(
    psArray* psArr                     ///< Void pointer array to destroy.
);

/** Sort the array according to an external compare function.
 *
 *  Sorts an array via the specification of a comparison function
 *  to specify how the objects on the array should be sorted.
 *
 *  The comparison function must return an integer less than, equal to, or 
 *  greater than zero if the first argument is considered to be respectively 
 *  less than, equal to, or greater than the second. 
 *
 *  If two members compare as equal, their order in the sorted array is 
 *  undefined.
 *
 *  @return psArray* The sorted array.
 */
psArray* psArraySort(
    psArray* in,                       ///< input array to sort.
    psComparePtrFcn compare            ///< the compare function
);

/** Set an element in the array.  If the current element is non-NULL, the old
 *  element is freed.
 *
 *  @return psBool  TRUE if the element was set successfully, otherwise FALSE
 */
psBool psArraySet(
    psArray* in,                       ///< input array to set element in
    psU32 position,                    ///< the element position to set
    void* value                        ///< the value to set it to
);

/** Get an element from the array.
 *
 *  @return void*   the element at given position.
 */
void* psArrayGet(
    psArray* in,                       ///< input array to get element from
    psU32 position                     ///< the element position to get
);

/// @}

#endif
