import uk.ac.bbk.dcs.automed.qproc.*;
import java.io.PrintStream;

/**
 * Command line program to print out an ASG graph to identify its
 * structure. An indentation is placed before the child of each node,
 * and the left branch is printed before the right branch.
 *                                                                               * Example of usage:
 *
 * java ASGExplore "[1 2 3 4]" "[{x} | {x} <- <<person>>]"
 * 
 */
public class ASGExplore {
  PrintStream out=System.out;
  int indent=0;
  private static final int MAX_INDENT=40;
  private static final String indents[]=new String[MAX_INDENT+1];

  static {
    StringBuffer sb=new StringBuffer();

    for (int i=0;i<MAX_INDENT;i++) {
      indents[i]=sb.toString();
      sb.append(' ');
    }

    indents[MAX_INDENT]=indents[MAX_INDENT-2]+'+';
  }

  private void printIndent() {
    out.print(indents[Math.min(indent,MAX_INDENT)]);
  }

  public void print(ASG g) throws Exception {
    print (g.root());
  }

  public void print(Cell c) throws Exception {
    printIndent();

    // Print the type of this cell with any value it might contain
    if (c==null)
      out.println("[Null]");
    else if (c.isApply())
      out.println("[Apply]");
    else if (c.isConsConstructor())
      out.println("[Cons]");
    else if (c.isFunction())
      out.println("[Function]="+c.text());
//    else if (c.isIdentifier())
 //     out.println("[Identifier]="+c.text());
    else if (c.isLambda())
      out.println("[Lambda]");
    else if (c.isConstant())
      out.println("[Constant]="+c.text());
    else if (c.isSpecial())
      out.println("[Special]="+c.text());
    else if (c.isVariable())
      out.println("[Variable]="+c.text());
    else if (c.isSysVariable())
      out.println("[SysVariable]="+c.text());
    else if (c.isConstructor())
      out.println("[Constructor]");
    else if (c.isNilConstructor())
      out.println("[Nil]");
    else if (c.isNum())
      out.println("[Num]="+c.text());
    else if (c.isScheme())
      out.println("[Scheme]="+c.data());

    // Then print the children
    indent+=1;
    
    if (c.l()!=null) {
      printIndent();
      print(c.l());
    }
    if (c.l()!=null) {
      printIndent();
      print(c.r());
    }  
    indent-=1;
  }

  public static void main(String args[]) throws Exception {
    String tests[]=args;

    //new String[]{
    //  "[{x,y} | {x,y} <- <<person,name,age>>; (=) 1 x]",
    //  "[1 2 3 4]"};

    for (int i=0;i<tests.length;i++) {
      ASGExplore e=new ASGExplore();
      e.out.println("*** Graph for "+tests[i]);
      e.print(new ASG(tests[i]));
    }
  }
}
