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

namespace Operators
{
    class Examples49_57
    {
        public static void GroupingQueryExpression()
        {
            // Listing 10-49
            var subjectGroups = from course in Course.Catalog
                                group course by course.Category;

            foreach (var group in subjectGroups)
            {
                Console.WriteLine("Kategoria: " + group.Key);
                Console.WriteLine();

                foreach (var course in group)
                {
                    Console.WriteLine(course.Title);
                }
                Console.WriteLine();
            }
        }

        public static void UseGroupOperatorDirectly()
        {
            // Listing 10-50
            var subjectGroups = Course.Catalog.GroupBy(course => course.Category);

            foreach (var group in subjectGroups)
            {
                Console.WriteLine("Kategoria: " + group.Key);
                Console.WriteLine();

                foreach (var course in group)
                {
                    Console.WriteLine(course.Title);
                }
                Console.WriteLine();
            }
        }

        private static void ShowStringGroups(IEnumerable<IGrouping<string, string>> groups)
        {
            foreach (var group in groups)
            {
                Console.WriteLine("Kategoria: " + group.Key);
                Console.WriteLine();

                foreach (var item in group)
                {
                    Console.WriteLine(item);
                }
                Console.WriteLine();
            }
        }

        public static void GroupWithItemProjection()
        {
            // Listing 10-51
            var subjectGroups = from course in Course.Catalog
                                group course.Title by course.Category;

            ShowStringGroups(subjectGroups);
        }

        public static void DirectGroupWithItemProjection()
        {
            // Listing 10-52
            var subjectGroups = Course.Catalog
                .GroupBy(course => course.Category, course => course.Title);

            ShowStringGroups(subjectGroups);
        }

        public static void GroupQueryWithGroupProjection()
        {
            // Listing 10-53
            var subjectGroups = from course in Course.Catalog
                                group course by course.Category into category
                                select string.Format("Liczba kursów w kategorii '{0}': {1}.",
                                    category.Key, category.Count());

            subjectGroups.Show();
        }

        public static void DirectGroupWithGroupProjection()
        {
            // Listing 10-54
            IEnumerable<string> subjectGroups = Course.Catalog
                .GroupBy(course => course.Category)
                .Select(category => string.Format("Liczba kursów w kategorii '{0}': {1}.",
                                                  category.Key, category.Count()));

            subjectGroups.Show();
        }

        public static void GroupWithKeyAndGroupProjections()
        {
            // Listing 10-55
            IEnumerable<string> subjectGroups = Course.Catalog.GroupBy(
                course => course.Category,
                (category, courses) => string.Format("Liczba kursów w kategorii '{0}': {1}.",
                                                     category, courses.Count()));

            subjectGroups.Show();
        }

        public static void GroupWithKeyItemAndGroupProjections()
        {
            // Listing 10-56
            IEnumerable<string> subjectGroups = Course.Catalog.GroupBy(
                course => course.Category,
                course => course.Title,
                (category, titles) =>
                     string.Format("Kategoria '{0}' zawiera {1} kursy: {2}",
                                   category, titles.Count(), string.Join(", ", titles)));

            subjectGroups.Show();
        }

        public static void CompositeGroupKey()
        {
            // Listing 10-57
            var bySubjectAndYear = from course in Course.Catalog
                                   group course by new { course.Category, course.PublicationDate.Year };
            foreach (var group in bySubjectAndYear)
            {
                Console.WriteLine("{0} ({1})", group.Key.Category, group.Key.Year);
                foreach (var course in group)
                {
                    Console.WriteLine(course.Title);
                }
            }
        }
    }
}
