/* Mapping Visitor
   A second-level framework, a part of the Binary Tree Traversal Framework
   H. Conrad Cunningham
   Version #1: 15 October 2008
   Version #2: 29 April 2010   Separate each level into separate files

This is a second-level framework that introduces a Mapping Visitor
that is a specialization and extension of the BinTreeVisitor feature
of the top-level framework.  

A concrete UnaryOp object will be needed for an application of this
framework.

123456789012345678901234567890123456789012345678901234567890123456789012345678
*/


 /* Class MappingVisitor is a concrete binary tree visitor class that
   implements a map operation over BinTree's.  That is, it applies a
   unary operator to every value stored in the tree. This has the
   ConcreteVisitor role in the Visitor design pattern.  It also has
   the role Context in the Strategy design pattern.  Method visit is
   a template method for the Mapping Visitor second-level
   framework.
*/

class MappingVisitor(op: UnaryOp) extends BinTreeVisitor {

  // attributes
  private var vop = op

  // mutators
  def setMapOp(op: UnaryOp) { vop = op }

  // visitor hook implementations
  def visit(t: Node) {
    t.setValue(vop.apply(t.getValue))
    val l = t.getLeft
    if (l != null) l.accept(this)
    val r = t.getRight
    if (r != null) r.accept(this)
  }

  def visit(t: NilTree.type) { }
}


/* Trait UnaryOp is a Strategy base interface that defines the hook
   method used by the MappingVisitor visit method.
*/

abstract trait UnaryOp {   
  def apply(v: Any): Any
}
