import gabl.graph.*;
import gabl.export.*;
import java.io.*;

/************************************************************************
 * A class for demonstrating the simple usage of
 * <code><a href="http://www.math.tu-berlin.de/Vorlesungen/SoSe02/GuNA/jGABL/doc">jGABL</a></code>,
 * a GraphAlgorihmBasedLibrary in Java designed by
 * <a href="http://www.math.tu-berlin.de/~schwartz">Alexander Schwartz</a>.
 * The <code>main</code>-method of this <b>static class</b>
 * reads a <a href="http://www.infosun.fmi.uni-passau.de/Graphlet/GML/index.html">GML</a>-encoded
 * graph and prints out its nodes' incidence lists.
 ************************************************************************/
public class Incidence {
    
    /********************************************************************
     * The name of the default GML-graph file to be printed.
     ********************************************************************/
    public static final String filename="../../../Uebungen/SS01/mst_graph.2.gml";
    
    /********************************************************************
     * This is a <b>static class</b>...
     ********************************************************************/
    public Incidence() {
    }
    /********************************************************************
     * Create information for the given edge <code>e</code> of
     * the graph <code>g</code>. The format will be:<br>
     * <code>id: {source, target}</code>
     * @param g the graph that holds the edge <code>e</code>
     * @param e create information for this edge
     * @return information for the given edge <code>e</code>
     ********************************************************************/
    private static String showEdge(AdjGraph g, Edge e) {
        
        // ask the graph for id, source and target information of edge e
        return g.toString(e)+": {"+
            g.toString(g.getSource(e))+", "+
            g.toString(g.getTarget(e))+"}";
    }
    
    /********************************************************************
     * Prints the incidence lists of the given graph <code>g</code>
     * to <code>System.out</code>.
     * @param g the graph to be printed
     ********************************************************************/
    private static void showGraph(AdjGraph g) {
        
        // get access to the vertices of the graph g
        VertexIterator i=g.createVertexIterator();
        
        // step through every vertex of the graph
        for (; ! i.atEnd(); i.increment()) {
            
            // ask the graph to print the current node's information
            System.out.println(g.toString(i.getVertex())+": ");
            
            // get access to the edges incident to the current vertex
            AdjacencyIterator ai=g.createAdjacencyIterator(i.getVertex());
            
            // step through every edge incident to the current vertex
            for (; ! ai.atEnd(); ai.increment()) {
                
                // print out the current edge
                System.out.println("\t"+showEdge(g, ai.getEdge()));
            }
        }
    }
    
    /********************************************************************
     * Creates a <code>File</code> object from <code>argv[0]</code>,
     * or from <code>filename</code> if <code>argv</code> has no
     * components or <code>argv[0]</code> does not exists or is
     * not readable.
     * @param argv try to create a <code>File</code> object for
     *        <code>argv[0]</code>
     * @return a readable <code>File</code> object for
     *         <code>argv[0]</code>, or for <code>filename</code>,
     *         if not possible
     * @see #filename
     ********************************************************************/
    private static File getFile(String[] argv) {
        if (argv.length>=1) {
            File f=new File(argv[0]);
            if (f.exists() && f.canRead()) {
                return f;
            } else {
                System.err.println("Incidence: cannot read "+argv[0]+"...");
            }
        } else {
            System.err.println("Usage: java Incidence <filename>...");
        }
        System.err.println("... assuming "+filename+" as default.");
        return new File(filename);
    }
    
    /********************************************************************
     * Reads the graph in file <code>argv[0]</code> resp.
     * <code>filename</code> and prints out its nodes' adjacency lists.
     * @param argv show the contents of the given GML encoded graph
     *             file <code>argv[0]</code>, or <code>filename</code>,
     *             if no arguments are given
     * @see #filename
     ********************************************************************/
    public static void main(String[] argv) {
        try {
            
            // fix the graph to be read to be undirected and not mutable
            GraphFactory f=new GraphFactory();
            
            // read the desired graph
            GraphBundle b=GraphFormatGML.readGraph(getFile(argv), f);
            
            // interprete the bundle's graph as an adjacency graph
            AdjGraph g=(AdjGraph) b.getGraph();
            
            // print out the graph g
            showGraph(g);
            
        } catch (IOException e) {
            System.err.println("Adjacency: caught "+e+" on I/O");
        } catch (Throwable t) {
            System.err.println("Adjacency: caught "+t);
        }
    }
}

