// ========================================================================
//
// Copyright (C) 2016-2017 MARC CHEVALDONNE
//                         marc.chevaldonne.free.fr
//
// Module        : Program.cs
// Author        : Marc Chevaldonné
// Creation date : 2016-09-26
//
// ========================================================================

using static System.Console;
using System.Collections.Generic;
using static ex_021_001_patternComposite.Component;

namespace ex_021_001_patternComposite
{
    interface IComponent
    {
        string Nom { get; set; }

        void Operation(string tab);
    }

    class Component : IComponent
    {
        internal const string TAB = " ";

        public string Nom
        {
            get;
            set;
        }

        public void Operation(string tab = TAB)
        {
            WriteLine($"{tab}Je suis {Nom}, un {GetType().Name}, et je réalise mon opération");
        }
    }

    class Composite : IComponent
    {
        public string Nom
        {
            get;
            set;
        }

        List<IComponent> mChildren = new List<IComponent>();

        public void AddRange(params IComponent[] children)
        {
            mChildren.AddRange(children);
        }

        public void Operation(string tab = TAB)
        {
            WriteLine($"{tab}Je suis {Nom}, un {GetType().Name}, et je débute mon opération");
            WriteLine($"{tab}Je suis {Nom}, un {GetType().Name}, et je fais travailler mes enfants");
            foreach (IComponent child in mChildren)
            {
                child.Operation(tab + TAB);
            }
            WriteLine($"{tab}Je suis {Nom}, un {GetType().Name}, et j'ai terminé mon opération");
        }
    }

    class Program
    {
        //N6 ---> N5 ---> N4 --> N1
        //    |       |
        //    |       --> N2
        //    |
        //    --> N3
        static void Main(string[] args)
        {
            OutputEncoding = System.Text.Encoding.UTF8;

            Component noeud1 = new Component() { Nom = "Noeud1" };
            Component noeud2 = new Component() { Nom = "Noeud2" };
            Component noeud3 = new Component() { Nom = "Noeud3" };
            Composite noeud4 = new Composite() { Nom = "Noeud4" };
            Composite noeud5 = new Composite() { Nom = "Noeud5" };
            Composite noeud6 = new Composite() { Nom = "Noeud6" };
            noeud6.AddRange(noeud5, noeud3);
            noeud5.AddRange(noeud4, noeud2);
            noeud4.AddRange(noeud1);

            noeud1.Operation();
            ReadLine();
            Clear();
            noeud4.Operation();
            ReadLine();
            Clear();
            noeud5.Operation();
            ReadLine();
            Clear();
            noeud6.Operation();
        }
    }
}
