#include<stk.h>
#include<LINK/stkWrapper/LINK_STk.h>
#include<LINK/stkWrapper/Wrapper.h>
#include<LINK/algorithm/Algorithms.h>
#include<LINK/basic/Sequence.h>
#include<LINK/graph/Graph.h>
#include<LINK/graph/Edge.h>

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

static PRIMITIVE DepthFirstSearchCmd(SCM g)
{
        Graph *gr;
        if (!(gr = getGraph(g)))
                Err("dfs: bad arg 1, graph expected", g);
        Sequence<Vertex*> s = DepthFirstSearch(gr);
        Sequence<Vertex*>* sp = new Sequence<Vertex*>(s);

        return STk_make_CXXwrapper(Wrapper<Sequence<Vertex*> >::type,
                Wrapper<Sequence<Vertex*> >::name, (void *) sp, LINK_DYNAMIC);
}

static PRIMITIVE DepthFirstSearchAnimCmd(SCM g, SCM view)
{
        Graph *gr;
        if (!(gr = getGraph(g)))
                Err("dfs: bad arg 1, graph expected", g);
	char *name = getViewName(view);
	int k = initAnimation();
	animationWindows(k, name);
        Sequence<Vertex*> s = DepthFirstSearch(gr,0,name);
        Sequence<Vertex*>* sp = new Sequence<Vertex*>(s);

        return STk_make_CXXwrapper(Wrapper<Sequence<Vertex*> >::type,
                Wrapper<Sequence<Vertex*> >::name, (void *) sp, LINK_DYNAMIC);
}

typedef Vertex* VertexPtr;
extern int rev_compare_vertices_by_finishtime(const VertexPtr&, 
					      const VertexPtr&);

static PRIMITIVE DepthFirstSearchAnimCmd2(SCM g, SCM view)
{
        Graph *gr;
        if (!(gr = getGraph(g)))
                Err("dfs: bad arg 1, graph expected", g);
	char *name = getViewName(view);
	int k = initAnimation();
	animationWindows(k, name);
        Sequence<Vertex*> s = 
	       DepthFirstSearch(gr,rev_compare_vertices_by_finishtime,name);
        Sequence<Vertex*>* sp = new Sequence<Vertex*>(s);

        return STk_make_CXXwrapper(Wrapper<Sequence<Vertex*> >::type,
                Wrapper<Sequence<Vertex*> >::name, (void *) sp, LINK_DYNAMIC);
}

void gen_DepthFirstSearch_Wrapper()
{
        STk_add_new_cpp_primitive("dfs", tc_subr_1,
                               (PRIMITIVE (*)(...))DepthFirstSearchCmd);
        STk_add_new_cpp_primitive("dfs*", tc_subr_2,
                               (PRIMITIVE (*)(...))DepthFirstSearchAnimCmd);
        STk_add_new_cpp_primitive("dfs-decreasing-finish-time*", tc_subr_2,
                               (PRIMITIVE (*)(...))DepthFirstSearchAnimCmd2);
        STk_add_new_cpp_primitive("depth-first-search", tc_subr_1,
                               (PRIMITIVE (*)(...))DepthFirstSearchCmd);
        STk_add_new_cpp_primitive("depth-first-search*", tc_subr_2,
                               (PRIMITIVE (*)(...))DepthFirstSearchAnimCmd);
}
