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

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

#include <LINK/basic/List.h>

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


typedef int* _int_;
typedef List<int* > _List_int__;

#define _List_int__DATA(x) ((List<int* >*) (EXTDATA(x)))
#define _List_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<List<int* > >::type))
#define _List_int__ISNT_DATA(x) (!IS_DATA(x))
#define _List_int__CXX_DATA(x) (*(List<int* >*) (EXTDATA(VAL(x))))
#define _List_int__CXX_IS_DATA(x) (INSTANCEP(x) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<List<int* > >::type))
#define _List_int__CXX_ISNT_DATA(x) (!CXX_IS_DATA(x))

static PRIMITIVE buildListInt(SCM l)
{
        SCM tmp, nl = NIL;
        SCM ne;
        SCM z;

        if (NNULLP(l)) {
                for (tmp=l; tmp != NIL; tmp = CDR(tmp))  {
                        ne = MakeIntCmd(CAR(tmp));
                        NEWCELL(z, tc_cons);
                        CAR(z) = ne;
                        CDR(z) = nl;
                        nl = z;
                }
                nl = STk_reverse(nl);
                return  ListWrapper<int*>::buildLinkList(nl);
        }
        return  NIL;
}

PRIMITIVE intList2STkList(SCM l)
{
        SCM z;

        if  (CXX_NTYPEP(l, Wrapper<List<int*> >::type))
                Err("typed-list-convert: wrong type of argument", l);
        List<int*> *lp = (List<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;
}


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

void genExtra_List_int__Methods() 
{
        STk_add_new_cpp_primitive("list-int2", tc_subr_1,
        (PRIMITIVE (*)(...))  buildListInt);
        STk_add_new_cpp_primitive("list-int->list2", tc_subr_1,
        (PRIMITIVE (*)(...))  intList2STkList);

        addIntListMethod("list-int", "list-int1", "list-int2", LINK_OVL);
        //addOneArgMethod("list->list-int",
        //        "<pair>",
        //        "list-int2", LINK_OVL);
        //addOneArgMethod("list-int->list",
        //        Wrapper<_List_int__ >::name,
        //        "list-int->list2", LINK_OVL);
}
