//genMethods "-g" "-t" "int*" "-h" "Array" "-I" "LINK/basic/Array.h" "-d" "basic" 

#include <stk.h>
#include <LINK/stkWrapper/LINK_STk.h>

#include <LINK/basic/Array.h>

#include <LINK/stkWrapper/Wrapper.h>
#include <LINK/stkWrapper/Register.h>
#include <LINK/stkWrapper/ArrayWrapper.h>


typedef int* _int_;
typedef Array<int* > _Array_int__;

#define _Array_int__DATA(x) ((Array<int* >*) (EXTDATA(x)))
#define _Array_int__IS_DATA(x) (TYPEP(x, tc_CXXwrapper) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<Array<int* > >::type))
#define _Array_int__ISNT_DATA(x) (!IS_DATA(x))

#define _Array_int__CXX_DATA(x) (*(Array<int* >*) (EXTDATA(VAL(x))))
#define _Array_int__CXX_IS_DATA(x) (INSTANCEP(x) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<Array<int* > >::type))
#define _Array_int__CXX_ISNT_DATA(x) (!CXX_IS_DATA(x))

PRIMITIVE intVector2STkList(SCM l)
{
        SCM z;

        if  (CXX_NTYPEP(l, Wrapper<Array<int*> >::type))
                Err("typed-list-convert: wrong type of argument", l);
        Array<int*> *lp = (Array<int*>*) CLASSDATA(l);
        Iterator<int*> get_next(lp);
        int *e;
        if (get_next(e)) {
                SCM new_el = STk_makeinteger(*e);
                SCM tail, head;
                NEWCELL(tail, tc_cons);
                CAR(tail) = new_el;
                CDR(tail) = NIL;
                head = tail;
                SCM z;
                while (get_next(e)) {
                        SCM new_el  = STk_makeinteger(*e);
                        NEWCELL(z, tc_cons);
                        CAR(z) = new_el;
                        CDR(z) = NIL;
                        CDR(tail) = z;
                        tail = z;
                }
                return head;
        }
        return NIL;
}

PRIMITIVE fillIntVector(SCM v, SCM e)
{
        SCM ne = MakeIntCmd(e);
        return ArrayWrapper<int*>::fillLinkArray(v, ne);
}

PRIMITIVE setIntVector(SCM v, SCM i, SCM e)
{
        SCM ne = MakeIntCmd(e);
        return ArrayWrapper<int*>::setLinkArray(v, i, ne);
}



// define your new methods above 
// and register them using STk_add_new_cpp_primitive() below

void genExtra_Array_int__Methods() 
{
        STk_add_new_cpp_primitive("vector-int->list2", tc_subr_1,
        (PRIMITIVE (*)(...))  intVector2STkList);
        STk_add_new_cpp_primitive("Vector-int-vector-set2!", tc_subr_3,
        (PRIMITIVE (*)(...))  setIntVector);
        STk_add_new_cpp_primitive("Vector-int-vector-fill2!", tc_subr_2,
        (PRIMITIVE (*)(...))  fillIntVector);


        //addOneArgMethod("vector-int->list",
        //        Wrapper<_Array_int__ >::name,
        //        "vector-int->list2", LINK_OVL);

        //addThreeArgMethod("vector-set!",
        //        Wrapper<_Array_int__ >::name,
        //        "<integer>",
        //        "<integer>",
        //        "Vector-int-vector-set2!", LINK_OVL);
        //addTwoArgMethod("vector-fill!",
        //        Wrapper<_Array_int__ >::name,
        //        "<integer>",
        //        "Vector-int-vector-fill2!", LINK_OVL);

}
