// Medusa is a graph viewer which allows interactive editing of networks
// (edges and nodes) and also connects to databases.
//
// Copyright (C) 2006 Sean Hooper
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330,
// Boston, MA 02111-1307 USA

package medusa.dataio;


import java.io.IOException;
import java.util.regex.Pattern;
import java.io.File;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.awt.Color;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.Iterator;

import java.util.HashMap;
import medusa.*;
import medusa.display.PaintTools;
import medusa.display.BasicGraphPanel;
import medusa.graph.BasicGraph;
import medusa.graph.Edge;
import medusa.graph.Graph;
import medusa.graph.Node;

//import clusterBlast.Graph;

/**
 * Class for saving, loading and exporting Graph objects to
 * text file formats. Also writes graphs to postscript
 * and pajek formats.
 */
public class DataLoader implements Runnable{
    
    private int width;
    private int height;
    private String fileName;
    //private MedusaSettings ss;
    private int nodeSize=10;
    
    public static final int LOAD_MEDUSA=0;
    public static final int LOAD_TABBED=1;
    private int loadType;
    public void setLoadType(int loadType){
        this.loadType=loadType;
    }
    
    /**
     * Constructs a new DataLoader and passes the graph size
     * information. Usually, graphs are 600x600 in size.
     * 
     * 
     * @param width
     * @param height
     */
    public DataLoader(int x, int y){
        this.width=x;
        this.height=y;
    }
    
    /**
     * 
     * 
     * 
     * @param width
     * @param height
     * @param fileName
     */
    public DataLoader(int x, int y, String fileName){
        this.width=x;
        this.height=y;
        this.fileName=fileName;
    }
    
    
    
    public DataLoader(){
        this.width=600;
        this.height=600;
    }
    
    // threaded methods, like load data
    Thread me=null;
    public void start(){
        if (me==null) {
            me=new Thread(this);
        }
        me.start();
        //System.out.println("thread started");
    }
    
    public void stop(){
        if (me!=null) {
            me=null;
        }
    }
    
    private Graph g;
    /**
     *
     * @return the graph object
     */
    public Graph getGraph(){
        return g;
    }
    
    public void run(){
        Thread myThread=Thread.currentThread();
        if (me==myThread){
            //System.out.println("thread running");
            g=new Graph();
            busy=true; done=false;
            try {
                switch (loadType){
                    case LOAD_MEDUSA:
                        g=load(fileName);
                        break;
                    case LOAD_TABBED:
                        g=loadSimplest(fileName);
                        break;
                        
                }
                success=true;
                
            } catch (IOException ie){
                success=false;
                
                
            } catch (DataFormatException ie){
                success=false;
                
            }
            
            busy=false;
        }
        done=true;
    }
    
    private boolean done;
    private boolean success;
    public boolean isDone(){
        return done;
    }
    private String status = "idle";
    public String getStatus(){
        return status;
    }
    private int progress;
    public int getProgress(){
        return progress;
    }
    
    private boolean busy=false;
    
    /**
     * Lets other methods know if the DataLoader is busy.
     * @return true if busy
     */
    public boolean isBusy(){
        return busy;
    }
    /**
     * The file to load. Set this before running the load
     * thread.
     * @param fileName
     */
    public void setFileName(String fileName){
        this.fileName=fileName;
    }
    
    private String separator="[\\t\\s]+";
    
    // structure patterns
    Pattern structurePattern = Pattern.compile("\\*nodes");
    Pattern startPattern = Pattern.compile("\\*edges");
    
    // edge patterns
    Pattern basicEdgePattern = Pattern.compile("^([^\\t]+)\\t([^\\t]+)");
    Pattern confEdgePattern = Pattern.compile("\\tc +([\\.\\d]+)");
    Pattern orientationEdgePattern = Pattern.compile("\\to +([\\-\\.\\d]+)");
    Pattern visibleEdgePattern = Pattern.compile("\\tf +(\\w+)");
    Pattern interactionEdgePattern = Pattern.compile("\\ti +(\\d+)");
    
    // node patterns
    Pattern basicNodePattern = Pattern.compile("^([^\\t]+)");
    Pattern xyNodePattern = Pattern.compile("\\t([\\.\\d]+)\\t([\\.\\d]+)");
    Pattern colorNodePattern = Pattern.compile
            ("\\tc *\\D*(\\d+)\\D*(\\d+)\\D*(\\d+)\\D*");
    Pattern color2NodePattern = Pattern.compile
            ("\\tc2 *\\D*(\\d+)\\D*(\\d+)\\D*(\\d+)\\D*");
    Pattern color3NodePattern = Pattern.compile
            ("\\tc3 *\\D*(\\d+)\\D*(\\d+)\\D*(\\d+)\\D*");
     Pattern color4NodePattern = Pattern.compile
            ("\\tc4 *\\D*(\\d+)\\D*(\\d+)\\D*(\\d+)\\D*");
    Pattern fixedNodePattern = Pattern.compile("\\tf +(\\w+)");
    Pattern shapeNodePattern = Pattern.compile("\\ts +(\\d)");

    Pattern dataspace1Pattern = Pattern.compile("\\td1 +(\\d+)");
    //Pattern annotationPattern = Pattern.compile("\\ta \\\"([^\\\"]+)\\\"");
    Pattern annotationPattern = Pattern.compile("\\ta \\\"(.+)\\\"");
    Pattern URLPattern = Pattern.compile("\\turl \\\"(.+)\\\"");
    Pattern ClusterPattern = Pattern.compile("\\tcluster \\\"(.+)\\\"");
    
    // parameter patterns
    // edge: n1:n2:i:c:o
    Pattern edgeParaPattern =
            Pattern.compile("\\s*(\\w[^:^\\s]+):([^:]+):(\\d+):([\\d\\.]+):([\\-\\d\\.]+)");
    Pattern testEdgeParaPattern =
            Pattern.compile("\\s*(\\w[^:]+):");
    // node: n1:width:height:c:s
    Pattern nodeParaPattern =
            Pattern.compile("\\s*(\\w[^:]+):([\\d\\.]+):([\\d\\.]+):(\\d+),(\\d+),(\\d+):(\\d)");
    
    /* save data to file
     */
    /**
     * Writes the graph to file
     * @param graph
     * @param fileName
     * @throws java.io.IOException
     */
    public void save(BasicGraph graph, String fileName) throws IOException{
        File saveFile = new File(fileName);
        FileWriter out = new FileWriter(saveFile);
        out.write(graph.report());
        out.close();
    }
    
    
    // this hack is horrid!
    /**
     * This method is not very nice... will need to be rewritten.
     * The scale function is generally messy.
     */
    public void save(Graph graph, String fileName, double scale)
    throws IOException{
        //System.out.println("scaling to "+1.0/scale);
        //try {
        //Graph g = (Graph)graph.clone();
        double scaler = scale*600;
        graph.rescaleNodes(1.0/scaler);
        //System.out.println("rescaled to "+scale);
        File saveFile = new File(fileName);
        FileWriter out = new FileWriter(saveFile);
        out.write(graph.report());
        graph.rescaleNodes(scaler);
        out.close();
        
        //catch (CloneNotSupportedException cs){
        //}
    }
    
    /* load data from a file
     */
    String currentFileName=null;
    
    /**
     * Loads a medusa format file.
     * @param fileName File to load
     * @throws java.io.IOException
     * @throws medusa.DataFormatException
     * @return returns a Graph object which is passed to Medusa
     */
    public Graph load(String fileName) throws IOException, DataFormatException{
        busy=true;
        max=600.0;
        progress=0;
        currentFileName=fileName;
        Graph graph = new Graph();
        
        String inLine;
        Matcher matcher;
        String comment="";
        File loadFile = new File(fileName);
        BufferedReader in = new BufferedReader
                (new InputStreamReader(new FileInputStream(loadFile)));
        //read to where the edges start
        while((inLine=in.readLine())!=null){
            
            matcher=startPattern.matcher(inLine);
            if (matcher.find())
                break;
            // if not edges, add to comment line
            comment+=inLine;
            comment+="\n";
            graph.addComment(comment);
        }
        
        // read the edges
        status="Reading edges";
        while ( (inLine=in.readLine())!=null){
            matcher=structurePattern.matcher(inLine);
            if (matcher.find()){
                //System.out.println("node section found");
                //containsNodes=true;
                status="Reading nodes";
                break;
            }
            Edge temp = readEdge(inLine);
            if (temp!=null){
                //graph.addEdge(readEdge(inLine));
                graph.addEdge(temp);
                progress++;
            }
        }
        
        
        // read nodes
        status="Reading nodes";
        while ( (inLine=in.readLine())!=null){
            readNode(graph,inLine);
        }
        
        in.close();
        busy=false;
       /* if (max>normalSize)
            graph.rescaleNodes(normalSize/max);*/
        status="idle";
        return graph;
    }
    
 
    
    /**
     * Loads the simplest possible file of three columns:
     * node1   node2   identity
     *
     * This can be used for instance by biologists who run BLAST searches with
     * the -m 8 option.
     *
     * If identity is greater than 1.0, it is rescaled.
     * @param fileName
     * @throws java.io.IOException
     * @throws medusa.DataFormatException
     * @return
     */
    public Graph loadSimplest(String fileName) throws IOException, DataFormatException{
        Graph graph = new Graph();
        //max=0;
        progress=0;
        String inLine;
        File loadFile = new File(fileName);
        BufferedReader in = new BufferedReader
                (new InputStreamReader(new FileInputStream(loadFile)));
        String[] result;
        while((inLine=in.readLine())!=null){
            result=inLine.split("\t");
            if(result.length>2){
                graph.addEdge(new Node(result[0]),new Node(result[1]),Float.parseFloat(result[2]),1);
                progress++;
            } else{
                throw new DataFormatException("File does not have three columns");
            }
            
        }
        in.close();
        graph.rescaleNodePercentage();
        // if (max>normalSize)
        //   graph.rescaleNodes(normalSize/max);
        if (graph.getEdgeSize()==0){
            throw new DataFormatException("No edges found");
        }
        return graph;
    }
    
    final double normalSize=600.0;
    double max;
    
    private void readNode(Graph g, String inLine){
       
        Matcher matcher=basicNodePattern.matcher(inLine);
        
        if (!matcher.find())
            return;
        //System.out.println(matcher.group(1));
        Node n=g.getNode(matcher.group(1));
        if (n==null)
            return;
        
        matcher=xyNodePattern.matcher(inLine);
        if (matcher.find()){
            double nodeX=Double.parseDouble(matcher.group(1));
            double nodeY=Double.parseDouble(matcher.group(2));
            //System.out.println("Found coords "+nodeX+" "+nodeY);
            if (nodeX<=1.0)
                nodeX*=width;
            if (nodeY<=1.0)
                nodeY*=height;
            // System.out.println("--- transformed to "+nodeX+" "+nodeY);
            n.setXY(nodeX,nodeY );
            // changed this
            //max=Math.max(max,Math.max(nodeX,nodeY));
            
        }
        
        // get color
        matcher=colorNodePattern.matcher(inLine);
        if (matcher.find()){
            java.awt.Color color=new java.awt.Color
                    (Integer.parseInt(matcher.group(1)),
                    Integer.parseInt(matcher.group(2)),
                    Integer.parseInt(matcher.group(3))
                    );
            n.setColor(color);
        }
        
        matcher=color2NodePattern.matcher(inLine);
        if (matcher.find()){
            java.awt.Color color=new java.awt.Color
                    (Integer.parseInt(matcher.group(1)),
                    Integer.parseInt(matcher.group(2)),
                    Integer.parseInt(matcher.group(3))
                    );
            n.setColor2(color);
        }
        matcher=color3NodePattern.matcher(inLine);
        if (matcher.find()){
            java.awt.Color color=new java.awt.Color
                    (Integer.parseInt(matcher.group(1)),
                    Integer.parseInt(matcher.group(2)),
                    Integer.parseInt(matcher.group(3))
                    );
            n.setColor3(color);
        }

         matcher=color4NodePattern.matcher(inLine);
        if (matcher.find()){
            java.awt.Color color=new java.awt.Color
                    (Integer.parseInt(matcher.group(1)),
                    Integer.parseInt(matcher.group(2)),
                    Integer.parseInt(matcher.group(3))
                    );
            n.setClusteringColor(color);
        }
        
        matcher = shapeNodePattern.matcher(inLine);
        if (matcher.find()){
            int shape=Integer.parseInt(matcher.group(1));
            n.setShape(shape);
        }
        
        matcher = dataspace1Pattern.matcher(inLine);
        if (matcher.find()){
            int ds1=Integer.parseInt(matcher.group(1));
            n.setDataSpace1(ds1);
        }
        matcher = annotationPattern.matcher(inLine);
        if (matcher.find()){
            String[] str = inLine.split("\t");
            for (int i = 0; i < str.length; i++) {
                String string = str[i];
                String pattern = "a \"";
                if(string.startsWith(pattern))
                    n.setAnnotation(string.substring(string.indexOf("\"")+1, string.lastIndexOf("\"")));
            }
            
        }

        matcher = URLPattern.matcher(inLine);
        if (matcher.find()){
            String[] str = inLine.split("\t");
            for (int i = 0; i < str.length; i++) {
                String string = str[i];
                String pattern = "url \"";
                if(string.startsWith(pattern))
                    n.setURL(string.substring(string.indexOf("\"")+1, string.lastIndexOf("\"")));
            }
        }
        matcher = ClusterPattern.matcher(inLine);
        if (matcher.find()){
            String[] str = inLine.split("\t");
            for (int i = 0; i < str.length; i++) {
                String string = str[i];
                String pattern = "cluster \"";
                if(string.startsWith(pattern))
                      n.setCluster(string.substring(string.indexOf("\"")+1, string.lastIndexOf("\"")));
            }
        }

        // get fixed
        matcher=fixedNodePattern.matcher(inLine);
        if (matcher.find())
            n.setFixed(Boolean.getBoolean(matcher.group(1)));
        
        
    }
    
    
    private Edge readEdge(String inLine) throws DataFormatException{
        //MRPL9	GON5	i 5	c 0.784	o 0	v true
        // get basic fields
        Edge e;
        Matcher matcher=basicEdgePattern.matcher(inLine);
        if (!matcher.find()){
            //return null;
            throw new
                    DataFormatException("Error in data file at line:\n "+inLine
                    +".\nEdge must contain basic node data."+
                    "If you are using an old data file version,"+
                    "consider using the conversion utility\n"+
                    "Offending line: \n"+inLine);
        }
        
        e=new Edge(matcher.group(1), matcher.group(2));
        float conf;
        matcher=confEdgePattern.matcher(inLine);
        if (matcher.find()){
            //System.out.println("conf: "+matcher.group(1));
            conf=Float.parseFloat(matcher.group(1));
            if ( (conf<0.0f) | (conf>1.0f))
                throw new DataFormatException("Confidence may not be less than"+
                        " zero or greater than one.\n"+
                        matcher.group(1)+" in line: \n"+inLine);
            e.setConf(conf);
        }
        
        // get orientation
        matcher=orientationEdgePattern.matcher(inLine);
        if (matcher.find()){
            //System.out.println("orientation: "+matcher.group(1));
            
            double d=Double.parseDouble(matcher.group(1));
            e.setOrientation(d);
        }
        /*// get visible
        matcher=visibleEdgePattern.matcher(inLine);
        if (matcher.find())
        edges[nedges-1].visible=Boolean.valueOf
        (matcher.group(1)).booleanValue();
         */
        // get the interaction type, ie the 'color'
        matcher=interactionEdgePattern.matcher(inLine);
        if (matcher.find())
            e.setType(Integer.parseInt
                    (matcher.group(1)) );
        
        return e;
    }
    
    // load from parameter lines
    // the format can be stricter, since the server admin has control over
    // the parameter output. No user friendliness anymore :)
    /**
     * For applets. Get parameter lines, e.g nodes and edges,
     * from the applet context and create a new graph.
     * @param edges
     * @param nodes
     * @return
     */
    public Graph readParameters(String edges, String nodes){
        Graph g=new Graph();
        Edge temp;
        //System.out.println(edges+"\n "+nodes);
        String edgeResult[] = edges.split(";\\n?");
        String[]  edgeItems;
        int lines = edgeResult.length;
        System.out.println("checking "+edgeResult.length+" edges");
        for (int i=0; i4)
        {
            Node n=g.getNode(result[0]);
            double nodeX=Double.parseDouble(result[1]);
            double nodeY=Double.parseDouble(result[2]);
            String[] colorComponents=result[3].split(",");
            java.awt.Color color=new java.awt.Color
                    (Integer.parseInt(colorComponents[0]),
                    Integer.parseInt(colorComponents[1]),
                    Integer.parseInt(colorComponents[2])
                    );
            n.setXY(nodeX,nodeY);
            n.setColor(color);
            int shape=Integer.parseInt(result[4]);
            n.setShape(shape);

            if(result.length>=6)
                n.setAnnotation(result[5]);

        if(result.length>=6)
            for (int i = 6; i < result.length; i++) {
                if(result[i].toLowerCase().contains("'cluster") )
                {String[] str  = result[i].split("cluster"); n.setCluster(str[1].substring(0,str[1].length()-1));}
                if(result[i].toLowerCase().contains("'http") )
                    n.setURL("http:"+result[i+1].substring(0,result[i+1].length()-1));
            }

          //  System.out.println("~~~~~~~~~~~~~~~"+n.getLabel()+" "+n.getAnnotation()+" "+n.getURL()+" "+n.getCLuster());
                

          
        }
        
        
    }
    
    
    
    
    /**
     * Draw the graph to postscript format
     */
    public void saveAsPS(Graph g, String saveFileName,MedusaSettings ss)
    throws IOException{
        saveAsPS( g,saveFileName,ss, nodeSize, fontSize);
    }
    
    private int fontSize=10;
    public void saveAsPS(Graph g, String saveFileName,
            MedusaSettings ss, int nodeSize, int fontSize)
            throws IOException{
        this.nodeSize=nodeSize;
        this.fontSize=fontSize;
        File saveFile = new File(saveFileName);
        FileWriter out = new FileWriter(saveFile);
        out.write("%!PS\n");
        
        drawGraph(g, out, ss);
        
        // finish the PS
        out.write("showpage\n");
        out.close();
    }
    
    public void saveAsEPS(Graph g, String saveFileName,MedusaSettings ss, int nodeSize, int fontSize)
    throws IOException{
        this.nodeSize=nodeSize;
        this.fontSize=fontSize;
        File saveFile = new File(saveFileName);
        FileWriter out = new FileWriter(saveFile);
        out.write("%!PS-Adobe EPSF-3.0\n");
        out.write("%%Creator: Medusa\n");
        out.write("%%BoundingBox: 0 0 "+docWidth+" "+docHeight+"\n");
        drawGraph(g, out, ss);
        
        // finish the PS
        //out.write("showpage\n");
        out.close();
    }
    
    private void drawGraph(Graph g, FileWriter out, MedusaSettings ss)
    throws IOException{
        
        out.write("50 50 translate\n");
        out.write("0.2 setlinewidth\n");
        out.write("0 0 0 setrgbcolor\n");
        
        // draw the edges
        drawEdges(out,g, ss);
        
        // draw nodes
        drawNodes(out,g);
        
        // draw labels
        drawLabels(out,g);
        
        // finish the PS
        //out.write("showpage\n");
        //out.close();
    }
    
    // public Color getColor(Integer i){
    //	return stringSettings.getColor(i);
    // }
    final int docWidth = 500;
    final int docHeight = 500;
    private int psY(double y){
        return (int)((600.0-y)/600.0*docHeight);
    }
    private int psX(double x){
        return (int)(x/600.0*docWidth);
    }
    private void drawEdges(FileWriter out, Graph g, MedusaSettings ss)
    throws IOException{
        int x1,x2;
        int y1,y2;
        String[] nodes = new String[2];
        Edge e;
        Node n1,n2;
        Integer colorType;
        Color color;
        float alpha;
        out.write("%% drawing edges\n");
        for (java.util.Iterator i = g.edgesIterator();i.hasNext();){
            e = (Edge) i.next();
            nodes=e.getNodes();
            n1=g.getNode(nodes[0]);
            x1=psX(n1.getX());
            
            y1=psY(n1.getY());
            n2=g.getNode(nodes[1]);
            x2=psX(n2.getX());
            
            y2=psY(n2.getY());
            
            colorType=new Integer(e.getType());
            color = (Color) ss.getColor(colorType);
            alpha = e.getConf();
            out.write(colorToString(color));
            out.write(alpha+" setalpha\n");
            // check if we want a path or a line
            if (e.getOrientation()!=0.0) {
                int[] cPoints = PaintTools.intControlPoints
                        (x1,y1,x2,y2,e.getOrientation(),BasicGraphPanel.offset);
                out.write(x1+" "+y1+" moveto\n");
                out.write(cPoints[0]+" "+cPoints[1]+" "+cPoints[2]+" "
                        +cPoints[3]+" "+x2+" "+y2+" curveto stroke\n");
            } else {
                out.write(x1+" "+y1+" moveto\n");
                out.write(x2+" "+y2+" lineto stroke\n");
            }
            
        }
        out.write("1.0 setalpha\n");
    }
    
    private String colorToString(final Color color){
        double red = color.getRed()/255.;
        double green = color.getGreen()/255.;
        double blue = color.getBlue()/255.;
        
        return red+" "+green
                +" "+blue+" setrgbcolor\n";
    }
    
    private void drawLabels(FileWriter out, Graph g) throws IOException{
        int labelCorrect=5;
        int x1;
        int y1;
        Node n;
        out.write("%% drawing labels\n");
        out.write("0 0 0 setrgbcolor\n");
        for (java.util.Iterator i = g.nodesIterator();i.hasNext();){
            n = (Node) i.next();
            x1=psX(n.getX());
            y1=psY(n.getY());
            //y1=600-(int)n.getY();
            out.write("/Times-Roman findfont\n"+fontSize+" scalefont\nsetfont\nnewpath\n");
            out.write((x1-labelCorrect)+" "+(y1+labelCorrect)+" moveto\n");
            out.write("("+n.getLabel()+") show\n");
            
        }
    }
    
    private void drawNodes(FileWriter out, Graph g) throws IOException{
        Node n;
        
        out.write("%% drawing nodes\n");
        
        for (java.util.Iterator i = g.nodesIterator();i.hasNext();){
            n = (Node) i.next();
            drawNodeShape(out,n);
            
            
        }
    }
    
    private void drawNodeShape(FileWriter out, Node n) throws IOException{
        int x1=psX(n.getX());
        int y1=psY(n.getY());
        java.awt.Color color=n.getColor();
        int shape=n.getShape();
        //int nodeSize=8;
        
        
        out.write(colorToString(color));
        switch (shape){
            case 1:
                out.write(PaintTools.psRectangle(x1,y1,nodeSize));
                break;
            case 2:
                out.write(PaintTools.psTriangle(x1,y1,nodeSize));
                break;
            case 3:
                out.write(PaintTools.psRhomb(x1,y1,nodeSize));
                break;
                
            default:
                out.write(PaintTools.psCircle(x1,y1,nodeSize));
                break;
        }
    }
    
    
    
    public void saveAsPajek(Graph g,String saveFileName) throws IOException{
        File saveFile = new File(saveFileName);
        FileWriter out = new FileWriter(saveFile);
        int nnodes = g.getNodeSize();
        out.write("*Vertices\t"+nnodes+"\n");
        int count=1;
        String cr = "\r\n";
        
        // we need to translate node names into indexes... add nodes to
        // a hashmap
        HashMap hm = new HashMap();
        for (Iterator i = g.nodesIterator();i.hasNext();count++){
            Node n = (Node) i.next();
            out.write(count+"\t\""+n.getLabel()+"\"\t"+n.getX()+"\t"+n.getY()+cr);
            hm.put(n.getLabel(),new Integer(count));
            
        }
        
        String[] nodes = new String[2];
        Integer n1,n2;
        
        // the hashmap is a dictionary
        out.write("*Edges\n");
        for (Iterator i = g.edgesIterator();i.hasNext();){
            Edge e = (Edge) i.next();
            nodes = e.getNodes();
            n1 = (Integer) hm.get(nodes[0]);
            n2 = (Integer) hm.get(nodes[1]);
            out.write(n1+"\t"+n2+"\t"+e.getType()+cr);
        }
        out.close();
    }




        public void saveAsArena3D(Graph g,String saveFileName) throws IOException{
        File saveFile = new File(saveFileName);
        FileWriter out = new FileWriter(saveFile);
        int nnodes = g.getNodeSize();

        ArrayList layers = new ArrayList();
          for (Iterator i = g.nodesIterator();i.hasNext();){
            Node n = (Node) i.next();
            if(!layers.contains(n.getColor()))
                layers.add(n.getColor());
          }
        if(layers.size()<=1)
            layers.add(Color.gray);


        out.write("number_of_layers::"+layers.size()+"\r\n");

        HashMap cl = new HashMap();
            for (int k = 0; k < layers.size(); k++) {
                out.write("layer::"+"number_"+(k+1)+"\r\n");
                      for (Iterator i = g.nodesIterator();i.hasNext();){
                        Node n = (Node) i.next();
                        if(layers.get(k).equals(n.getColor()))
                        {
                            cl.put(n.getLabel(), "number_"+(k+1));
                            out.write(n.getLabel()+"\t");
                            out.write("DESCTIPTION::"+n.getAnnotation()+"\t");
                            if(n.getURL()!=null)
                            if(n.getURL().contains("http"))
                            out.write("URL::"+n.getURL()+"\t");
                            out.write("\r\n");

                        }
                      }
                out.write("end_of_layer_inputs\r\n");
            }
        

        int count=1;
        String cr = "\r\n";

        // the hashmap is a dictionary
        ArrayList connections  = new ArrayList();
        out.write("start_connections\r\n");
        for (Iterator i = g.edgesIterator();i.hasNext();){
            Edge e = (Edge) i.next();
            if(!connections.contains(e.getFromName()+"\t"+e.getToName())){
            out.write(e.getFromName()+"::"+cl.get(e.getFromName())+"\t"+e.getToName()+"::"+cl.get(e.getToName())+"\t"+e.getConf()+"\r\n");
            connections.add(e.getFromName()+"\t"+e.getToName());
            }
        }
        out.write("end_connections\r\n");
        out.close();
        
    }



     public void saveAsBiolayout(Graph g,String saveFileName) throws IOException{
        File saveFile = new File(saveFileName);
        FileWriter out = new FileWriter(saveFile);
        for (Iterator i = g.edgesIterator();i.hasNext();){
            Edge e = (Edge) i.next();
            out.write(e.getFromName()+"\t"+e.getToName()+"\t"+e.getConf()+"\t"+"\""+e.getType()+"\""+"\r\n");
        }
        out.close();

    }


       public void saveAsCytoscape(Graph g,String saveFileName) throws IOException{
        File saveFile = new File(saveFileName);
        FileWriter out = new FileWriter(saveFile);
        for (Iterator i = g.edgesIterator();i.hasNext();){
            Edge e = (Edge) i.next();
            out.write(e.getFromName()+"\t"+e.getType()+"\t"+e.getToName()+"\r\n");
        }
        out.close();

    }



        public void saveAsGraphViz(Graph g,String saveFileName) throws IOException{
        File saveFile = new File(saveFileName);
        FileWriter out = new FileWriter(saveFile);

        out.write("digraph G {\r\n");

        for (Iterator i = g.edgesIterator();i.hasNext();){
            Edge e = (Edge) i.next();
            out.write(e.getFromName()+" -> "+e.getToName()+";\r\n");
        }

        out.write("}\r\n");
        out.close();

    }
















    public void saveHTMLParameters(Graph g, String fileName)
    throws IOException{
        StringBuffer sb=new StringBuffer();
        sb.append("\n");
        sb.append("\n");
        sb.append("\n");
        sb.append("\n");
        FileWriter out = new FileWriter(fileName);
        out.write(sb.toString());
        out.close();
        
    }
    
}

 

Ads help maintain this website.