//genMethods "-t" "Attribute<int>*" "-I" "LINK/graph/Attribute.h" "-d" "graph" "-y" "display_attribute_int" 

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

#include <LINK/graph/Attribute.h>

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

void display_attribute_intptr(SCM, SCM, int);

typedef Attribute<int>* _Attribute_int__;

#define _Attribute_int__DATA(x) ((Attribute<int>**) (EXTDATA(x)))
#define _Attribute_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<Attribute<int>* >::type))
#define _Attribute_int__ISNT_DATA(x) (!_Attribute_int__IS_DATA(x))

#define _Attribute_int__CXX_DATA(x) (*(Attribute<int>**) (EXTDATA(VAL(x))))
#define _Attribute_int__CXX_IS_DATA(x) (INSTANCEP(x) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<Attribute<int>* >::type))
#define _Attribute_int__CXX_ISNT_DATA(x) (!_Attribute_int__CXX_IS_DATA(x))

#include <strstream.h>
#include <LINK/graph/GraphObject.h>

void display_attribute_intptr(SCM c, SCM port, int mode)
{
        ostrstream oss;
	if (*_Attribute_int__DATA(c))
        	oss << **_Attribute_int__DATA(c);
        oss << ends;
        char *buffer = oss.str();
        Puts(buffer, FILEPTR(port));
        delete buffer;
}

static SCM findAttributeCmd(SCM name, SCM go)
{
	GraphObject *gobj;

	if (!SYMBOLP(name))
		Err("find-attribute: bad arg 1, symbol expected", name);
	if (!(gobj = getGraphObject(go)))
		Err("find-attribute: bad arg 2, graph, vertex, or edge"
		    "expected", go);
	char *nm = PNAME(name);
	
	int val;
	if (getAttribute(gobj, nm, val) == LINK_GET_ATTR_FAIL)
		Err("find-attribute: error retrieving attribute", name);
	
	SCM ret_val = STk_makeinteger(val);
	return ret_val;
}

static SCM setAttributeCmd(SCM name, SCM val, SCM go)
{
	GraphObject *gobj;

	if (!SYMBOLP(name))
		Err("set-attribute!: bad arg 1, symbol expected", name);
	if (!INTEGERP(val))
		Err("set-attribute!: bad arg 2, integer expected", val);
	if (!(gobj = getGraphObject(go)))
		Err("set-attribute!: bad arg 3, graph, vertex, or edge"
		    "expected", go);
	char *nm = PNAME(name);
	int value = INTEGER(val);

	if (setAttribute(gobj, nm, value) == LINK_SET_ATTR_FAIL)
		Err("set-attribute: error setting attribute", name);
	
	return UNDEFINED;
}

static SCM newAttributeCmd(SCM name, SCM val, SCM go)
{
	Graph *g;

	if (!SYMBOLP(name))
		Err("new-attribute!: bad arg 1, symbol expected", name);
	if (!INTEGERP(val))
		Err("new-attribute!: bad arg 2, integer expected", val);
	if (!(g = getGraph(go)))
		Err("new-attribute!: bad arg 3, graph expected", go);
	char *nm = PNAME(name);
	int value = INTEGER(val);

	if (newAttribute(g, nm, value) == LINK_NEW_ATTR_FAIL)
		Err("new-attribute: error creating attribute", name);
	
	return UNDEFINED;
}

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

void genExtra_Attribute_int__Methods() 
{
        STk_add_new_cpp_primitive("find-attribute", tc_subr_2,
                                    (PRIMITIVE (*)(...))findAttributeCmd);
        STk_add_new_cpp_primitive("set-attribute!", tc_subr_3,
                                    (PRIMITIVE (*)(...))setAttributeCmd);
        STk_add_new_cpp_primitive("new-attribute!", tc_subr_3,
                                    (PRIMITIVE (*)(...))newAttributeCmd);
}

