/*
Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
$Id$

=head1 NAME

classes/pytuple.pmc - Python tuple

=head1 DESCRIPTION

This class, PyTuple, implements an array of fixed size, which stores PMCs,
it puts things into Integer, Float, or String PMCs as appropriate
TODO currently this uses Perl types.

=head2 Methods

=over 4

=cut

*/

#include "parrot/parrot.h"

/* cache of classes referenced */
static INTVAL dynclass_PyInt;

pmclass PyTuple extends PyObject need_ext does array dynpmc group python_group {

/*

=item C<void class_init()>

Class initialization. Caches the type id of various PMCs because
they will be used frequently here.

=cut

*/

    void class_init() {
        if (pass) {
            dynclass_PyInt     = Parrot_PMC_typenum(INTERP, "PyInt");
        }
    }

/*

=item C<void init()>

Initializes the array.

=cut

*/

    void init () {
        list_pmc_new(INTERP, SELF);
        PMC_int_val(SELF) = 0;
    }

/*

=item C<void destroy()>

Destroys the array.

=cut

*/

    void destroy () {
        if (PMC_data(SELF))
            mem_sys_free(PMC_data(SELF));
        PMC_data(SELF) = NULL;
        PMC_int_val(SELF) = 0;
    }

/*

=item C<INTVAL elements()>

Returns the number of elements in the array.

=cut

*/

    INTVAL elements () {
        return PMC_int_val(SELF);
    }

/*

=item C<INTVAL get_integer()>

Returns the number of elements in the array.

=cut

*/

    INTVAL get_integer () {
        return DYNSELF.elements();
    }

/*

=item C<PMC* get_pmc_keyed_int(INTVAL key)>

Returns the PMC value of the element at index C<key>.

=cut

*/

    PMC* get_pmc_keyed_int (INTVAL key) {
        PMC **data;
        if (key < 0 || key >= PMC_int_val(SELF))
            internal_exception(OUT_OF_BOUNDS,
                "PyTuple: index out of bounds!\n");

        data = (PMC **)PMC_data(SELF);
        return data[key];
    }

/*

=item C<STRING *get_string()>

Return a representation of the tuple

=cut

*/

    STRING* get_string () {
        STRING *res, *s;
        INTVAL j, n;
        PMC *val;

        res = string_from_cstring(INTERP, "(", 0);
        n = VTABLE_elements(INTERP, SELF);
        for (j = 0; j < n; ++j) {
            val = SELF.get_pmc_keyed_int(j);
            res = string_append(INTERP, res,
                    VTABLE_get_repr(INTERP, val), 0);
            if (n == 1)
                res = string_append(INTERP, res,
                        const_string(INTERP, ","), 0);
            else if (j < n - 1)
                res = string_append(INTERP, res,
                        const_string(INTERP, ", "), 0);
        }
        res = string_append(INTERP, res,
                    const_string(INTERP, ")"), 0);
        return res;
    }

/*

=item C<void set_integer_keyed(PMC *key, INTVAL value)>

Sets the integer value of the element at index C<key> to C<value>.

=cut

*/

    void set_integer_keyed (PMC *key, INTVAL value) {
        PMC *val = pmc_new(INTERP, dynclass_PyInt);
        VTABLE_set_integer_native(INTERP, val, value);
        DYNSELF.set_pmc_keyed_int(PMC_int_val(key), val);
    }

/*

=item C<void set_integer_native(INTVAL size)>

Resizes the array to C<size> elements.

=cut

*/

    void set_integer_native (INTVAL size) {
        int i;
        PMC **data;

        if (PMC_int_val(SELF) && size)
            internal_exception(OUT_OF_BOUNDS, "PyTuple: Can't resize!\n");
        if (!size)
            return;
        PMC_int_val(SELF) = size;
        data = (PMC**)mem_sys_allocate(size * sizeof(PMC*));
        for(i = 0; i < size; i++)
            data[i] = PMCNULL;
        PMC_data(SELF) = data;
        PObj_data_is_PMC_array_SET(SELF);
    }

/*

=item C<void set_pmc_keyed_int(INTVAL key, PMC *src)>

Sets the PMC value of the element at index C<key> to C<*src>.

=cut

*/

    void set_pmc_keyed_int (INTVAL key, PMC* src) {
        PMC **data;
        if (key < 0 || key >= PMC_int_val(SELF))
            internal_exception(OUT_OF_BOUNDS,
                "PyTuple: index out of bounds!\n");

        data = (PMC**)PMC_data(SELF);
        DOD_WRITE_BARRIER(INTERP, SELF, data[key], src);
        data[key] = src;
    }

/*

=back

=cut

*/

}

/*
 * Local variables:
 * c-indentation-style: bsd
 * c-basic-offset: 4
 * indent-tabs-mode: nil
 * End:
 *
 * vim: expandtab shiftwidth=4:
*/
