#include<stk.h>
#include<LINK/stkWrapper/LINK_STk.h>
#include<LINK/stkWrapper/Wrapper.h>
#include<LINK/stkWrapper/Register.h>
#include<LINK/generator/Generators.h>
#include<LINK/graph/UBinGraph.h>
#include<LINK/graph/Graph.h>

#include <stdio.h>
#include <stdlib.h>

static PRIMITIVE GenCycleCmd(SCM n)
{
        Graph *gr;
        if (!INTEGERP(n))
                Err("gen-cycle: bad arg 1, <integer> expected", n);
	int sz = INTEGER(n);
        Graph *g = GenCycle(sz);
        Register<Graph>::createEntry(Wrapper<UBinGraph>::type,
                                     Wrapper<UBinGraph>::name, g);
        Graph **gp = new Graph*(g);

        return STk_make_CXXwrapper(Wrapper<UBinGraph*>::type,
                Wrapper<UBinGraph*>::name, (void *) gp, LINK_DYNAMIC);
}

void gen_Cycle_Wrapper()
{
        STk_add_new_cpp_primitive("gen-cycle", tc_subr_1,
                               (PRIMITIVE (*)(...))GenCycleCmd);
}
#include<stk.h>
#include<LINK/stkWrapper/LINK_STk.h>
#include<LINK/stkWrapper/Wrapper.h>
#include<LINK/stkWrapper/Register.h>
#include<LINK/generator/Generators.h>
#include<LINK/graph/UBinGraph.h>
#include<LINK/graph/Graph.h>

#include <stdio.h>
#include <stdlib.h>

static PRIMITIVE GenRandomGraphCmd(SCM n, SCM p)
{
        Graph *gr;
        if (!INTEGERP(n))
                Err("gen-random-graph: bad arg 1, <integer> expected", n);
        if (!FLONUMP(p))
                Err("gen-random-graph: bad arg 2, <number> expected", n);
	int sz = INTEGER(n);
	double prob = FLONM(p);
        Graph *g = GenRandomGraph(sz, prob);
        Register<Graph>::createEntry(Wrapper<UBinGraph>::type,
                                     Wrapper<UBinGraph>::name, g);
        Graph **gp = new Graph*(g);
        return STk_make_CXXwrapper(Wrapper<UBinGraph*>::type,
                Wrapper<UBinGraph*>::name, (void *) gp, LINK_DYNAMIC);
}

void gen_RandomGraph_Wrapper()
{
        STk_add_new_cpp_primitive("gen-random-graph", tc_subr_2,
                               (PRIMITIVE (*)(...))GenRandomGraphCmd);
}
#include<stk.h>
#include<LINK/stkWrapper/LINK_STk.h>
#include<LINK/stkWrapper/Wrapper.h>
#include<LINK/stkWrapper/Register.h>
#include<LINK/generator/Generators.h>
#include<LINK/graph/UBinGraph.h>
#include<LINK/graph/Graph.h>

#include <stdio.h>
#include <stdlib.h>

static PRIMITIVE GenCompleteGraphCmd(SCM n)
{
        Graph *gr;
        if (!INTEGERP(n))
                Err("gen-cycle: bad arg 1, <integer> expected", n);
	int sz = INTEGER(n);
        Graph *g = GenCompleteGraph(sz);
        Register<Graph>::createEntry(Wrapper<UBinGraph>::type,
                                     Wrapper<UBinGraph>::name, g);
        Graph **gp = new Graph*(g);

        return STk_make_CXXwrapper(Wrapper<UBinGraph*>::type,
                Wrapper<UBinGraph*>::name, (void *) gp, LINK_DYNAMIC);
}

void gen_CompleteGraph_Wrapper()
{
        STk_add_new_cpp_primitive("gen-complete-graph", tc_subr_1,
                               (PRIMITIVE (*)(...))GenCompleteGraphCmd);
}
#include<stk.h>
#include<LINK/stkWrapper/LINK_STk.h>
#include<LINK/stkWrapper/Wrapper.h>
#include<LINK/stkWrapper/Register.h>
#include<LINK/generator/Generators.h>
#include<LINK/graph/UBinGraph.h>
#include<LINK/graph/Graph.h>

#include <stdio.h>
#include <stdlib.h>

static PRIMITIVE GenGridGraphCmd(SCM rows, SCM cols)
{
        Graph *gr;
        if (!INTEGERP(rows))
             Err("gen-grid-graph: bad arg 1, #rows (<integer>) expected", rows);
        if (!INTEGERP(cols))
             Err("gen-grid-graph: bad arg 1, #cols (<integer>) expected", cols);
	int r = INTEGER(rows);
	int c = INTEGER(cols);
        Graph *g = GenGridGraph(r, c);
        Register<Graph>::createEntry(Wrapper<UBinGraph>::type,
                                     Wrapper<UBinGraph>::name, g);
        Graph **gp = new Graph*(g);

        return STk_make_CXXwrapper(Wrapper<UBinGraph*>::type,
                Wrapper<UBinGraph*>::name, (void *) gp, LINK_DYNAMIC);
}

void gen_GridGraph_Wrapper()
{
        STk_add_new_cpp_primitive("gen-grid-graph", tc_subr_2,
                               (PRIMITIVE (*)(...))GenGridGraphCmd);
}
#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);
}
#include<stk.h>
#include<LINK/stkWrapper/LINK_STk.h>
#include<LINK/stkWrapper/Wrapper.h>
#include<LINK/stkWrapper/Register.h>
#include<LINK/generator/Generators.h>
#include<LINK/graph/UBinGraph.h>
#include<LINK/graph/Graph.h>
#include <fstream.h>

static PRIMITIVE GenHalinGraphCmd(SCM g)
{
        Graph *gr = getGraph(g);
        if (!gr)
                Err("gen-halin-graph: bad arg 1, <graph*> expected", g);
        Graph *hg = GenHalinGraph(gr);
        Register<Graph>::createEntry(Wrapper<UBinGraph>::type,
                                     Wrapper<UBinGraph>::name, hg);
        Graph **gp = new Graph*(hg);
        return STk_make_CXXwrapper(Wrapper<UBinGraph*>::type,
                Wrapper<UBinGraph*>::name, (void *) gp, LINK_DYNAMIC);
}

void gen_HalinGraph_Wrapper()
{
        STk_add_new_cpp_primitive("gen-halin-graph", tc_subr_1,
                               (PRIMITIVE (*)(...))GenHalinGraphCmd);
}
#include<stk.h>
#include<LINK/stkWrapper/LINK_STk.h>
#include<LINK/stkWrapper/Wrapper.h>
#include<LINK/stkWrapper/Register.h>
#include<LINK/generator/Generators.h>
#include<LINK/graph/DBinGraph.h>
#include<LINK/graph/Graph.h>

#include <stdio.h>
#include <stdlib.h>

static PRIMITIVE GenLatkaTournamentCmd(SCM i, SCM k)
{
        Graph *gr;
        if (!INTEGERP(i))
                Err("gen-latka-tournament: bad arg 1, <integer> expected", i);
        if (!INTEGERP(k))
                Err("gen-latka-tournament: bad arg 2, <integer> expected", i);
	int sz = INTEGER(i);
	int spread = INTEGER(k);
        Graph *g = GenLatkaTournament(sz, spread);
        Register<Graph>::createEntry(Wrapper<DBinGraph>::type,
                                     Wrapper<DBinGraph>::name, g);
        Graph **gp = new Graph*(g);

        return STk_make_CXXwrapper(Wrapper<DBinGraph*>::type,
                Wrapper<DBinGraph*>::name, (void *) gp, LINK_DYNAMIC);
}

void gen_LatkaTournament_Wrapper()
{
        STk_add_new_cpp_primitive("gen-latka-tournament", tc_subr_2,
                               (PRIMITIVE (*)(...))GenLatkaTournamentCmd);
}
#include<iostream.h>
#include<strstream.h>
#include<stk.h>
#include<LINK/stkWrapper/LINK_STk.h>
#include<LINK/stkWrapper/Wrapper.h>
#include<LINK/algorithm/Algorithms.h>
#include<LINK/algorithm/Partitioning.h>
#include<LINK/basic/Sequence.h>
#include<LINK/graph/Graph.h>
#include<LINK/graph/UBinGraph.h>
#include<LINK/graph/Edge.h>
#include<LINK/graph/Vertex.h>

static PRIMITIVE GenPruferWrapper(SCM elements, int len)
{
        SCM vlist, elist;
        Graph *g, **gp;
        char vname[10];
        Sequence<int> seq;

        if (len == 0)
                return wrapGraph(new MUBinGraph);
        if (STRINGP(CAR(elements))) {
		g = GenPrufer(STRING(CAR(elements)));
        } else {
        	SCM l=elements;
        	for (;;) {
                	if (NULLP(l))
                        	break;
                	if (!INTEGERP(CAR(l)))
				Err("gen-prufer: integer expected", CAR(l));
                	seq.append(INTEGER(CAR(l)));
                	l = CDR(l);
        	}
        	g = GenPrufer(seq.size()+2, seq);
        }
        return wrapGraph(g);
}

void gen_Prufer_Wrapper()
{
        STk_add_new_cpp_primitive("gen-prufer", tc_lsubr,
				 (PRIMITIVE (*)(...))GenPruferWrapper);
}
#include<stk.h>
#include<LINK/stkWrapper/LINK_STk.h>
#include<LINK/stkWrapper/Wrapper.h>
#include<LINK/stkWrapper/Register.h>
#include<LINK/generator/Generators.h>
#include<LINK/graph/UBinGraph.h>
#include<LINK/graph/Graph.h>

#include <stdio.h>
#include <stdlib.h>

static PRIMITIVE GenRegularCmd(SCM n, SCM k)
{
        Graph *gr;
        if (!INTEGERP(n))
             Err("gen-regular-graph: bad arg 1, #verts (<integer>) expected",n);
        if (!INTEGERP(k))
             Err("gen-regular-graph: bad arg 2, degree (<integer>) expected",k);
	int r = INTEGER(n);
	int c = INTEGER(k);
        MUBinGraph *g = GenRegularGraph(r, c);
        Register<Graph>::createEntry(Wrapper<MUBinGraph>::type,
                                     Wrapper<MUBinGraph>::name, g);
        Graph **gp = new Graph*(g);

        return STk_make_CXXwrapper(Wrapper<MUBinGraph*>::type,
                Wrapper<MUBinGraph*>::name, (void *) gp, LINK_DYNAMIC);
}

void gen_Regular_Wrapper()
{
        STk_add_new_cpp_primitive("gen-regular-graph", tc_subr_2,
                               (PRIMITIVE (*)(...))GenRegularCmd);
}
#include<stk.h>
#include<LINK/stkWrapper/LINK_STk.h>
#include<LINK/stkWrapper/Wrapper.h>
#include<LINK/stkWrapper/Register.h>
#include<LINK/generator/Generators.h>
#include<LINK/graph/UHyperGraph.h>
#include<LINK/graph/Graph.h>

#include <stdio.h>
#include <stdlib.h>

static PRIMITIVE GenUHyperGraphKUCmd(SCM n, SCM m, SCM k)
{
        Graph *gr;
        if (!INTEGERP(n))
            Err("gen-uniform-hypergraph: bad arg 1, #v (<integer>) expected",n);
        if (!INTEGERP(m))
            Err("gen-uniform-hypergraph: bad arg 1, #e (<integer>) expected",m);
        if (!INTEGERP(k))
            Err("gen-uniform-hypergraph: bad arg 1, #v (<integer>) expected",k);
	int num_verts = INTEGER(n);
	int num_edges = INTEGER(m);
	int edge_size = INTEGER(k);
        Graph *g = GenUHyperGraphKU(num_verts, num_edges, edge_size);
        Register<Graph>::createEntry(Wrapper<UBinGraph>::type,
                                     Wrapper<UBinGraph>::name, g);
        Graph **gp = new Graph*(g);

        return STk_make_CXXwrapper(Wrapper<UHyperGraph*>::type,
                Wrapper<UBinGraph*>::name, (void *) gp, LINK_DYNAMIC);
}

void gen_UHyperGraphKU_Wrapper()
{
        STk_add_new_cpp_primitive("gen-uniform-hypergraph", tc_subr_3,
                               (PRIMITIVE (*)(...))GenUHyperGraphKUCmd);
}
