#include <iostream.h>
#include <stk.h>
#include <LINK/stkWrapper/LINK_STk.h>
#include <LINK/graph/Graph.h>
#include <LINK/stkWrapper/Wrapper.h>
#include <LINK/stkWrapper/Register.h>
void display_graphptr(SCM, SCM, int);
void mark_graphptr(SCM);
void free_graphptr(SCM);
typedef Graph* _Graph_;
#define _Graph_DATA(x) ((Graph**) (EXTDATA(x)))
#define _Graph_IS_DATA(x) (TYPEP(x, tc_CXXwrapper) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<Graph* >::type))
#define _Graph_ISNT_DATA(x) (!IS_DATA(x))
#define _Graph_CXX_DATA(x) (*(Graph**) (EXTDATA(VAL(x))))
#define _Graph_CXX_IS_DATA(x) (INSTANCEP(x) && \
		TYPEP(STk_slot_ref(x,val_scm), tc_CXXwrapper) && \
		(EXTID(STk_slot_ref(x,val_scm)) == Wrapper<Graph* >::type))
#define _Graph_CXX_ISNT_DATA(x) (!CXX_IS_DATA(x))
//----------------------------------------------------------------------
#include <LINK/basic/Iterator.h>
#include <LINK/basic/Set.h>
#include <LINK/basic/Matrix.h>
#include <strstream.h>
#include <LINK/graph/Vertex.h>
#include <LINK/graph/Edge.h>
#include <LINK/graph/Graph.h>
#include <LINK/graph/UBinGraph.h>

static PRIMITIVE MakeGraphFromLinearOrdersCmd(SCM parms, int args)
{
	SCM numv = CAR(parms);
	int n;
	if (args < 1)
		Err("usage: (make-graph-from-linear-orders <num verts> "
		    " [<perm-rank1> <perm-rank2> ...])", parms);
	int &sv_type = Wrapper<Set<Vertex*> >::type;
	if (!INTEGERP(numv))
		Err("usage: (make-graph-from-linear-orders <num verts> "
		    " [<perm-rank1> <perm-rank2> ...])", parms);
	n = INTEGER(numv);
	SCM intparms = CDR(parms);
	Set<int> perms;
	for (;;) {
		if (NULLP(intparms))
			break;
		if (!INTEGERP(CAR(intparms)))
			Err("usage: (make-graph-from-linear-orders <num verts> "
		    	    " [<perm-rank1> <perm-rank2> ...])", parms);
		int next_perm = INTEGER(CAR(intparms));
		perms.insert(next_perm);
		intparms = CDR(intparms);
	}
	MUBinGraph *g = GenGraphFromLinearOrders(n, perms);
	return wrapGraph(g);
}

static PRIMITIVE UpdateLinearOrdersGraphCmd(SCM parms, int args)
{
	if (args < 1)
		Err("usage: (update-linear-orders-graph <graph*> "
		    " [<perm-rank1> <perm-rank2> ...])", parms);
	Graph *g = getGraph(CAR(parms));
	int n = g->order();
	int &sv_type = Wrapper<Set<Vertex*> >::type;
	SCM intparms = CDR(parms);
	Set<int> perms;
	for (;;) {
		if (NULLP(intparms))
			break;
		if (!INTEGERP(CAR(intparms)))
			Err("usage: (update-linear-orders-graph <graph*> "
		     	    " [<perm-rank1> <perm-rank2> ...])", parms);
		int next_perm = INTEGER(CAR(intparms));
		perms.insert(next_perm);
		intparms = CDR(intparms);
	}
	UpdateLinearOrdersGraph(g, perms);
	return UNDEFINED;
}

void gen_LinearOrdersGraph_Wrapper()
{
        STk_add_new_cpp_primitive("gen-graph-from-linear-orders", tc_lsubr,
                            (PRIMITIVE (*)(...))MakeGraphFromLinearOrdersCmd);
        STk_add_new_cpp_primitive("update-linear-orders-graph", tc_lsubr,
                            (PRIMITIVE (*)(...))UpdateLinearOrdersGraphCmd);
}
