using System;
using System.Collections.Generic;
using System.Linq;
using static System.Console;
using System.Text;
using System.Threading.Tasks;

namespace ex_031_008_LINQ_projecting
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Nounours> nounours = new List<Nounours> {
                                      new Nounours("mouton", new DateTime(2009, 09, 16), 1000),
                                      new Nounours("ours", new DateTime(2009, 08, 15), 2000),
                                      new Nounours("chat", new DateTime(2009, 07, 14), 1000),
                                      new Nounours("chien", new DateTime(2009, 06, 13), 500),
                                      new Nounours("lapin", new DateTime(2009, 05, 12), 500),
                                      new Nounours("chat", new DateTime(2009, 07, 14), 2000),
                                      new Nounours("macaque", new DateTime(2009, 04, 11), 500)};

            //////////////
            //Projecting//
            //////////////
            WriteLine("Projecting");

            //////////////
            //SELECT    //
            //////////////

            //Select : chaque élément d'un type T1 est transformé en un autre élément d'un type T2
            //Dans cet exemple, chaque nounours est transformé en un entier correspondant au nombre de lettres dans le nom du Nounours (ok ça ne sert à rien...)
            WriteLine("Select");
            IEnumerable<int> selected = nounours.Select(n => n.Nom.Length);
            foreach (int i in selected)
            {
                WriteLine(i);
            }
            WriteLine();

            //idem en Query Syntax
            WriteLine("Select");
            IEnumerable<int> selectedQS = from n in nounours
                                          select n.Nom.Length;
            foreach (int i in selectedQS)
            {
                WriteLine(i);
            }
            WriteLine();

            //Select : avec un type anonyme
            WriteLine("Select + type anonyme");
            var selectedAnonymous = nounours.Select(n => new { Nom = n.Nom, AnnéeNaissance = n.Naissance.Year, MoisNaissance = n.Naissance.Month, TailleDuNom = n.Nom.Length });
            foreach (var a in selectedAnonymous)
            {
                WriteLine(a);
            }
            WriteLine();

            //Select : avec un type anonyme
            WriteLine("Select + type anonyme");
            var selectedAnonymousQS = from n in nounours
                                      select new { Nom = n.Nom, AnnéeNaissance = n.Naissance.Year, MoisNaissance = n.Naissance.Month, TailleDuNom = n.Nom.Length };
            foreach (var a in selectedAnonymousQS)
            {
                WriteLine(a);
            }
            WriteLine();

            //indexed projection
            WriteLine("Select + index");
            var selectedIndexed = nounours.Select((n, i) => $"{i + 1}. {n.Nom}");
            foreach (var s in selectedIndexed)
            {
                WriteLine(s);
            }
            WriteLine();


            //////////////
            //SELECTMANY//
            //////////////

            //SelectMany concatène des séquences en une seule séquence
            //SelectMany peut donc être utilisé pour :
            //  - applatir des collections imbriquées
            //  - rejoindre deux collections en une seule séquence

            //SelectMany : exemple 1 : applatir des collections
            WriteLine("SelectMany");
            string[] phrases = { @"Le premier lundi du mois d'avril 1625, le bourg de Meung, où naquit l'auteur du Roman de la Rose,
                            semblait être dans une révolution aussi entière que si les huguenots en fussent venus faire une seconde Rochelle.",
                            @"Plusieurs bourgeois, voyant s'enfuir les femmes du côté de la Grand-Rue, entendant les enfants crier sur le seuil des portes,
                            se hâtaient d'endosser la cuirasse, et, appuyant leur contenance quelque peu incertaine d'un mousquet ou d'une pertuisane,
                            se dirigeaient vers l'Hôtellerie du Franc - Meunier, devant laquelle s'empressait, en grossissant de minute en minute, un groupe compact,
                            bruyant et plein de curiosité.",
                            @"Arrivé là, chacun put voir et reconnaître la cause de cette humeur.",
                            @"Un jeune homme... traçons son portrait d'un seul trait de plume : figurez- vous don Quichotte à dix-huit ans ; don Quichotte décorselé,
                            sans haubert et sans cuissards ; don Quichotte revêtu d'un pourpoint de laine dont la couleur bleue s'était transformée en une nuance insaisissable de lie de vin
                            et d'azur céleste. Visage long et brun ; la pommette des joues saillante, signe d'astuce ; les muscles maxillaires énormément développés,
                            indice infaillible auquel on reconnaît le Gascon, même sans béret, et notre jeune homme portait un béret orné d'une espèce de plume ;
                            l'oeil ouvert et intelligent ; le nez crochu, mais finement dessiné ; trop grand pour un adolescent, trop petit pour un homme fait,
                            et qu'un oeil peu exercé eût pris pour un fils de fermier en voyage, sans la longue épée qui, pendue à un baudrier de peau,
                            battait les mollets de son propriétaire quand il était à pied, et le poil hérissé de sa monture quand il était à cheval.",
                            @"Car notre jeune homme avait une monture, et cette monture était même si remarquable, qu'elle fut remarquée : c'était un bidet du Béarn,
                            âgé de douze ou quatorze ans, jaune de robe, sans crins à la queue, mais non pas sans javarts aux jambes, et qui, tout en marchant la tête plus bas que les genoux,
                            ce qui rendait inutile l'application de la martingale, faisait encore également ses huit lieues par jour.",
                            @"Malheureusement les qualités de ce cheval étaient si bien cachées sous son poil étrange et son allure incongrue,
                            que dans un temps où tout le monde se connaissait en chevaux, l'apparition du susdit bidet à Meung,
                            où il était entré il y avait un quart d'heure à peu près par la porte de Beaugency, produisit une sensation dont la défaveur rejaillit jusqu'à son cavalier." };

            var avecSelect = phrases.Select(phrase => phrase.Split());
            foreach (var p in avecSelect)
            {
                WriteLine(p);
            }

            var avecSelectMany = phrases.SelectMany(phrase => phrase.ToLower().Split())
                                         .Where(mot => !String.IsNullOrWhiteSpace(mot))
                                         .Distinct()
                                         .OrderBy(mot => mot);
            foreach (var p in avecSelectMany)
            {
                WriteLine(p);
            }

            //SelectMany : cross product avec un selectmany en query syntax
            WriteLine("SelectMany et cross product");
            var affrontements = from n1 in nounours
                                from n2 in nounours
                                where n1.Nom != n2.Nom
                                select $"{n1.Nom} vs. {n2.Nom}";
            foreach (var a in affrontements)
            {
                WriteLine(a);
            }

        }
    }
}
