//genMethods "-t" "Attribute<Vertex*>*" "-I" "LINK/graph/Attribute.h" "-I" "LINK/graph/Vertex.h" "-d" "graph" "-y" "display_attribute_vertexptr" 
#include <stk.h>
#include <LINK/stkWrapper/LINK_STk.h>

#include <LINK/graph/Attribute.h>

#include <LINK/graph/Vertex.h>

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

void display_attribute_vertexptr(SCM, SCM, int);

typedef Attribute<Vertex*>* _Attribute_Vertex___;

#define _Attribute_Vertex___DATA(x) ((Attribute<Vertex*>**) (EXTDATA(x)))
#define _Attribute_Vertex___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<Vertex*>* >::type))
#define _Attribute_Vertex___ISNT_DATA(x) (!_Attribute_Vertex___IS_DATA(x))

#define _Attribute_Vertex___CXX_DATA(x) (*(Attribute<Vertex*>**) (EXTDATA(VAL(x))))
#define _Attribute_Vertex___CXX_IS_DATA(x) (INSTANCEP(x) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<Attribute<Vertex*>* >::type))
#define _Attribute_Vertex___CXX_ISNT_DATA(x) (!_Attribute_Vertex___CXX_IS_DATA(x))


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

typedef Vertex *VertexPtr;

#define VPTR(s)    (*(VertexPtr*) ((s)->storage_as.flonum.data))

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

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

	if (!SYMBOLP(name))
		Err("find-vertex-attribute: bad arg 1, symbol expected", name);
	if (!(gobj = getGraphObject(go)))
		Err("find-vertex-attribute: bad arg 2, graph, vertex, or edge"
		    "expected", go);
	char *nm = PNAME(name);
	
	Vertex *val;
	if (getAttribute(gobj, nm, val) == LINK_GET_ATTR_FAIL)
		Err("find-attribute: error retrieving attribute", name);
	
        Vertex **w = new Vertex *(val);
        return STk_make_CXXwrapper(Wrapper<Vertex*>::type,
                        Wrapper<Vertex*>::name, (void *) w, LINK_DYNAMIC);
}

static SCM setVertexPtrAttributeCmd(SCM name, SCM val, SCM go)
{
	GraphObject *gobj;
        int& v_type = Wrapper<Vertex*>::type;

	if (!SYMBOLP(name))
		Err("set-vertex-attribute!: bad arg 1, symbol expected", name);

        if (!CXX_TYPEP(val, v_type))
               Err("set-vertex-attribute!: bad arg 1, <vertex*> expected", 
						val);
	if (!(gobj = getGraphObject(go)))
		Err("set-vertex-attribute!: bad arg 3, graph, vertex, or edge"
		    "expected", go);
	char *nm = PNAME(name);
	Vertex *value = VPTR(val);
	
	if (setAttribute(gobj, nm, value) == LINK_SET_ATTR_FAIL)
		Err("set-vertex-attribute: error setting attribute", name);
	
	return UNDEFINED;
}

static SCM newVertexPtrAttributeCmd(SCM name, SCM val, SCM go)
{
	Graph *g;
        int& v_type = Wrapper<Vertex*>::type;

	if (!SYMBOLP(name))
		Err("new-vertex-attribute!: bad arg 1, symbol expected", name);
        if (!CXX_TYPEP(val, v_type))
               Err("new-vertex-attribute!: bad arg 1, <vertex*> expected", val);
	if (!(g = getGraph(go)))
		Err("new-attribute!: bad arg 3, graph expected", go);
	char *nm = PNAME(name);
	Vertex *value = VPTR(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_Vertex___Methods() 
{
        STk_add_new_cpp_primitive("find-vertex-attribute", tc_subr_2,
                            (PRIMITIVE (*)(...))findVertexPtrAttributeCmd);
        STk_add_new_cpp_primitive("set-vertex-attribute!", tc_subr_3,
                            (PRIMITIVE (*)(...))setVertexPtrAttributeCmd);
        STk_add_new_cpp_primitive("new-vertex-attribute!", tc_subr_3,
                            (PRIMITIVE (*)(...))newVertexPtrAttributeCmd);
}
