import org.graphstream.graph.*;
import org.graphstream.graph.implementations.SingleGraph;
import org.graphstream.stream.GraphParseException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.HashMap;

public class TP2 {
    public static void main(String[] args) {
        Graph graph = new SingleGraph("exemple");
        try {
            graph.read("data/exemple.dgs");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (GraphParseException e) {
            e.printStackTrace();
        }

        graph.addAttribute("ui.stylesheet", "edge { fill-color: #CACACA; }");


        // 1.1
//        BreadthFirstIterator<Node> bfi = new BreadthFirstIterator(graph.getNode("a"));
//        int n = 1;
//        while (bfi.hasNext()) {
//            Node v = bfi.next();
//            v.setAttribute("label", v.getId()+"("+n+")");
//            n++;
//        }

        //1.2
//        DepthFirstIterator<Node> dfi = new DepthFirstIterator(graph.getNode("a"));
//        int m = 1;
//        while (dfi.hasNext()) {
//            Node v = dfi.next();
//            v.setAttribute("label", v.getId()+"("+m+")");
//            m++;
//        }

        //2
        BreadthFirstIterator<Node> bfi = new BreadthFirstIterator(graph.getNode("a"));
        while (bfi.hasNext()) {
            Node v = bfi.next();
            v.setAttribute("label", v.getId()+"("+bfi.getDepthOf(v)+")");
        }

        HashMap<Node, Integer> distance = bfs(graph, graph.getNode("c"));
        HashMap<Node, Integer> poids = new HashMap<Node, Integer>();

        //4
        for (Node c : distance.keySet()) {
            poids.put(c, 0);
            int nb = 0;
            Iterator<Node> it = c.getNeighborNodeIterator();
            while (it.hasNext()) {
                Node n = it.next();
                if (distance.get(n) < distance.get(c)) {
                    if (poids.get(n)==null)
                        nb++;
                    else
                        nb += (poids.get(n));
                }
            }
            poids.put(c, poids.get(c) + nb);
        }

        System.out.println(poids);


        graph.display(false);
    }



    private static HashMap<Node, Integer> bfs(Graph g, Node s) {
        ArrayList<Node> open = new ArrayList<Node>();
        HashMap<Node, Integer> dist= new HashMap<Node, Integer>();
        for (int i = 0; i<g.getNodeCount(); i++) {
            Node v = g.getNode(i);
            dist.put(v, 100);
        }
        dist.put(s, 0);
        open.add(s);

        while (!open.isEmpty()){
            Node v = open.remove(0);

            Iterator<Edge> it = v.getEdgeIterator();
            while(it.hasNext()) {
                Edge e = it.next();
                Node u = e.getOpposite(v);
                if (dist.get(u) == 100) {
                    dist.put(u, dist.get(v)+1);
                    open.add(u);
                    e.setAttribute("ui.style", "fill-color:black;");
                }
            }
        }

        return dist;
    }
}
