/*
    Element-Operator
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace _10LINQBasics
{
    public class Customer
    {
        public string customerID;
        public string companyName;
        public string country;

        public Order[] orders;
    }

    public class Order
    {
        public int orderID;
        public DateTime orderDate;
        public string shipCountry;

        public int productID;
    }

    public class Product
    {
        public int productID;
        public double unitPrice;
        public string name;
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Product p1 = new Product { productID = 31, unitPrice = 12.5, name = "Gorgonzola Telino" };
            Product p2 = new Product { productID = 52, unitPrice = 7.0, name = "Filo Mix" };
            Product p3 = new Product { productID = 63, unitPrice = 43.9, name = "Vegie-spread" };
            Product p4 = new Product { productID = 48, unitPrice = 12.7, name = "Chocolade" };
            Product p5 = new Product { productID = 43, unitPrice = 46.0, name = "Ipoh Coffee" };
            Product p6 = new Product { productID = 37, unitPrice = 26.0, name = "Gravad lax" };

            Product p7 = new Product { productID = 9999, unitPrice = 146.45, name = "new Product" };

            Product[] products = new Product[] { p1, p2, p3, p4, p5, p6, p7 };

            //Orders
            Order[] orderALFKI = new Order[]
                {
                    new Order {orderID = 10643, orderDate = DateTime.Parse("25.08.1997"), shipCountry = "Germany", productID = 31},
                    new Order {orderID = 10692, orderDate = DateTime.Parse("03.10.1997"), shipCountry = "Germany", productID = 63},
                    new Order {orderID = 10702, orderDate = DateTime.Parse("13.10.1997"), shipCountry = "Germany", productID = 48},

                };

            Order[] orderBERGS = new Order[]
                {
                    new Order {orderID = 10278, orderDate = DateTime.Parse("12.08.1996"), shipCountry = "Sweden", productID = 48},
                    new Order {orderID = 10280, orderDate = DateTime.Parse("14.08.1996"), shipCountry = "Sweden", productID = 52},
                    new Order {orderID = 10384, orderDate = DateTime.Parse("16.12.1996"), shipCountry = "Sweden", productID = 48},

                };

            Order[] orderDUMON = new Order[]
                {
                    new Order {orderID = 10311, orderDate = DateTime.Parse("20.09.1996"), shipCountry = "France", productID = 37},
                    new Order {orderID = 10609, orderDate = DateTime.Parse("24.07.1997"), shipCountry = "France", productID = 31},
                    new Order {orderID = 10683, orderDate = DateTime.Parse("26.09.1997"), shipCountry = "France", productID = 43},
                };

            Order[] orderLEHMS = new Order[]
                {
                    new Order {orderID = 10279, orderDate = DateTime.Parse("13.08.1996"), shipCountry = "Germany", productID = 37},
                    new Order {orderID = 10284, orderDate = DateTime.Parse("19.08.1996"), shipCountry = "Germany", productID = 43},
                    new Order {orderID = 10343, orderDate = DateTime.Parse("31.10.1996"), shipCountry = "Germany", productID = 43},
                };

            //Customers
            Customer[] customers = new Customer[]
                {
                    new Customer {customerID = "ALFKI", companyName = "Alfreds Futterkiste", country = "Germany", orders = orderALFKI},
                    new Customer {customerID = "BERGS", companyName = "Berglunds snabbköp", country = "Sweden", orders = orderBERGS},
                    new Customer {customerID = "DUMON", companyName = "Du monde entier", country = "France", orders = orderDUMON},
                    new Customer {customerID = "LEHMS", companyName = "Lehmanns Marktstand", country = "Germany", orders = orderLEHMS}
                };

            //Codefragment//



            #region ElementAt
            {
                var result1 =
                from p in products
                orderby p.unitPrice descending
                select new { p.productID, p.name, p.unitPrice };

                Console.WriteLine(result1.ElementAt(3));

                Console.WriteLine(result1.ElementAt(3).name);
                Console.WriteLine(result1.ElementAt(3).productID);
                Console.WriteLine(result1.ElementAt(3).unitPrice);
            }
            #endregion

            Console.WriteLine();

            #region ElementAtOrDefault
            {
                var result2 =
                from p in products
                orderby p.unitPrice descending
                select new { p.productID, p.name, p.unitPrice };

                Console.WriteLine(result2.ElementAtOrDefault(99));

                Console.WriteLine(result2.ElementAtOrDefault(99) == null ? "-" : result2.ElementAt(99).name);
                Console.WriteLine(result2.ElementAtOrDefault(99) == null ? -1 : result2.ElementAt(99).productID);
                Console.WriteLine(result2.ElementAtOrDefault(99) == null ? 0.00 : result2.ElementAt(99).unitPrice);
            }
            #endregion

            Console.WriteLine();

            #region First, FirstOrDefault
            {
                var result3 =
                from p in products
                orderby p.unitPrice descending
                select new { p.productID, p.name, p.unitPrice };

                Console.WriteLine(result3.First());

                Console.WriteLine(result3.FirstOrDefault() == null ? "-" : result3.First().name);
                Console.WriteLine(result3.FirstOrDefault() == null ? -1 : result3.First().productID);
                Console.WriteLine(result3.FirstOrDefault() == null ? 0.00 : result3.First().unitPrice);
            }
            #endregion

            Console.WriteLine();

            #region Last, LastOrDefault
            {
                var result4 =
                from p in products
                orderby p.unitPrice descending
                select new { p.productID, p.name, p.unitPrice };

                Console.WriteLine(result4.Last());

                Console.WriteLine(result4.LastOrDefault() == null ? "-" : result4.Last().name);
                Console.WriteLine(result4.LastOrDefault() == null ? -1 : result4.Last().productID);
                Console.WriteLine(result4.LastOrDefault() == null ? 0.00 : result4.Last().unitPrice);
            }
            #endregion

            Console.WriteLine();

            #region Single, SingleOrDefault
            {
                var result5 =
                from p in products
                orderby p.unitPrice descending
                select new { p.productID, p.name, p.unitPrice };

                Console.WriteLine(result5.Single(p => p.productID == 63));

                Console.WriteLine(result5.SingleOrDefault(p => p.productID == 63) == null ? "-" : result5.Single(p => p.productID == 63).name);
                Console.WriteLine(result5.SingleOrDefault(p => p.productID == 63) == null ? 0.00 : result5.Single(p => p.productID == 63).unitPrice);
            }
            #endregion



            //Codefragment//

            Console.ReadLine();
        }
    }
}