/* Binary Tree Traversal Framework Applications Test
   Applications of the various second-level frameworks
   H. Conrad Cunningham
   Version #1: 15 October 2008
   Version #2: 29 April 2010   Separate each level into a separate file

123456789012345678901234567890123456789012345678901234567890123456789012345678
*/


/* Parenthesized traversal strategy for Euler Tour Traversal Framework */

class VisitParen extends EulerStrategy {
  def visitLeft(ts: Any, t: BinTree)   = 
    ts.asInstanceOf[String] + "("
  def visitBottom(ts: Any, t: BinTree) = 
    ts.asInstanceOf[String] + t.getValue.asInstanceOf[String]
  def visitRight(ts: Any, t: BinTree)  = 
    ts.asInstanceOf[String] + ")" 
  def visitNilTree(ts: Any, t: BinTree) = 
    ts.asInstanceOf[String] + "(NIL)"
}


/* UnaryOp strategy for MappingVisitor Framework.  This "zaps" the
   values to be stars.
*/

class AllStars extends UnaryOp {
  def apply(v: Any) = "*"
}

/* This concrete BreadthFirstStrategy appends the values onto a String. */

class Appender extends BreadthFirstVisitStrategy {

  def visitNode(ts: Any, t: BinTree)     =
    ts.asInstanceOf[String] + "|" + t.getValue.asInstanceOf[String]

  def visitNilTree (ts: Any, t: BinTree) = ts
}


/*  Toward a test program.  Minimal testing so far.  */

object BinTreeTest {

  def main(args: Array[String]) {   
    val vs = new VisitParen
    val v  = new EulerTourVisitor(vs,"START>")

    println("Euler parenthesized traversal")
    println("Input is NilTree")
    NilTree.accept(v)
    println(v.getResult.asInstanceOf[String])
    println(" ")
    
    v.reinitResult
    val t = new Node("1",new Node("2",NilTree,new Node("3",NilTree,NilTree)),
	                 new Node("4",NilTree,NilTree) ) 
    println("Input is " + t)
    t.accept(v)
    println(v.getResult.asInstanceOf[String])
    println(" ")

    println("Breadth first traversal -- appender");
    val bfs = new Appender
    val bfv = new BreadthFirstVisitor(bfs,"");
    t.accept(bfv);
    println(bfv.getResult.asInstanceOf[String])

    println("Mapping Visitor -- allstars");
    val mv = new MappingVisitor(new AllStars)
    t.accept(mv)
    println("Result is: " + t.asInstanceOf[Node])
    v.setResult("")
    t.accept(v)
    println(v.getResult.asInstanceOf[String])
  }
}
