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

#ifndef PS_VECTOR_H
#define PS_VECTOR_H

#include "psType.h"

/// @addtogroup Vector
/// @{

/** An vector to support primitive types.
 *
 * Struct for maintaining an vector of frequently used primitive types.
 *
 */
typedef struct
{
    psType type;                ///< Type of data.
    psU32 nalloc;        ///< Total number of elements available.
    psU32 n;             ///< Number of elements in use.

    union {
        psU8* U8;               ///< Unsigned 8-bit integer data.
        psU16* U16;             ///< Unsigned 16-bit integer data.
        psU32* U32;             ///< Unsigned 32-bit integer data.
        psU64* U64;             ///< Unsigned 64-bit integer data.
        psS8* S8;               ///< Signed 8-bit integer data.
        psS16* S16;             ///< Signed 16-bit integer data.
        psS32* S32;             ///< Signed 32-bit integer data.
        psS64* S64;             ///< Signed 64-bit integer data.
        psF32* F32;             ///< Single-precision float data.
        psF64* F64;             ///< Double-precision float data.
        psC32* C32;             ///< Single-precision complex data.
        psC64* C64;             ///< Double-precision complex data.
    } data;                     ///< Union for data types.
}
psVector;

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

/* FUNCTION PROTOTYPES                                                       */

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


/** Allocate a vector.
 *
 *  Uses psLib memory allocation functions to create a vector collection of
 *  data as defined by the psType type.
 *
 * @return psVector*    Pointer to psVector.
 */
psVector* psVectorAlloc(
    psU32 nalloc,               ///< Total number of elements to make available.
    psElemType dataType                ///< Type of data to be held by vector.
);

/** Reallocate a vector.
 *
 *  Uses psLib memory allocation functions to reallocate a vector collection
 *  of data. The vector is reallocated according to the psType type member
 *  contained within the vector.
 *
 *  @return psVector*      Pointer to psVector.
 *
 */
psVector* psVectorRealloc(
    psVector* psVec,                   ///< Vector to reallocate.
    psU32 nalloc                       ///< Total number of elements to make available.
);

/** Recycle a vector.
 *
 *  Uses psLib memory allocation functions to reallocate a vector collection
 *  of data. The vector is reallocated according to the psElemType type
 *  parameter.
 *
 * @return psVector*       Pointer to psVector.
 *
 */
psVector* psVectorRecycle(
    psVector* psVec,
    ///< Vector to recycle.  If NULL, a new vector is created.  No effort
    ///< taken to preserve the values.

    psU32 nalloc,                      ///< Total number of elements to make available.
    psElemType type                    ///< the datatype of the returned vector
);

/** Copy a vector, converting types.
 *
 *  Performs a deep copy of the elements of one psVector to a new psVector,
 *  converting numeric types to a specified type.
 *
 * @return psVector*       Pointer to resulting psVector.
 *
 */
psVector* psVectorCopy(
    psVector* out,                     ///< if non-NULL, a psVector to recycle
    const psVector* in,                ///< the vector to copy.
    psElemType type                    ///< the data type of the resulting psVector
);

/** Sort an array of floats.
 *
 *  Sorts an array of floats in ascending order.  This function is valid for
 *  all non-complex data types.
 *
 *  @return  psVector*     Pointer to sorted psVector.
 */
psVector* psVectorSort(
    psVector* outVector,               ///< the output vector to recycle, or NULL if new vector desired.
    const psVector* inVector           ///< the vector to sort.
);

/** Creates an array of indices based on sort ordered of array.
 *
 *  Sorts a vector and creates an integer array holding indices of
 *  sorted float values based on pre-sort index positions.
 *
 *  @return  psVector*     vector of the indices of sort.
 */
psVector* psVectorSortIndex(
    psVector* outVector,               ///< vector to recycle
    const psVector* inVector           ///< vector to sort
);

/** Creates a string from a psVector's values in the form "[x0,x1,x2]".
 *
 *  @return psPtr          a newly allocated string
 */
char* psVectorToString(
    psVector* vector,                  ///< vector to create a string from
    int maxLength                      ///< the maximum length of the resulting string
);

/** Returns an element in the vector as a psF64 value
 *
 *  @return psF64          the value at specified position, or NAN if position is invalid.
 */
psF64 p_psVectorGetElementF64(
    psVector* vector,                  ///< vector to retrieve element
    int position                       ///< the vector position to get
);

// XXX EAM a utility function
bool p_psVectorPrint (FILE *f, psVector *a, char *name);

/// @}

#endif
