// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
namespace ICSharpCode.TreeView
{
	/// 
	/// Static helper methods for traversing trees.
	/// 
	static class TreeTraversal
	{
		/// 
		/// Converts a tree data structure into a flat list by traversing it in pre-order.
		/// 
		/// The root element of the tree.
		/// The function that gets the children of an element.
		/// Iterator that enumerates the tree structure in pre-order.
		public static IEnumerable PreOrder(T root, Func> recursion)
		{
			return PreOrder(new T[] { root }, recursion);
		}
		
		/// 
		/// Converts a tree data structure into a flat list by traversing it in pre-order.
		/// 
		/// The root elements of the forest.
		/// The function that gets the children of an element.
		/// Iterator that enumerates the tree structure in pre-order.
		public static IEnumerable PreOrder(IEnumerable input, Func> recursion)
		{
			Stack> stack = new Stack>();
			try {
				stack.Push(input.GetEnumerator());
				while (stack.Count > 0) {
					while (stack.Peek().MoveNext()) {
						T element = stack.Peek().Current;
						yield return element;
						IEnumerable children = recursion(element);
						if (children != null) {
							stack.Push(children.GetEnumerator());
						}
					}
					stack.Pop().Dispose();
				}
			} finally {
				while (stack.Count > 0) {
					stack.Pop().Dispose();
				}
			}
		}
	}
}