/** @file  psScalar.c
 *
 *  @brief Contains basic scalar definitions and operations
 *
 *  This file defines the basic type for a scalar struct and functions useful
 *  in manupulating scalars.
 * *
 *  @author Ross Harman, MHPCC
 *
 *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
 *  @date $Date: 2005-02-17 19:26:23 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
 */

#include "psMemory.h"
#include "psError.h"
#include "psScalar.h"
#include "psLogMsg.h"
#include "psAbort.h"

#include "psCollectionsErrors.h"

psScalar* psScalarAlloc(psC64 value, psElemType dataType)
{
    psScalar* scalar = NULL;

    // Create scalar
    scalar = (psScalar* ) psAlloc(sizeof(psScalar));

    scalar->type.dimen = PS_DIMEN_SCALAR;
    scalar->type.type = dataType;

    switch (dataType) {
    case PS_TYPE_S8:
        scalar->data.S8 = (psS8) value;
        break;
    case PS_TYPE_U8:
        scalar->data.U8 = (psU8) value;
        break;
    case PS_TYPE_S16:
        scalar->data.S16 = (psS16) value;
        break;
    case PS_TYPE_U16:
        scalar->data.U16 = (psU16) value;
        break;
    case PS_TYPE_S32:
        scalar->data.S32 = (psS32) value;
        break;
    case PS_TYPE_U32:
        scalar->data.U32 = (psU32) value;
        break;
    case PS_TYPE_S64:
        scalar->data.S64 = (psS64) value;
        break;
    case PS_TYPE_U64:
        scalar->data.U64 = (psU64) value;
        break;
    case PS_TYPE_F32:
        scalar->data.F32 = (psF32) value;
        break;
    case PS_TYPE_F64:
        scalar->data.F64 = (psF64) value;
        break;
    case PS_TYPE_C32:
        scalar->data.C32 = (psC32) value;
        break;
    case PS_TYPE_C64:
        scalar->data.C64 = (psC64) value;
        break;
    default:
        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
                PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE,
                dataType);
        psFree(scalar);
        return NULL;
    }

    return scalar;
}

psScalar* psScalarCopy(psScalar *scalar)
{
    psElemType dataType;
    psScalar *newScalar = NULL;

    if (scalar == NULL) {
        psError(PS_ERR_BAD_PARAMETER_NULL, true,
                PS_ERRORTEXT_psScalar_COPY_NULL);
        return NULL;
    }

    dataType = scalar->type.type;
    switch (dataType) {
    case PS_TYPE_S8:
        newScalar =  psScalarAlloc(scalar->data.S8, dataType);
        break;
    case PS_TYPE_U8:
        newScalar =  psScalarAlloc(scalar->data.U8, dataType);
        break;
    case PS_TYPE_S16:
        newScalar =  psScalarAlloc(scalar->data.S16, dataType);
        break;
    case PS_TYPE_U16:
        newScalar =  psScalarAlloc(scalar->data.U16, dataType);
        break;
    case PS_TYPE_S32:
        newScalar =  psScalarAlloc(scalar->data.S32, dataType);
        break;
    case PS_TYPE_U32:
        newScalar =  psScalarAlloc(scalar->data.U32, dataType);
        break;
    case PS_TYPE_S64:
        newScalar =  psScalarAlloc(scalar->data.S64, dataType);
        break;
    case PS_TYPE_U64:
        newScalar =  psScalarAlloc(scalar->data.U64, dataType);
        break;
    case PS_TYPE_F32:
        newScalar =  psScalarAlloc(scalar->data.F32, dataType);
        break;
    case PS_TYPE_F64:
        newScalar =  psScalarAlloc(scalar->data.F64, dataType);
        break;
    case PS_TYPE_C32:
        newScalar =  psScalarAlloc(scalar->data.C32, dataType);
        break;
    case PS_TYPE_C64:
        newScalar =  psScalarAlloc(scalar->data.C64, dataType);
        break;
    default:
        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
                PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE,
                dataType);
        return NULL;
    }

    return newScalar;
}
