//genMethods "-g" "-t" "int" "-d" "basic" "-y" "display_int" "-w" "free_int" 
#include <stk.h>
#include <LINK/stkWrapper/LINK_STk.h>
#include <LINK/stkWrapper/Wrapper.h>
#include <LINK/stkWrapper/Register.h>
void display_int(SCM, SCM, int);
void free_int(SCM);
typedef int _int;
#define _intDATA(x) ((int*) (EXTDATA(x)))
#define _intIS_DATA(x) (TYPEP(x, tc_CXXwrapper) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<int >::type))
#define _intISNT_DATA(x) (!IS_DATA(x))
#define _intCXX_DATA(x) (*(int*) (EXTDATA(VAL(x))))
#define _intCXX_IS_DATA(x) (INSTANCEP(x) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<int >::type))
#define _intCXX_ISNT_DATA(x) (!CXX_IS_DATA(x))
#include<iostream.h>
#include<strstream.h>
void free_int(SCM p)
{
	//cout << "free_int" << endl;
        if (!EXTSTATICP(p))
                Register<int>::deleteEntry(_intDATA(p));
}
void display_int(SCM c, SCM port, int mode)
{
        ostrstream oss;
        if (_intDATA(c))
        	oss << *_intDATA(c);
        oss << ends;
        char *buffer = oss.str();
        Puts(buffer, PORT_FILE(port));
        delete buffer;
}

PRIMITIVE MakeIntCmd(SCM num)
{
        Tcl_HashEntry *p;
        SCM objptr;
        int *ap;
        int not_found;
        if (NINTEGERP(num))
                Err("<integer> expected", num);
        ap = new int(INTEGER(num));
        //Register<int>::createEntry(ap);
        Register<int>::createEntry(Wrapper<int>::type,
                                       Wrapper<int>::name, ap);
        return STk_make_CXXwrapper(Wrapper<int>::type,
                        Wrapper<int>::name, (void *) ap, LINK_DYNAMIC);
}

static PRIMITIVE SeedRandomDoubleCmd(SCM n)
{
	if (NEXACTP(n)) Err("set-seed!: bad number", n);
	Link_setSeed(STk_integer_value_no_overflow(n));
	return UNDEFINED;
}
static PRIMITIVE RandomLongCmd(SCM n)
{
	if (NEXACTP(n)) Err("random-int: bad integer", n);
	long l = Link_randomLong();
	return STk_makeinteger(l % STk_integer_value_no_overflow(n));
}
static double round_it(double d, int places)
{
	double mult = pow(10.0, places);
	return floor(d * mult) / mult;
}
static PRIMITIVE RandomDoubleCmd()
{
	double d = Link_randomDouble0_1();
	return STk_makenumber(round_it(d, 3));
}
// define your new methods above 
// and register them using STk_add_new_cpp_primitive() below
void genExtra_intMethods() 
{
        STk_add_new_cpp_primitive("set-seed!", tc_subr_1,
                                       (PRIMITIVE (*)(...))SeedRandomDoubleCmd);
        STk_add_new_cpp_primitive("random-int", tc_subr_1,
                                       (PRIMITIVE (*)(...))RandomLongCmd);
        STk_add_new_cpp_primitive("random-double", tc_subr_0,
                                        (PRIMITIVE (*)(...))RandomDoubleCmd);
        STk_add_new_cpp_primitive("make-int", tc_subr_1,
                                        (PRIMITIVE (*)(...))MakeIntCmd);
}
