package uk.me.graphe.client;

import java.util.HashMap;
import java.util.List;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.Window;

import uk.me.graphe.shared.Edge;
import uk.me.graphe.shared.Vertex;
import uk.me.graphe.shared.VertexDirection;
import uk.me.graphe.shared.graphmanagers.GraphManager2d;

public class GraphString{ 
    
    
    /**
     * Adds to the graph manager nodes,edges contained in the dot language code
     * @param graphManager
     * @param graphCode
     * @return
     *      false if error in the DOT code
     */
    public static boolean addDot(GraphManager2d graphManager,String graphCode){

        HashMap<String, Vertex> verticesMap = new HashMap<String, Vertex>();
        graphCode = graphCode.replaceAll("\\r|\\n", "");
        if(graphCode.indexOf("{") < 0)return false;
        if(graphCode.indexOf("}") < 0)return false;
        String betweenCurly = graphCode.split("{")[1].split("}")[0];
        String[] lines = betweenCurly.split(";");
        for(int i = 0;i<lines.length;i++){
            int weight = 1;
            String line = lines[i].trim();
            line = line.replaceAll(" ","");
            if(line.indexOf("label=\"") > 0){
                String label = line.split("label=\"")[1].split("\"")[0];
                weight = Integer.parseInt(label);
            }
            if(line.indexOf("[") > 0){
                line = line.split("\\[")[0].trim();
            }
            if(line.indexOf("->") > 0){
                String[] nodes = line.split("->");
                if(nodes.length!=2)return false;
                if(!verticesMap.containsKey(nodes[0]))verticesMap.put(nodes[0],new Vertex(nodes[0]));
                if(!verticesMap.containsKey(nodes[1]))verticesMap.put(nodes[1],new Vertex(nodes[1]));
                graphManager.addEdge(verticesMap.get(nodes[0].trim()), 
                        verticesMap.get(nodes[1].trim()), VertexDirection.fromTo, weight);
            }else{
                // Add node
                Vertex v = new Vertex(line);
                verticesMap.put(line,v);
                int randomX = Random.nextInt(500)+50;
                int randomY = Random.nextInt(200)+50;
                graphManager.addVertex(v, randomX, randomY, Graphemeui.VERTEX_SIZE);
            }
        }
        return true;
    }
    
    /**
     * returns the "DOT language" (http://en.wikipedia.org/wiki/DOT_language) 
     * representation of the graph
     *
     * @param graphManager
     *            the graph manager containing the graph
     * @param graphName
     *            name to use in the DOT code
     * @param directed
     *            true if the graph to be coded is directed
     * @param showWeights
     *            true if the graph should display edge waits
     */
    public static String getDot(GraphManager2d graphManager, String graphName, boolean directed, boolean showWeights){
        
        VertexDrawable vertexToDraw;
        String graphString;
        List<Vertex> mVertices;
        List<Edge> mEdges;
        int vertexStyle;
        String label;
        String arrow = "--";
        mVertices = graphManager.getUnderlyingGraph().getVertices();
        mEdges = graphManager.getUnderlyingGraph().getEdges();
        
        if(directed)graphString = "digraph "+graphName+" {";
        else graphString = "graph "+graphName+" {";
        
        // Set up the styles for the nodes
        for (Vertex thisVertex : mVertices) {
            
            vertexToDraw = graphManager.getVertexDrawable(thisVertex.getLabel());
            vertexStyle = vertexToDraw.getStyle();
            label = vertexToDraw.getLabel();
            graphString += cleanLabel(vertexToDraw.getLabel())+" ";

            if (vertexStyle == VertexDrawable.STROKED_TERM_STYLE){
                graphString += "[label=<<FONT COLOR=\"black\">"+label+
                    "</FONT>> fillcolor=gray, style=\"rounded,filled\", shape=box]";
            }else if (vertexStyle == VertexDrawable.STROKED_SQUARE_STYLE){
                graphString += "[label=<<FONT COLOR=\"black\">"+label+
                    "</FONT>> fillcolor=gray, style=\"filled\", shape=box]";
            }else if (vertexStyle == VertexDrawable.STROKED_DIAMOND_STYLE){
                graphString += "[label=<<FONT COLOR=\"black\">"+label+
                    "</FONT>> fillcolor=gray, style=\"filled\", shape=diamond]";
            }else if (vertexStyle == VertexDrawable.COLORED_FILLED_CIRCLE){
                graphString += "[fillcolor=black, style=\"filled\", shape=circle]";
            }else{
                graphString += "[label=<<FONT COLOR=\"white\">"+label+
                    "</FONT>> fillcolor=black, style=\"filled\", shape=circle]";
            }
            graphString += ";";
        }
        
        // Do the edges between the nodes
        if(directed) arrow = "->";
        for (Edge thisEdge : mEdges) {
            graphString += cleanLabel(thisEdge.getFromVertex().getLabel())+" "+arrow+" "+
                cleanLabel(thisEdge.getToVertex().getLabel());
            if(showWeights)graphString += "[label=\""+thisEdge.getWeight()+"\"]";
            graphString += ";";
        }
        
        graphString+="}";
        
        return graphString;
    }
    
    private static String cleanLabel(String label){
        label = label.replaceAll(" ", "_");
        return label;
    }
    
    
}

@@ -1693,54 +1693,101 @@
 s%5B0%5D
-))verticesMap.put(nodes%5B0%5D,new Vertex(
+.trim()))%7B%0D%0A                    verticesMap.put(nodes%5B0%5D.trim(),addEdge(graphManager,
 nodes%5B0%5D
 ));%0D
@@ -1782,21 +1782,47 @@
 nodes%5B0%5D
+.trim()
 ));%0D%0A
+                %7D%0D%0A
         
@@ -1869,57 +1869,130 @@
 s%5B1%5D
-))verticesMap.put(nodes%5B1%5D,new Vertex(nodes%5B1%5D));
+.trim()))%7B%0D%0A                    verticesMap.put(nodes%5B1%5D.trim(),addEdge(graphManager,nodes%5B1%5D.trim()));%0D%0A                %7D
 %0D%0A  
@@ -2223,35 +2223,56 @@
     
-Vertex v = new Vertex(
+verticesMap.put(line,addEdge(graphManager,
 line)
+)
 ;%0D%0A 
@@ -2286,46 +2286,174 @@
     
+%7D%0D%0A
     
-verticesMap.put(line,v);%0D%0A        
+    %7D%0D%0A        return true;%0D%0A    %7D%0D%0A    %0D%0A    private static Vertex addEdge(GraphManager2d graphManager,String label)%7B%0D%0A        Vertex v = new Vertex(label);%0D%0A
     
@@ -2491,32 +2491,24 @@
 t(500)+50;%0D%0A
-        
         int 
@@ -2542,24 +2542,16 @@
 0)+50;%0D%0A
-        
         
@@ -2624,34 +2624,8 @@
 );%0D%0A
-            %7D%0D%0A        %7D%0D%0A
     
@@ -2627,36 +2627,33 @@
 %0A        return 
-true
+v
 ;%0D%0A    %7D%0D%0A    %0D%0A

Fix import bug, for undeclared nodes