namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter08.Listing08_10
{
    using System;
    using Listing08_02;

    class Program
    {
        public static void Main()
        {
            Contact[] contacts = new Contact[] {
                new Contact(
        "Dariusz", "Tracz",
        "ul. Wysoka 123, 45-287 Poznań",
        "123-123-1234")
            // …
        };

        // Klasy są niejawnie przekształcane
        // na obsługiwane interfejsy.
        contacts.List(Contact.Headers);

            Console.WriteLine();

            Publication[] publications = new Publication[3] {
      new Publication("Dyscypliny życia duchowego",
        "Richard Foster", 1978),
      new Publication("Ortodoksja",
        "G.K. Chesterton", 1908),
      new Publication(
        "Autostopem przez galaktykę",
        "Douglas Adams", 1979)
                };
            publications.List(Publication.Headers);
        }
    }

    static class Listable
    {
        public static void List(
            this IListable[] items, string[] headers)
        {
            int[] columnWidths = DisplayHeaders(headers);

            for(int itemCount = 0; itemCount < items.Length; itemCount++)
            {
                if (items[itemCount] != null)
                {
                    string[] values = items[itemCount].ColumnValues;

                    DisplayItemRow(columnWidths, values);
                }
            }
        }

        /// <summary>Wyświetla nagłówki kolumn</summary>
        /// <returns>Zwraca tablicę szerokości kolumn</returns>
        private static int[] DisplayHeaders(string[] headers)
        {
            var columnWidths = new int[headers.Length];
            for(int index = 0; index < headers.Length; index++)
            {
                Console.Write(headers[index]);
                columnWidths[index] = headers[index].Length;
            }
            Console.WriteLine();
            return columnWidths;
        }

        private static void DisplayItemRow(
            int[] columnWidths, string[] values)
        {
            if(columnWidths.Length != values.Length)
            {
                throw new ArgumentOutOfRangeException(
                    $"{ nameof(columnWidths) },{ nameof(values) }",
                    "Liczba szerokości kolumn musi pasować do liczby wyświetlanych wartości");
            }

            for(int index = 0; index < values.Length; index++)
            {
                string itemToPrint = values[index].PadRight(columnWidths[index], ' ');
                Console.Write(itemToPrint);
            }
            Console.WriteLine();
        }
    }
}
