package brn.util;


/**
 * DOT and Co support.
 */
public abstract class Graphviz {

  public final static double DEFAULT_SCALE = 100.0;

  public double x_scale;
  public double y_scale;

  StringBuffer dotGraph;

  public Graphviz(double x_scale, double y_scale) {
    dotGraph = new StringBuffer();
    this.x_scale = x_scale;
    this.y_scale = y_scale;
  }

  public String getText() {
    return dotGraph.toString();
  }

  protected String getColor(int ch) {
    switch (ch) {
      case 0:
        return "gold";
      case 1:
        return "cadetblue1";
      case 2:
        return "coral";
      case 3:
        return "darkolivegreen2";
      case 4:
      default:
        return "aliceblue";
    }
  }


  /**
   * Used to print the network with multiple channels.
   * <p/>
   * Usage:  neato -Tpng foo.graph > foo.png
   */
  public static class Graph extends Graphviz {

    public Graph(String filename) {
      this(filename, DEFAULT_SCALE, DEFAULT_SCALE);
    }

    public Graph(String filename, double x_scale, double y_scale) {
      super(x_scale, y_scale);
      dotGraph.append("graph {\n");
    }

    public void addNode(String id, double posX, double posY, int color) {
      dotGraph.append(id).append(" [ pos = \"").append(posX / x_scale)
              .append(",").append(posY / y_scale).append("!\" ")
              .append("color = \"").append(getColor(color)).append("\" style = \"filled\"")
              .append(" ];\n");
    }

    public void addLink(String from, String to) {
      dotGraph.append('"').append(from).append('"').append(" -- ")
              .append('"').append(to).append('"').append("\n");
    }

//    public void write(String filename) {
//      dotGraph.append("}");
//      super.write(filename);
//    }

    public String getText() {
      return super.getText() + "}";
    }
  }

  /**
   * Used to print the network with multiple channels.
   * <p/>
   * Usage:  dot -Tpng foo.graph > foo.png
   */
  public static class DiGraph extends Graphviz {

    public DiGraph() {
      this(DEFAULT_SCALE, DEFAULT_SCALE, false);
    }

    public DiGraph(double x_scale, double y_scale, boolean splines) {
      super(x_scale, y_scale);
      dotGraph.append("digraph {\n");
      if (splines)
        dotGraph.append("graph [splines=true]\n");
    }

    public void addNode(String id, int color) {
      dotGraph.append('"').append(id).append('"').append(" [ ").append("color = \"")
              .append(getColor(color)).append("\" style = \"filled\"").append(" ];\n");
    }

    public void addNode(String id, double posX, double posY, int color) {
      dotGraph.append('"').append(id).append('"').append(" [ pos = \"").append(posX / x_scale)
              .append(",").append(posY / y_scale).append("!\" ")
              .append("color = \"").append(getColor(color)).append("\" style = \"filled\"")
              .append(" ];\n");
    }

    public void addLink(String from, String to, int width) {

      int widthSize = (int) (Math.log(width) / Math.log(10.0)) + 1;

      dotGraph.append('"').append(from).append('"').append(" -> ")
              .append('"').append(to).append('"').append("[ label=")
              .append('"').append(width).append('"')
              .append(" style=\"setlinewidth(").append(widthSize).append(")\"")
              .append("]\n");

    }

    public void addLink(String from, String to, int width, int color) {

      int widthSize = (int) (Math.log(width) / Math.log(10.0)) + 1;

      dotGraph.append('"').append(from).append('"').append(" -> ")
              .append('"').append(to).append('"').append("[ label=")
              .append('"').append(width).append('"')
              .append(" style=\"setlinewidth(").append(widthSize).append(")\"")
              .append(" color = \"").append(getColor(color)).append("\"")
              .append("]\n");

    }

    public void addLink(String from, String to, String label) {
      dotGraph.append('"').append(from).append('"').append(" -> ")
              .append('"').append(to).append('"').append("[ label=")
              .append('"').append(label).append('"').append("]\n");
    }

//    public void write(String filename) {
//      dotGraph.append("}");
//      super.write(filename);
//    }

    public String getText() {
      return super.getText() + "}";
    }
  }

}
