package com.dlvr.continuum.collect;


import java.util.LinkedHashSet;
import java.util.Set;

/**
 * Directed, Acyclic graph
 *
 * Created by zack on 3/11/16.
 */
public class Tree<V> implements Visitable<V> {

    private final Tree<V> parent;

    private final Set<Tree<V>> nodes = new LinkedHashSet<>();

    public V data;

    public Tree(V data) {
        this(null, data);
    }

    public Tree(Tree<V> parent, V data) {
        this.parent = parent;
        this.data = data;
    }

    public Tree<V> child(V data) {
        for (Tree<V> child : nodes) {
            if (child.data.equals(data)) {
                return child;
            }
        }

        return child(new Tree<>(this, data));
    }

    public Tree<V> child(Tree<V> child) {
        nodes.add(child);
        return child;
    }

    public Tree<V> parent() {
        return parent;
    }

    @Override
    public String toString() {
        String s = "";
        if (nodes != null) s += nodes.toString();
        return s;
    }

    public void accept(Visitor<V> visitor) {
        visitor.visitData(this, data);
        for (Tree<V> child : nodes) {
            Visitor<V> childVisitor = visitor.visitTree(child);
            child.accept(childVisitor);
        }
    }

    static class IndentVisitor<V> implements Visitor<V> {

        private final int indent;

        IndentVisitor(int indent) {
            this.indent = indent;
        }

        @Override
        public Visitor<V> visitTree(Tree<V> tree) {
            return new IndentVisitor<>(indent + 2);
        }

        @Override
        public void visitData(Tree<V> parent, V data) {
            for (int i = 0; i < indent; i++) {
                System.out.print(" ");
            }

            System.out.println(data);
        }
    }
}

@@ -1001,32 +1001,136 @@
 eturn s;%0A    %7D%0A%0A
+    public void breadthFirst(Consumer%3CV%3E consumer) %7B%0A        accept(new BreadthFirst(consumer));%0A    %7D%0A%0A
     public void 
@@ -1154,24 +1154,24 @@
  visitor) %7B%0A
-
         visi
@@ -1291,32 +1291,83 @@
 sitTree(child);%0A
+            if (childVisitor != null) // stop?%0A    
             chil
@@ -1390,16 +1390,16 @@
 sitor);%0A
-
         
@@ -1924,24 +1924,24 @@
 ntln(data);%0A
-
         %7D%0A  
@@ -1943,11 +1943,833 @@
  %7D%0A    %7D
+%0A%0A    public class BreadthFirst implements Visitor%3CV%3E %7B%0A%0A        private final Consumer%3CV%3E consumer;%0A        private int level;%0A%0A        public BreadthFirst(Consumer%3CV%3E consumer) %7B%0A            this(0, consumer);%0A        %7D%0A%0A        public BreadthFirst(int level, Consumer%3CV%3E consumer) %7B%0A            this.level = level;%0A            this.consumer = consumer;%0A        %7D%0A%0A        @Override%0A        public Visitor%3CV%3E visitTree(Tree%3CV%3E tree) %7B%0A            boolean cont = consumer.visit(level, tree);%0A            return cont ? new BreadthFirst(level + 1, consumer) : null;%0A        %7D%0A        @Override%0A        public void visitData(Tree%3CV%3E parent, V data) %7B%0A            consumer.visit(level, parent);%0A        %7D%0A    %7D%0A%0A    @FunctionalInterface%0A    public interface Consumer%3CV%3E %7B%0A        boolean visit(int level, Tree%3CV%3E tree);%0A    %7D
 %0A%7D%0A

implement breadth first search