package edu.neu.ccs.demeterf.demfgen;

import edu.neu.ccs.demeterf.demfgen.classes.*;
import edu.neu.ccs.demeterf.lib.List;
import edu.neu.ccs.demeterf.lib.ident;
import edu.neu.ccs.demeterf.*;

/** Generate a Dot/Graphviz representation of the class dictionary */
public class GraphGen{
    static String nodeAttr = " [shape=box,height=0.25];\n";

    static void p(String s){{ System.out.print(s); }}
    static void pe(String s){{ System.err.print(s); }}
    public static void genGraph(List<CDFile> CD, String title){
        p("digraph \""+title+"\" {\n");
        p("   node "+nodeAttr);
        List<String> tps = Factory.newTraversal(new GGen(), Control.builtins(Impl.class,Bound.class))
                           .traverseList_TypeDef_(DemFGenMain.justTypes(CD));
        //p(tps.toString(nodeAttr,"   ")+GGen.choose(tps,nodeAttr,""));
        p("}\n");
    }
}

class GGen extends ID{
    GGen(){ }
    String combine(TypeUse u, ident id, List<String> par){
        return ""+id;//+(par.isEmpty()?"":"("+par.toString(", ", "")+")");    
    }
    String combine(Field f, ident n, String t){
        return "\""+t+"\" [dir=forward,arrowhead=normal,arrowtail=none,label=\""+n+"\"]";
        //"dir=back,arrowhead=none,arrowtail=empty");
    }
    String quote(ident id, List<String> par){
        return "\""+id+"\"";//+(par.isEmpty()?"":"("+par.toString(", ", "")+")")+"\"";
    }
    String combine(ClassDef c, DoGen g, ident id, List<String> par, List<String> es, List<String> fs){
        String sum = "\" [dir=back,arrowhead=none,arrowtail=empty];\n";
        GraphGen.p(fs.toString(";\n","   "+quote(id,par)+" -> ")+choose(fs,";\n",""));
        GraphGen.p(es.toString(sum,"   "+quote(id,par)+" -> \"")+choose(es,sum,""));
        return ""+id;
            
    }
    //List<String> combine(SumType s, String prfx, List<String> tps, String pstfx){ return tps; }
    String combine(IntfcDef itf, DoGen g, ident id, List<String> par, List<String> es){
        String sum = "\" [dir=back,arrowhead=none,arrowtail=empty];\n";
        GraphGen.p(es.toString(sum,"   "+quote(id,par)+" -> \"")+choose(es,sum,""));
        return ""+id;
    }
    String combine(NameDef n, ident i, Bound b){ return ""+i; }
    String combine(TypeUse n, ident i, String s){ return ""+i; }
    List<String> combine(TypeDefParams p, List<String> l){ return l; }
    List<String> combine(TypeUseParams p, List<String> l){ return l; }
    
    String combine(LitToken t){ return ""; }
    String combine(Syntax s){ return ""; }
    List<String> combine(ConsList l, String f, List<String> r){
        return (f.length()==0)?r:r.push(f);
    }
    
    List<String> combine(EmptyList e){ return List.<String>create(); }    
    List<String> combine(List<?> e){ return List.<String>create(); }
    static String choose(List<?> l, String cons, String empty){
        if(!l.isEmpty()) return cons;
        return empty;
    }
    DoGen combine(DoGen g){ return g; }
}