/Users/petercappello/NetBeansProjects/56-2014/56-2014-FileIO/src/GraphIO.java
import java.awt.Point;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.DataFormatException;
import javax.swing.JFileChooser;

/**
 * A graph utility to read a graph from a file and write a graph to a file.
 * @author Peter Cappello
 */
public class GraphIO
{
    private final Map<Integer, List<Integer>> mapVvertexToAdjacencyList = new HashMap<>();
    
    /**
     * Construct a graph from its text representation in a file.
     * @throws IOException
     * @throws DataFormatException 
     */
    public void readFile() throws IOException, DataFormatException
    {
        JFileChooser fileChooser = new JFileChooser();
        int returnValue = fileChooser.showOpenDialog( null );
        if ( returnValue == JFileChooser.APPROVE_OPTION )
        {
            File readFile = fileChooser.getSelectedFile();
            try ( BufferedReader reader = new BufferedReader( new FileReader( readFile.getCanonicalPath() ) ) )
            {
                for ( String line; ( line = reader.readLine() ) != null; ) 
                {
                    addEdge( makeEdge( line ) );
                }
            }
        }
        // else the user cancelled the file chooser. 
    }
    
    /**
     * Write a text representation of the graph to a file. 
     * @throws java.io.IOException
     */
    public void writeFile() throws IOException
    {
        JFileChooser fileChooser = new JFileChooser();
        int returnValue = fileChooser.showSaveDialog( null );
        if ( returnValue == JFileChooser.APPROVE_OPTION )
        {
            File writeFile = fileChooser.getSelectedFile();
            try ( Writer writer = new BufferedWriter( new FileWriter( writeFile.getCanonicalPath() ) ) )
            {
                for ( Integer vertexV : mapVvertexToAdjacencyList.keySet() )
                {
                    List<Integer> adjacencyList = mapVvertexToAdjacencyList.get( vertexV );
                    {
                        for ( Integer vertexW : adjacencyList )
                        {
                            String line = vertexV + " " + vertexW;
                            writer.write( line );
                            writer.write( '\n' );
                            System.out.println( line );
                        }
                    }
                }
            }
        }
        // else user cancelled the file chooser.
    }
    
    private Point makeEdge( String line ) throws DataFormatException
    {
        String[] vertices = line.split( "\\s" );
        if ( vertices.length != 2 )
        {
            throw new DataFormatException( line + " should contain exactly 2 integers");
        }
        try
        {
            int vertexV = Integer.parseInt( vertices[ 0 ] );
            int vertexW = Integer.parseInt( vertices[ 1 ] );
            return new Point( vertexV, vertexW );
        }
        catch ( NumberFormatException exception )
        {
            String msg = "One of the following is not intepretible as an integer: " 
                       + vertices[ 0 ] + " " + vertices[ 1 ];
            throw new NumberFormatException( msg );
        }
    }
    
    private void addEdge( Point edge )
    {
        addEdge( edge.x, edge.y );
        addEdge( edge.y, edge.x );
    }
    
    private void addEdge( int v, int w )
    {
        List<Integer> edgeList = mapVvertexToAdjacencyList.get( v );
        if ( edgeList == null )
        {
            edgeList = new ArrayList();
            mapVvertexToAdjacencyList.put( v, edgeList );
        }
        assert edgeList != null;
        edgeList.add( w );
    }
    
    public static void main( String[] args ) throws IOException, DataFormatException
    {
        Graph graph = new Graph();
        TextFileProcessor textFileProcessor = new TextFileProcessor( null );
        System.out.println( "Reading graph ..." );
        textFileProcessor.readFile( graph );
        System.out.println(  "Writing graph ..." );
        textFileProcessor.writeFile( graph );
    }
}