namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter17.Listing17_16
{
    using System.Collections.Generic;
    using Listing17_14;

    public class BinaryTree<T> :
      IEnumerable<T>
    {
        public BinaryTree(T value)
        {
            Value = value;
        }

        #region IEnumerable<T>
        public IEnumerator<T> GetEnumerator()
        {
            // Zwracanie elementu powiązanego z danym węzłem.
            yield return Value;

            // Przetwarzanie każdego elementu pary.
            foreach(BinaryTree<T> tree in SubItems)
            {
                if(tree != null)
                {
                    // Ponieważ każdy element z pary to drzewo,
                    // należy przejść po tym drzewie i zwrócić każdy element.
                    foreach (T item in tree)
                    {
                        yield return item;
                    }
                }
            }
        }
        #endregion IEnumerable<T>

        #region Składowe interfejsu IEnumerable
        System.Collections.IEnumerator
            System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        #endregion

        public T Value { get; }  // Automatycznie generowana właściwość z samym getterem (kod dla wersji C# 6.0).
        
        public Pair<BinaryTree<T>> SubItems { get; set; }
    }
}
