package IO;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import Model.LayeredGraphEdge;
import Model.LayeredGraphNode;

/**
 * Writes a {@link LayeredGraphNode} to a JSON file.
 * @author kolja
 *
 */
public class Writer {

    private String file;
    
    public Writer( String outputFileName )
    {
        file = outputFileName;
    }
    
    /**
     * Writes the given {@link LayeredGraphNode} to a JSON file.
     * @param graph the graph that is to be saved.
     */
    public void writeOutputGraph( LayeredGraphNode graph )
    {
        try {
            BufferedWriter w = new BufferedWriter( new FileWriter( file ) );
            w.write( parseNode( graph ).toString() );
            w.close();
        } catch (IOException | JSONException e) {
            e.printStackTrace();
        }        
    }
    
    private JSONObject parseNode( LayeredGraphNode graph ) throws JSONException
    {
        JSONObject node = new JSONObject();
        JSONArray layers = new JSONArray();
        int id = 0;
        for( ArrayList<LayeredGraphNode> l : graph.getContainedLayers() )
        {
            JSONArray layer = new JSONArray();
            for( LayeredGraphNode n : l )
            {
                n.setName( "" + (id++) );
                layer.put( parseNode( n ) );
            }
            layers.put( layer );
        }
        node.put( "layers", layers );
        JSONArray edges = new JSONArray();
        for( LayeredGraphEdge e : graph.getContainedEdges() )
        {
            edges.put( parseEdge( e ) );
        }
        node.put( "edges", edges );
        node.put( "name", graph.getName() );
        return node;
    }
    
    private JSONObject parseEdge( LayeredGraphEdge e ) throws JSONException
    {
        JSONObject edge = new JSONObject();
        edge.put( "source", e.getSources().get( 0 ).getName() );
        edge.put( "target", e.getTargets().get( 0 ).getName() );
        return edge;
    }
}
