﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Collections;

namespace Linq {

    class Program {

        static IEnumerable<Customer> customers;

        static void Main(string[] args) {

            customers = new[]       {
                new Customer{ FirstName = "Luka", LastName="Abrus", Age = 41},
                new Customer{ FirstName = "Syed", LastName="Abbas", Age = 23},
                new Customer{ FirstName = "Keith", LastName="Harris", Age = 59},
                new Customer{ FirstName = "David", LastName="Pelton", Age = 25},
                new Customer{ FirstName = "John", LastName="Peoples", Age = 37},
                new Customer{ FirstName = "Toni", LastName="Poe", Age = 29},
                new Customer{ FirstName = "Jeff", LastName="Price", Age = 74}
            };

            //One();
            //AnonymousType();
            //Where();
            //Order();
            //GroupBy();
            Dynamic();

        }

        static void One() {

            List<string> customerLastNames = new List<string>();

            foreach (Customer customer in customers) {
                customerLastNames.Add(customer.LastName);
            }

            //IEnumerable<string> customerLastNames = customers.Select(cust => cust.LastName);

            foreach (string name in customerLastNames) {
                Console.WriteLine(name);
            }

        }

        static void AnonymousType() {

            var customerNames = customers.Select(cust => new { FirstName = cust.FirstName, LastName = cust.LastName });

            foreach (var item in customerNames) {
                Console.WriteLine("{0} {1}", item.FirstName, item.LastName);
            }

        }

        static void Where() {

            var customerLastNames = customers.Where(cust => cust.Age > 25).
            Select(cust => cust.LastName);

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

        }

        static void Order() {

            var sortedCustomers = customers.OrderBy(cust => cust.FirstName);

            foreach (var item in sortedCustomers) {
                Console.WriteLine("{0} {1}", item.FirstName, item.Age.ToString());
            }

            sortedCustomers = customers.OrderByDescending(cust => cust.FirstName);
            Console.WriteLine("---------------------");

            foreach (var item in sortedCustomers) {
                Console.WriteLine("{0} {1}", item.FirstName, item.Age.ToString());
            }

            sortedCustomers = customers.OrderBy(cust => cust.FirstName).ThenByDescending(cust => cust.Age);


        }

        static void GroupBy() {

            Console.WriteLine("Count:{0}\n\rAverage age:{1}\n\rLowest:{2}\n\rHighest:{3}",
                              customers.Count(),
                              customers.Average(cust => cust.Age),
                              customers.Min(cust => cust.Age),
                              customers.Max(cust => cust.Age));


            var customersGroupedByAgeRange = customers.GroupBy(cust => {

                if (cust.Age < 20)
                    return "age < 20";
                if (cust.Age >= 20 && cust.Age < 40)
                    return "age >= 20 and < 40";
                if (cust.Age >= 40 && cust.Age < 60)
                    return "age >= 40 and < 60";
                if (cust.Age >= 60)
                    return "age >= 60";
                return "Error";

            });

            foreach (var cust in customersGroupedByAgeRange.OrderBy(cust => cust.Key)) {
                Console.WriteLine("{0}:{1}", cust.Key, cust.Count());
            }


        }

        static void Dynamic() {

            List<Student> students = new List<Student>() {  
              new Student{Id = 10, Registry=100, Name="Paulo"},   
              new Student{Id = 20, Registry=200, Name="Pedro"},   
              new Student{Id = 50, Registry=300, Name="Felipe"},   
              new Student{Id = 60, Registry=400, Name="Lucas"} 
            };

            Expression<Func<Student,bool>> expression = DynamicLinq.MakeExpression(1, 50);
            IEnumerable resultStudents = students.Where(expression.Compile());

            foreach (Student item in resultStudents) {
                Console.WriteLine(item.Name);
            }

        }

    }

}