#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<LINK/graph/Vertex.h>

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

static PRIMITIVE BreadthFirstSearchAnimCmd(SCM parms, int len)
{
    SCM graph, view=UNBOUND, vertex=UNBOUND;
    Graph *gr;
    char *name;
    Vertex *v;
    int& v_type = Wrapper<Vertex*>::type;

    switch (len) {
	case 0: return UNDEFINED;
		break;
	case 1: graph = CAR(parms);
		break;
	case 2: graph = CAR(parms);
		view = CAR(CDR(parms));
		break;
	case 3: graph = CAR(parms);
		view = CAR(CDR(parms));
		vertex = CAR(CDR(CDR(parms)));
		break;
    }
    if (!(gr = getGraph(graph)))
	Err("bfs: bad arg 1, graph expected", graph);
    if ((len > 1) && (!(name = getViewName(view))))
	Err("bfs: bad arg 2, graph view expected", view);
    if ((len > 2) && (!CXX_TYPEP(vertex, v_type)))
	Err("bfs: bad arg 3, <vertex*> expected", vertex);
    Sequence<Vertex*> s; 
    Sequence<Vertex*>* sp;
    if (len > 1) {
    	int k = initAnimation();
    	animationWindows(k, name);
	if (len > 2) {
		v = *(Vertex**) CLASSDATA(vertex);
    		s = BreadthFirstSearch(gr,name,v);
	} else
    		s = BreadthFirstSearch(gr,name);
    } else 
    	s = BreadthFirstSearch(gr);
    sp = new Sequence<Vertex*>(s);
    return STk_make_CXXwrapper(Wrapper<Sequence<Vertex*> >::type,
			       Wrapper<Sequence<Vertex*> >::name, (void *) sp, LINK_DYNAMIC);
}

void gen_BreadthFirstSearch_Wrapper()
{
        STk_add_new_cpp_primitive("bfs", tc_lsubr,
				 (PRIMITIVE (*)(...))BreadthFirstSearchAnimCmd);
        STk_add_new_cpp_primitive("breadth-first-search", tc_lsubr,
				 (PRIMITIVE (*)(...))BreadthFirstSearchAnimCmd);
}
