// Prints the Library's Catalog into the console as individual entries.
 // Each entry has their information displayed on the console.
 public void PrintItems()
 {
     for (int i = 0; i < Catalog.Count; i++)
     {
         Item item = Catalog[i];
         item.PrintInfo();
         CnslFormatter.MakeLineSpace(1);
     }
 }
        // Prompts User for multiple inputs that will serve as the info for a new Item.
        // The new Item will then be placed into the Catalog
        public void AddNewItem()
        {
            string newTitle  = CnslFormatter.PromptForInput("Please enter the Title of the new Item: ");
            string newAuthor = CnslFormatter.PromptForInput("Please enter the Author of the new Item: ");
            int    newYear   = -1;

            while (true)
            {
                string newYearStr = CnslFormatter.PromptForInput("Please enter the Release Year of the new Item: ");
                if (Int32.TryParse(newYearStr, out newYear))
                {
                    break;
                }
            }
            // Type Prompt, user enters a string to determine which kind of Item should be created through specialized calls.
            // Will repeat until a valid string value is given.
            while (true)
            {
                string newType = CnslFormatter.PromptForInput("Please enter the Type of the new Item [book, cd, dvd, magazine]: ");
                if (newType.ToLower().Equals("book"))
                {
                    Item newBook = MakeNewBook(newTitle, newAuthor, newYear);
                    Catalog.Add(newBook);
                    Console.WriteLine("New Book Added to Catalog!");
                    CnslFormatter.PauseByAnyKey();
                    break;
                }
                else if (newType.ToLower().Equals("cd"))
                {
                    Item newCD = MakeNewCD(newTitle, newAuthor, newYear);
                    Catalog.Add(newCD);
                    Console.WriteLine("New CD Added to Catalog!");
                    CnslFormatter.PauseByAnyKey();
                    break;
                }
                else if (newType.ToLower().Equals("dvd"))
                {
                    Item newDVD = MakeNewDVD(newTitle, newAuthor, newYear);
                    Catalog.Add(newDVD);
                    Console.WriteLine("New DVD Added to Catalog!");
                    CnslFormatter.PauseByAnyKey();
                    break;
                }
                else if (newType.ToLower().Equals("magazine"))
                {
                    Item newMagazine = MakeNewMagazine(newTitle, newAuthor, newYear);
                    Catalog.Add(newMagazine);
                    Console.WriteLine("New Magazine Added to Catalog!");
                    CnslFormatter.PauseByAnyKey();
                    break;
                }
            }
        }
        // Finds the specified Item within the Library's Catalog and checks to see if it is available to be checked out.
        // If available, the Item's status is changed to CheckedOut, and their DueDate value is changed to 14 days following the current date/time.
        // If it is already checked out, the console states that the item is not available.
        public void Checkout(List <Item> itemsList)
        {
            Console.Clear();
            for (int i = 0; i < itemsList.Count; i++)
            {
                Console.Write($"Item {i + 1}. ");
                itemsList[i].PrintInfo();
                Console.WriteLine();
            }
            string input = CnslFormatter.PromptForInput($"Please select the item you would like to checkout. [{CnslFormatter.MoreThanOne(itemsList)}]: ");

            if (Int32.TryParse(input, out int num))
            {
                int index = num - 1;

                if (index < 0 || index >= itemsList.Count)
                {
                    Console.WriteLine($"Input out of range. {CnslFormatter.MoreThanOne(itemsList)}.");
                }
                else
                {
                    if (itemsList[index].Status == ItemStatus.OnShelf)
                    {
                        Console.WriteLine(Environment.NewLine + "You have checked out: ");
                        Console.WriteLine($"   {itemsList[index].Title} by {itemsList[index].Author}");
                        DateTime checkoutDate = DateTime.Now;
                        itemsList[index].Status  = ItemStatus.CheckedOut;
                        itemsList[index].DueDate = checkoutDate.AddDays(14);
                        Console.WriteLine($"   Due back by {itemsList[index].DueDate:d}");
                        CnslFormatter.PauseByAnyKey();
                    }
                    else if (itemsList[index].Status == ItemStatus.CheckedOut || itemsList[index].Status == ItemStatus.Overdue)
                    {
                        Console.WriteLine("\nItem is already checked out. Cannot complete checkout at this time.");
                        CnslFormatter.PauseByAnyKey();
                    }
                    else
                    {
                        Console.WriteLine("\nCannot complete checkout at this time.");
                        CnslFormatter.PauseByAnyKey();
                    }
                }
            }
            else
            {
                Console.WriteLine("\nNon-Integer input detected. Please enter an integer next time.");
            }
        }
 // Returns a new CD using base Item values for arguments, and specialized values given by user.
 public Item MakeNewCD(string title, string author, int year)
 {
     while (true)
     {
         try
         {
             int  newTracks = Int32.Parse(CnslFormatter.PromptForInput("Please enter the Tracks of the new CD: "));
             Item newCD     = new CD(title, author, year, newTracks);
             return(newCD);
         }
         catch (FormatException)
         {
             Console.WriteLine("Please enter a valid number");
         }
     }
 }
        // Returns a new DVD using base Item values for arguments, and specialized values given by user.
        // Input prompt will repeat until a valid integer is given.
        public Item MakeNewDVD(string title, string author, int year)
        {
            int newRunTime = -1;

            while (true)
            {
                string newRunTimeStr = CnslFormatter.PromptForInput("Please enter the RunTime of the new DVD: ");
                if (Int32.TryParse(newRunTimeStr, out newRunTime))
                {
                    break;
                }
            }

            Item newDVD = new DVD(title, author, year, newRunTime);

            return(newDVD);
        }
        // Returns a new Book using base Item values for arguments, and specialized values given by user.
        // Input prompt will repeat until a valid integer is given.
        public Item MakeNewBook(string title, string author, int year)
        {
            int newPageCnt = -1;

            while (true)
            {
                string newPageCntStr = CnslFormatter.PromptForInput("Please enter the PageCount of the new Book: ");
                if (Int32.TryParse(newPageCntStr, out newPageCnt))
                {
                    break;
                }
            }

            Item newBook = new Book(title, author, year, newPageCnt);

            return(newBook);
        }
        // Finds the specified Item within the Library's Catalog and checks to see if it is checked out to then be checked back in.
        // If checked out, the Item's status is changed to OnShelf (checked in).
        // If it is already checked in, the console states that the item is already checked in.
        public void CheckIn(List <Item> itemsList)
        {
            bool proceed = CnslFormatter.AskYesOrNo($"Would you like to return an item? ");

            while (proceed)
            {
                Console.Clear();
                for (int i = 0; i < itemsList.Count; i++)
                {
                    Console.Write($"Item {i + 1}. ");
                    itemsList[i].PrintInfo();
                    Console.WriteLine();
                }
                string input = CnslFormatter.PromptForInput($"Please select the item you would like to return? [{CnslFormatter.MoreThanOne(itemsList)}]: ");
                if (Int32.TryParse(input, out int num))
                {
                    int index = num - 1;

                    if (index < 0 || index >= itemsList.Count)
                    {
                        Console.WriteLine($"Input out of range. {CnslFormatter.MoreThanOne(itemsList)}.");
                    }
                    else
                    {
                        if (itemsList[index].Status == ItemStatus.CheckedOut || itemsList[index].Status == ItemStatus.Overdue)
                        {
                            Console.WriteLine(Environment.NewLine + "You have checked in: ");
                            Console.WriteLine($"   {itemsList[index].Title} by {itemsList[index].Author}");
                            itemsList[index].Status = ItemStatus.OnShelf;
                            proceed = false;
                        }
                        else
                        {
                            Console.WriteLine("Cannot complete checkout at this time.");
                            CnslFormatter.PauseByAnyKey();
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Non-Integer input detected. Please enter an integer.");
                }
            }
            CnslFormatter.PauseByAnyKey();
        }
        // Returns a new Magazine using base Item values for arguments, and specialized values given by user.
        // Input prompt will repeat until a valid integer between 1 and 12 is given.
        public Item MakeNewMagazine(string title, string author, int year)
        {
            int newMonth = -1;

            while (true)
            {
                string newRunTimeStr = CnslFormatter.PromptForInput("Please enter the Month of Publishing of the new Magazine: ");
                if (Int32.TryParse(newRunTimeStr, out newMonth))
                {
                    if (!(newMonth < 1 || newMonth > 12))
                    {
                        break;
                    }
                }
            }
            Item newMagazine = new Magazine(title, author, year, newMonth);

            return(newMagazine);
        }
        static void Main(string[] args)
        {
            List <Item>  itemsLoaded = new List <Item>();
            StreamReader reader      = new StreamReader("../../../SavedItems.txt");
            string       line        = reader.ReadLine();

            while (line != null)
            {
                string[] itemEntryInfo = line.Split("|"); // Record line
                Item     newItem       = GenerateItem(itemEntryInfo);
                itemsLoaded.Add(newItem);
                line = reader.ReadLine();
            }
            reader.Close();

            Library L = new Library(itemsLoaded);

            bool userContinue = true;


            Console.WriteLine("Welcome to the Library!");
            while (userContinue)
            {
                LibraryMenu();
                string input = CnslFormatter.PromptForInput($"\nWhat would you like to do? ");
                Console.WriteLine();

                if (input == "1")  //prompts user to ask if they want to check out an item
                {
                    L.PrintItems();
                    bool proceed = CnslFormatter.AskYesOrNo($"Would you like to check out an item?");
                    if (proceed)
                    {
                        L.Checkout(L.Catalog);
                    }
                    else
                    {
                        Console.Clear();
                    }
                }
                else if (input == "2") //prompt for user to search by author name
                {
                    input = CnslFormatter.PromptForInput("Please enter name to search: ");
                    List <Item> resultsAuthor = L.SearchByAuthor(input);

                    if (resultsAuthor.Count == 0)
                    {
                        Console.WriteLine("\nNo items found.");
                        CnslFormatter.PauseByAnyKey();
                    }
                    else if (resultsAuthor.Count >= 1)
                    {
                        Console.WriteLine();
                        foreach (Item result in resultsAuthor)
                        {
                            result.PrintInfo();
                            Console.WriteLine();
                        }
                        bool proceed = CnslFormatter.AskYesOrNo($"Would you like to check out an item?");
                        if (proceed)
                        {
                            L.Checkout(resultsAuthor);
                        }
                        else
                        {
                            Console.Clear();
                        }
                    }
                }
                else if (input == "3") //prompt for user to search by title
                {
                    input = CnslFormatter.PromptForInput("Please enter title to search: ");
                    List <Item> resultsTitle = L.SearchByTitle(input);

                    if (resultsTitle.Count == 0)
                    {
                        Console.WriteLine("\nNo items found.");
                        CnslFormatter.PauseByAnyKey();
                    }
                    else if (resultsTitle.Count >= 1)
                    {
                        foreach (Item result in resultsTitle)
                        {
                            result.PrintInfo();
                            Console.WriteLine();
                        }
                        bool proceed = CnslFormatter.AskYesOrNo($"Would you like to check out an item?");
                        if (proceed)
                        {
                            L.Checkout(resultsTitle);
                        }
                        else
                        {
                            Console.Clear();
                        }
                    }
                }
                else if (input == "4") //lists all items that has been checked out
                {
                    Console.Clear();
                    Console.WriteLine("Items Currently Checked Out:\n");
                    List <Item> results = new List <Item>();
                    foreach (Item itemMatch in L.Catalog)
                    {
                        if (itemMatch.Status == ItemStatus.CheckedOut || itemMatch.Status == ItemStatus.Overdue)
                        {
                            results.Add(itemMatch);
                        }
                    }
                    if (results.Count <= 0)
                    {
                        Console.WriteLine("No matches found");
                        CnslFormatter.PauseByAnyKey();
                    }
                    else if (results.Count >= 1)
                    {
                        foreach (Item result in results)
                        {
                            result.PrintInfo();
                            Console.WriteLine();
                        }
                        L.CheckIn(results);
                    }
                }
                else if (input == "5")  //Brings up a series of prompts for the user to create new items
                {
                    L.AddNewItem();
                }
                else if (input == "6")  //displays item list and asks if user want to check in an item
                {
                    userContinue = false;
                }
                else
                {
                    Console.WriteLine("Invalid input. Please try again. ");
                    CnslFormatter.PauseByAnyKey();
                }
            }
            Console.WriteLine("Saving Library Content!");

            File.WriteAllText("../../../SavedItems.txt", string.Empty);            // Clear the File
            StreamWriter writer     = new StreamWriter("../../../SavedItems.txt"); // Should generate new file if deleted
            List <Item>  itemsSaved = L.Catalog;

            foreach (Item item in itemsSaved)
            {
                string itemEntry = GenerateEntry(item);
                writer.WriteLine(itemEntry);
            }
            writer.Close();


            Console.WriteLine("Goodbye!");
        }