/******************************************************************************
 *{@C
 * Copyright:   2018-2025 Paul Obermeier (obermeier@poSoft.de)
 *
 *              See the file "Mawt_License.txt" for information on
 *              usage and redistribution of this file, and for a
 *              DISCLAIMER OF ALL WARRANTIES.
 *
 * Description: SWIG file defining utility functions for accessing
 *              elements of a C vector.
 *              Slightly enhanced version of the carrays.i of the 
 *              SWIG standard library.
 *
 *              Note: Vectors of type "char", "unsigned char", 
 *                    GLchar and GLcharARB are not supported, because the
 *                    corresponding typemaps would collide with the standard
 *                    SWIG mapping for C strings.
 *                    Use type UByte, if you need Vectors 
 *                    with element sizes of 1 byte.
 *
 *****************************************************************************/

/* -----------------------------------------------------------------------------
 * %baseTypeVector(TYPE,NAME)
 *
 * Generates functions for creating and accessing elements of a C vector
 * (as pointers).  Creates the following functions:
 *
 *        TYPE *new_NAME(int nelements)
 *        void delete_NAME(TYPE *);
 *        TYPE NAME_getitem(TYPE *, int index);
 *        void NAME_setitem(TYPE *, int index, TYPE value);
 * 
 * ----------------------------------------------------------------------------- */

%define %baseTypeVector(TYPE,NAME)
%{
static TYPE *new_##NAME(int nelements) {
#if DEBUG_VECTOR
    printf (">> new_%s (%d)\n", "NAME", nelements); fflush (stdout);
#endif
%}
#ifdef __cplusplus
%{ return new TYPE[nelements]; %}
#else
%{ return (TYPE *) calloc(nelements,sizeof(TYPE)); %}
#endif
%{}

static void delete_##NAME(TYPE *ary) {
#if DEBUG_VECTOR
    printf ("<< delete_%s\n", "NAME"); fflush (stdout);
#endif
%}
#ifdef __cplusplus
%{ delete [] ary; %}
#else
%{ free(ary); %}
#endif
%{}

static int NAME##_elemsize(TYPE *ary) {
    return sizeof (ary[0]);
}

static TYPE NAME##_getitem(TYPE *ary, int index) {
    return ary[index];
}

static void NAME##_setitem(TYPE *ary, int index, TYPE value) {
    ary[index] = value;
}

static void NAME##_setrgb(TYPE *ary, int index, TYPE r, TYPE g, TYPE b) {
    ary[index]   = r;
    ary[++index] = g;
    ary[++index] = b;
}

static void NAME##_setrgba(TYPE *ary, int index, TYPE r, TYPE g, TYPE b, TYPE a) {
    ary[index]   = r;
    ary[++index] = g;
    ary[++index] = b;
    ary[++index] = a;
}

static void NAME##_setvector(TYPE *ary, TYPE value, int startIndex, int len) {
    int i;
    int endIndex = startIndex + len;
    for (i=startIndex; i<endIndex; i++) {
        ary[i] = value;
    }
}

static void NAME##_addvector(TYPE *ary, double value, int startIndex, int len) {
    int i;
    int endIndex = startIndex + len;
    for (i=startIndex; i<endIndex; i++) {
        ary[i] += (TYPE) value;
    }
}

static void NAME##_mulvector(TYPE *ary, double value, int startIndex, int len) {
    int i;
    int endIndex = startIndex + len;
    for (i=startIndex; i<endIndex; i++) {
        ary[i] *= (TYPE) value;
    }
}

static TYPE *NAME##_ind(TYPE *ary, int incr) {
    return (ary + incr);
}
static TYPE *NAME##_cast(void *ary) {
    return (TYPE *)ary;
}
%}

TYPE *new_##NAME(int nelements);
void delete_##NAME(TYPE *ary);
int  NAME##_elemsize(TYPE *ary);
TYPE NAME##_getitem(TYPE *ary, int index);
void NAME##_setitem(TYPE *ary, int index, TYPE value);
void NAME##_setrgb(TYPE *ary, int index, TYPE r, TYPE g, TYPE b);
void NAME##_setrgba(TYPE *ary, int index, TYPE r, TYPE g, TYPE b, TYPE a);
void NAME##_setvector(TYPE *ary, TYPE value, int startIndex, int len);
void NAME##_addvector(TYPE *ary, double value, int startIndex, int len);
void NAME##_mulvector(TYPE *ary, double value, int startIndex, int len);
TYPE *NAME##_ind(TYPE *ary, int incr);
TYPE *NAME##_cast(void *ary);

%enddef

// Generate vector functions (new, delete, getitem, setitem, setrgb, setrgba, ind, cast)
// for the following types.
%baseTypeVector(unsigned char,UByte)
%baseTypeVector(char,Byte)
