package baem;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Baum<E> {
	boolean isEmpty=false;
	E element;
	List<Baum<E>> childNodes;
	public Baum(E hd, List<Baum<E>> childNodes) {
		super();
		this.element = hd;
		this.childNodes = childNodes;
	}
	
	public Baum() {
		this(null,null);
		isEmpty=true;
	}
	int groesse() {
      return isEmpty
		? 0
		: 1  // Wurzel
		   + // Summe der Größen der Kinder
		    childNodes
		   .parallelStream()
		   .reduce(0, (Integer r, Baum<E> child) -> r+child.groesse(),(x,y)->x+y);
	}
	int groesse2() {
		if (isEmpty) return 0;
		var result  = 0;
		for (var child:childNodes)
			result = result + child.groesse2();
		return 1+result;
	}
	Set<E> elemente(){
		var result = Collections.synchronizedSet(new HashSet<E>());
		elemente2(result);
		return result;
	}
	void elemente(Set<E> result){
		if (isEmpty) return;
		result.add(element);
		for (var child:childNodes)
			child.elemente(result);
	}
	void elemente2(Set<E> result){
		if (isEmpty) return;
		result.add(element);
		childNodes.parallelStream().forEach((child)->child.elemente2(result));
		//for (var child:childNodes)
		//	child.elemente(result);
	}
	public void toString(StringBuffer buffer) {
		if (isEmpty) {
			buffer.append("Emptytree[]");
			return;
		}
		buffer.append("Baum("+element+", ");
		for (var child:childNodes)
			child.toString(buffer);
	}
	
	@Override
	public String toString() {
		var result = new StringBuffer();
		toString(result);
		return result.toString();
	}
	
	public static void main(String[] args) {
		var baum = new Baum<>("Elizabeth",List.of
				(new Baum<>("Charles",List.of
					(new Baum<>("William",List.of())
					,new  Baum<>("Harry",List.of())
					))
				,new Baum<>("Anne",List.of())
				,new Baum<>("Edward",List.of())
				,new Baum<>("Andrew",List.of())
				));
		System.out.println(baum.groesse());
		System.out.println(baum.groesse2());
		System.out.println(baum.elemente());
		var baum2 = new Baum<>("Olaf1",List.of
				(new Baum<>("Olaf2",List.of
					(new Baum<>("Olaf",List.of())
					,new  Baum<>("Olaf",List.of())
					))
				,new Baum<>("Olaf2",List.of(new Baum<>("Olaf",List.of())
						,new  Baum<>("Olaf",List.of())))
				,new Baum<>("Olaf2",List.of(new Baum<>("Olaf",List.of())
						,new  Baum<>("Olaf",List.of())))
				,new Baum<>("Olaf2",List.of(new Baum<>("Olaf",List.of())
						,new  Baum<>("Olaf",List.of())))
				));
		System.out.println(baum2.elemente());

	}
}
