#include <stdlib.h>
#include <strstream.h>
#include <LINK/graph/Attribute.h>
#include <LINK/graph/Graph.h>
#include <LINK/graph/UBinGraph.h>
#include <LINK/graph/Vertex.h>
#include <LINK/graph/Edge.h>
#include <LINK/basic/Set.h>
    
//
// Generate a grid graph, given an n x m grid, and layout the
// vertices and edges on that grid.  m rows and n columns.
//

int findIndexOfLowestLabeledWithDegree1(int *degree_remaining, int n)
{
	int i;
	for (i=0; i<n; i++)
		if (degree_remaining[i] == 1)
			return i;
	return -1;
}

MUBinGraph*
GenPrufer(int n, Sequence<int> vnums)
{
    MUBinGraph*  graph = new MUBinGraph(); 	// Undirected binary graph
    int *degree_remaining = new int[n];

    if (vnums.size() != n-2)
	return graph;
    int i;
    for (i=0; i<n; i++)
	degree_remaining[i] = 1;

    int vnum;
    Iterator<int> get_vnums(&vnums);
    while (get_vnums(vnum)) {
		if ((vnum >= n) || (vnum < 0)) {
			cerr << "GenPrufer: illegal number in sequence:" 
			     << vnum << endl;
			cerr << "must be in the interval: (" << 0 << ","
                             << n-1 << ")" << endl;
			return graph;
		}
		degree_remaining[vnum]++;
    }
    graph->addVertices(n);
    int v1, v2;  
    MSet<Vertex*> vs;  
    get_vnums.reset();
    i=0;
    while (get_vnums(vnum)) {
	v1 = findIndexOfLowestLabeledWithDegree1(degree_remaining, n);
	if (v1 == -1) {
		cerr << "GenPrufer: error in sequence" << endl;
		return graph;
	}
	vs.insert(graph->vertex(v1)); 
	vs.insert(graph->vertex(vnum));
	Edge *e = graph->addEdge(vs);
	setAttribute((GraphObject*)e, "rank", i++);
	
        degree_remaining[v1]--;
        degree_remaining[vnum]--;
	vs.clear();
    }
    v1 = findIndexOfLowestLabeledWithDegree1(degree_remaining, n);
    degree_remaining[v1]--;
    v2 = findIndexOfLowestLabeledWithDegree1(degree_remaining, n);
    vs.insert(graph->vertex(v1)); 
    vs.insert(graph->vertex(v2));
    Edge *e = graph->addEdge(vs);
    setAttribute((GraphObject*)e, "rank", i);
    return graph;	
}

MUBinGraph*
GenPrufer(char *vnums)
{
	Sequence<int> vs;
	istrstream iss(vnums, strlen(vnums));
	int i;
	while (iss >> i)
		vs.append(i);
        return GenPrufer(vs.size()+2, vs);
}
