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

#include <LINK/graph/Attribute.h>

#include <LINK/graph/Edge.h>

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

void display_attribute_edgeptr(SCM, SCM, int);

typedef Attribute<Edge*>* _Attribute_Edge___;

#define _Attribute_Edge___DATA(x) ((Attribute<Edge*>**) (EXTDATA(x)))
#define _Attribute_Edge___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<Edge*>* >::type))
#define _Attribute_Edge___ISNT_DATA(x) (!_Attribute_Edge___IS_DATA(x))

#define _Attribute_Edge___CXX_DATA(x) (*(Attribute<Edge*>**) (EXTDATA(VAL(x))))
#define _Attribute_Edge___CXX_IS_DATA(x) (INSTANCEP(x) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<Attribute<Edge*>* >::type))
#define _Attribute_Edge___CXX_ISNT_DATA(x) (!_Attribute_Edge___CXX_IS_DATA(x))

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

typedef Edge *EdgePtr;

#define EPTR(s)    (*(EdgePtr*) ((s)->storage_as.flonum.data))

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

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

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

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

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

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

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

	if (!SYMBOLP(name))
		Err("new-edge-attribute!: bad arg 1, symbol expected", name);
        if (!CXX_TYPEP(val, v_type))
               Err("new-edge-attribute!: bad arg 1, <edge*> expected", val);
	if (!(g = getGraph(go)))
		Err("new-attribute!: bad arg 3, graph expected", go);
	char *nm = PNAME(name);
	Edge *value = EPTR(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_Edge___Methods() 
{
        STk_add_new_cpp_primitive("find-edge-attribute", tc_subr_2,
                            (PRIMITIVE (*)(...))findEdgePtrAttributeCmd);
        STk_add_new_cpp_primitive("set-edge-attribute!", tc_subr_3,
                            (PRIMITIVE (*)(...))setEdgePtrAttributeCmd);
        STk_add_new_cpp_primitive("new-edge-attribute!", tc_subr_3,
                            (PRIMITIVE (*)(...))newEdgePtrAttributeCmd);
}
