/// <summary>
        /// Loads from file to movie array.
        /// </summary>
        /// <param name="filePath">Load filepath</param>
        /// <param name="movies">Movie array to add movies to</param>
        /// <param name="menuItem">MenuItem to update with new spacing</param>
        /// <returns>Movie array with loaded entries</returns>
        public static Movie[] LoadFile(string filePath, Movie[] movies, MenuItem menuItem)
        {
            if (File.Exists(filePath))
            {
                StreamReader file = new StreamReader(filePath);
                string       line;
                while ((line = file.ReadLine()) != null)
                {
                    string[] lines = line.Split('\t');
                    if (lines.Length <= 0)
                    {
                        file.Close();
                        File.WriteAllText(filePath, string.Empty);
                        break;
                    }
                    string title = lines[0];
                    Genres genre;
                    double rating;
                    double length;
                    bool   seen;

                    if (!Enum.TryParse(lines[1], out genre) && !double.TryParse(lines[2], out rating))
                    {
                        Console.WriteLine("Couldn't parse genre");
                        break;
                    }

                    if (!double.TryParse(lines[2], out rating))
                    {
                        Console.WriteLine("Couldn't parse rating");
                        break;
                    }

                    if (!double.TryParse(lines[3], out length))
                    {
                        Console.WriteLine("Couldn't parse length");
                        break;
                    }

                    if (!bool.TryParse(lines[4], out seen))
                    {
                        Console.WriteLine("Couldn't parse seen");
                        break;
                    }

                    Movie newMovie = new Movie(title, genre, rating, length, seen);
                    movies = EssentialFunctions.AddMovie(newMovie, movies);//Uses add movie function to dynamically add movies to an array (doesn't matter the size of the array)
                    EssentialFunctions.UpdateSpacing(title.Length, 2, menuItem);
                }

                file.Close();

                Console.WriteLine("Loaded file");
                return(movies);
            }
            else
            {
                File.Create(filePath);
                return(null);
            }
        }
        static void Main(string[] args)
        {
            bool playing = true;

            string savePath = "Filmer.txt";

            Movie[] movieList      = new Movie[0];
            Movie[] searchedMovies = new Movie[0];

            int spacingTitle  = 14;//Variables that dictates spacing between menu items
            int spacingOther  = 14;
            int spacingMovies = 8;

            Genres[]     genres       = Enums.genres;
            ConsoleColor defaultColor = ConsoleColor.Yellow;

            Menu[]   menus       = new Menu[3];//Define how many menus there are.
            IntRange currentMenu = new IntRange(0, menus.Length);

            menus[0] = new Menu(true, true);
            menus[1] = new Menu(false);

            menus[0].AddMenuItem("Title", spacingTitle, defaultColor, defaultColor, showCursor: true, sortingType: SortingTypes.Title);
            menus[0].AddMenuItem("Genre", spacingOther, defaultColor, defaultColor, showCursor: true, sortingType: SortingTypes.Genre);
            menus[0].AddMenuItem("Rating", spacingOther, defaultColor, defaultColor, showCursor: true, sortingType: SortingTypes.Rating);
            menus[0].AddMenuItem("Length", spacingOther, defaultColor, defaultColor, showCursor: true, sortingType: SortingTypes.Length);
            menus[0].AddMenuItem("Seen", spacingOther, defaultColor, defaultColor, showCursor: true, sortingType: SortingTypes.Seen);

            menus[1].AddMenuItem("Title", spacingMovies, errorProfile: new ErrorProfileTitle());
            menus[1].AddMenuItem("Genre", spacingMovies, errorProfile: new ErrorProfileGenre());
            menus[1].AddMenuItem("Rating", spacingMovies, errorProfile: new ErrorProfileRating(0, 10));
            menus[1].AddMenuItem("Length", spacingMovies, errorProfile: new ErrorProfileLength());
            menus[1].AddMenuItem("Seen", spacingMovies, errorProfile: new ErrorProfileSeen(), showCursor: true);
            menus[1].AddMenuItem("[Done]", color: ConsoleColor.Green, showCursor: false);
            menus[1].AddMenuItem("[Cancel]", showCursor: false);

            IntRange selection    = new IntRange(0, menus[0].menuItems.Length - 1);
            IntRange selectionAlt = new IntRange(0, movieList.Length);
            bool     ratingSorted = false;
            bool     editMovie    = false;

            movieList = FileFunctions.LoadFile(savePath, movieList, menus[currentMenu.Value].menuItems[0]);
            ConsoleKey     consoleKey;
            ConsoleKeyInfo searchKeyInfo;

            string headerText   = "[1. Add] [Enter. Edit] [Delete. Remove] Search: ";
            string searchString = "";

            while (playing)
            {
                selection.MaxValue    = menus[currentMenu.Value].Amount - 1;
                selectionAlt.MaxValue = movieList.Length;
                Console.SetCursorPosition(0, 0);
                Console.WriteLine(headerText + searchString);

                SetupMenus(menus[currentMenu.Value].MenuItems, 0, 2);
                if (searchString.Length > 0)
                {
                    DisplayMovies(searchedMovies);
                    Console.SetCursorPosition(0, 5 + movieList.Length);
                    for (int i = 5 + searchedMovies.Length; i < 5 + movieList.Length; i++)//
                    {
                        Console.SetCursorPosition(0, i);
                        Console.Write(new string(' ', Console.WindowWidth));
                    }
                }
                else
                {
                    DisplayMovies(movieList);
                }
                Console.SetCursorPosition(headerText.Length + searchString.Length, 0);

                searchKeyInfo = Console.ReadKey();
                consoleKey    = searchKeyInfo.Key;
                UpdateMenu(consoleKey);
                if (consoleKey == ConsoleKey.D1 || (consoleKey == ConsoleKey.Enter && selectionAlt.Value > 0)) //Key 1 pressed
                {
                    int movieIndex = 0;
                    if (selectionAlt.Value > 0 && consoleKey != ConsoleKey.D1) //Check if movie is being edited
                    {
                        editMovie  = true;
                        movieIndex = selectionAlt.Value - 1;
                    }
                    ChangeMenu(1);
                    if (editMovie)
                    {
                        Console.WriteLine("Edit movie");
                    }
                    else
                    {
                        Console.WriteLine("Add movie");
                    }

                    selection.MaxValue    = menus[currentMenu.Value].Amount - 1;
                    selectionAlt.MaxValue = 0;

                    int topOffset   = 2;                                          //Used to add offset from top line
                    int errorOffset = 9;                                          //Used to position error line

                    Object[] movieVariables = new Object[5];                      //Create array that is going to hold input variables, the reason it's an object array is because the variable types are not the same
                    string[] userInputs     = new string[selection.MaxValue + 1]; //Used to store all keystrokes from corresponding selection
                    bool[]   inputsCorrect  = new bool[userInputs.Length];        //Bool array used to collect all errors, if there are no errors the user can press done.

                    for (int i = 0; i < userInputs.Length; i++)
                    {
                        userInputs[i] = "";
                    }
                    for (int i = 0; i < menus[currentMenu.Value].menuItems.Length; i++)//Resets all menu items
                    {
                        menus[currentMenu.Value].menuItems[i].Correct = false;
                    }

                    DisplayGenres(genres, 0, 12 + topOffset, "Genres");

                    while (currentMenu.Value == 1)//While in adding movie menu
                    {
                        Console.SetCursorPosition(0, errorOffset + topOffset);
                        Console.Write(new string(' ', Console.WindowWidth));//Clear the error line

                        Console.SetCursorPosition(0, errorOffset + topOffset);
                        for (int i = 0; i < movieVariables.Length; i++)
                        {
                            if (menus[currentMenu.Value].menuItems[i].errorProfile != null && selection.Value == i)
                            {
                                SetInputs(menus[currentMenu.Value].menuItems[i].errorProfile.CheckError(userInputs[i], out movieVariables[i], 0, errorOffset + topOffset), i);
                            }
                        }

                        if (EssentialFunctions.CheckBools(inputsCorrect))//Sets the done button to true or false depending on if all other buttons are correct or not
                        {
                            SetInputs(true, 5);
                        }
                        SetupMenus(menus[currentMenu.Value].menuItems, 0, topOffset);
                        Console.SetCursorPosition(menus[currentMenu.Value].menuItems[selection.Value].Spacing + userInputs[selection.Value].Length, selection.Value + topOffset);

                        ConsoleKeyInfo consoleKeyInfo = Console.ReadKey();
                        consoleKey = consoleKeyInfo.Key;
                        if (UpdateMenu(consoleKey))
                        {
                        }
                        else if (consoleKey == ConsoleKey.Enter)
                        {
                            if (selection.Value == selection.MaxValue - 1 && EssentialFunctions.CheckBools(inputsCorrect))//Add movie
                            {
                                Movie newMovie = new Movie((string)movieVariables[0], (Genres)movieVariables[1], (double)movieVariables[2], (double)movieVariables[3], (bool)movieVariables[4]);
                                if (editMovie)
                                {
                                    movieList = EssentialFunctions.ReplaceMovie(movieIndex, newMovie, movieList);
                                    FileFunctions.SaveFile(savePath, movieList);
                                    editMovie = false;
                                }
                                else
                                {
                                    movieList = EssentialFunctions.AddMovie(newMovie, movieList);
                                    FileFunctions.SaveFile(savePath, movieList);
                                }

                                int newSpacing = movieVariables[0].ToString().Length;
                                EssentialFunctions.UpdateSpacing(newSpacing, 2, menus[0].MenuItems[0]);
                                ChangeMenu(0);
                            }
                            else if (selection.Value == selection.MaxValue)//Cancel
                            {
                                ChangeMenu(0);
                            }
                            else
                            {
                                selection.Value++;
                            }
                        }
                        else
                        {
                            if (consoleKey == ConsoleKey.Backspace && userInputs[selection.Value].Length > 0)
                            {
                                userInputs[selection.Value] = userInputs[selection.Value].Remove(userInputs[selection.Value].Length - 1);
                                Console.SetCursorPosition(menus[currentMenu.Value].menuItems[selection.Value].Spacing + userInputs[selection.Value].Length, selection.Value + topOffset);
                                Console.Write(" ");
                            }
                            else if (consoleKey != ConsoleKey.Backspace)
                            {
                                userInputs[selection.Value] += consoleKeyInfo.KeyChar;
                            }
                        }
                    }
                    void SetInputs(bool input, int index)
                    {
                        inputsCorrect[index] = input;
                        menus[currentMenu.Value].menuItems[index].Correct = input;
                    }
                }
                else if (consoleKey == ConsoleKey.Enter) //Enter pressed
                {
                    if (selectionAlt.Value == 0)         //If the selection is on a menu item, Sort list
                    {
                        for (int i = 0; i < menus[currentMenu.Value].menuItems.Length; i++)
                        {
                            menus[currentMenu.Value].menuItems[i].SetSorted();
                        }
                        EssentialFunctions.Sort(movieList, menus[currentMenu.Value].menuItems[selection.Value], 0, movieList.Length - 1, menus[currentMenu.Value].menuItems[selection.Value].SortedAscending);
                    }
                }
                else if (consoleKey == ConsoleKey.Delete)//Delete pressed
                {
                    if (selectionAlt.Value > 0)
                    {
                        movieList = EssentialFunctions.RemoveMovie(selectionAlt.Value - 1, ref selectionAlt, movieList);
                        FileFunctions.SaveFile(savePath, movieList);
                    }
                }
                else//Search
                {
                    if (consoleKey == ConsoleKey.Backspace && searchString.Length > 0)
                    {
                        searchString = searchString.Remove(searchString.Length - 1);
                        Console.SetCursorPosition(headerText.Length + searchString.Length, 0);
                        Console.Write(" ");
                    }
                    else if (consoleKey != ConsoleKey.Backspace)
                    {
                        char inputKey = searchKeyInfo.KeyChar;
                        if (char.IsLetterOrDigit(inputKey) || consoleKey == ConsoleKey.Spacebar)
                        {
                            searchString += inputKey;
                        }
                    }
                    if (searchString.Length > 0)
                    {
                        searchedMovies = EssentialFunctions.Search(movieList, searchString);
                    }
                }
            }
            void ChangeMenu(int menuIndex)//Changes the menu variables and clears the console.
            {
                Console.Clear();
                currentMenu.Value  = menuIndex;
                selection.Value    = 0;
                selectionAlt.Value = 0;
            }

            void SetupMenus(MenuItem[] menuItems, int left, int top)//Displays menu items with their corresponding options such as color, name, cursor, spacing.
            {
                Console.SetCursorPosition(left, top);
                if (menuItems[selection.Value].ShowCursor)
                {
                    Console.CursorVisible = true;
                }
                else
                {
                    Console.CursorVisible = false;
                }

                int lineLength = 0;

                for (int i = 0; i < menuItems.Length; i++)
                {
                    string   menuItemString = "";
                    MenuItem menuItem       = menuItems[i];
                    if (i == selection.Value && selectionAlt.Value < 1)
                    {
                        menuItem.Select(true);
                    }
                    else
                    {
                        menuItem.Select(false);
                    }

                    if (menus[currentMenu.Value].Spacing)
                    {
                        menuItemString += string.Format("{0," + -menuItem.Spacing + "}", menuItem.Name);
                    }
                    else
                    {
                        menuItemString += string.Format("{0}", menuItem.Name);
                    }

                    if (menus[currentMenu.Value].Horizontal == false || i == menuItems.Length - 1)
                    {
                        menuItemString += "\n";
                    }

                    if (!menuItem.Correct)
                    {
                        Console.ForegroundColor = menuItem.ErrorColor;
                    }
                    else
                    {
                        Console.ForegroundColor = menuItem.Color;
                    }
                    lineLength += menuItemString.Length;
                    Console.Write(menuItemString);
                }
                Console.Write(new string('_', lineLength - 8) + "\n\n");
                Console.ForegroundColor = ConsoleColor.White;
            }

            bool UpdateMenu(ConsoleKey consoleKey)//Takes input (the input depends on if the current menu is horizontal) and changes selection value which in term makes the menus update, returns true if correct key was pressed
            {
                bool isHorizontal = menus[currentMenu.Value].Horizontal;

                if (isHorizontal)
                {
                    if (consoleKey == ConsoleKey.RightArrow)
                    {
                        selectionAlt.Value = 0;
                        selection.Value++;
                    }
                    else if (consoleKey == ConsoleKey.LeftArrow)
                    {
                        selectionAlt.Value = 0;
                        selection.Value--;
                    }
                    else if (consoleKey == ConsoleKey.DownArrow)
                    {
                        selection.Value = 0;
                        selectionAlt.Value++;
                    }
                    else if (consoleKey == ConsoleKey.UpArrow)
                    {
                        selection.Value = 0;
                        selectionAlt.Value--;
                    }
                }
                else
                {
                    if (consoleKey == ConsoleKey.DownArrow)
                    {
                        selection.Value++;
                    }
                    else if (consoleKey == ConsoleKey.UpArrow)
                    {
                        selection.Value--;
                    }
                    else if (consoleKey == ConsoleKey.RightArrow)
                    {
                        selectionAlt.Value++;
                    }
                    else if (consoleKey == ConsoleKey.LeftArrow)
                    {
                        selectionAlt.Value--;
                    }
                }
                if (consoleKey == ConsoleKey.DownArrow || consoleKey == ConsoleKey.UpArrow || consoleKey == ConsoleKey.LeftArrow || consoleKey == ConsoleKey.RightArrow)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            void DisplayMovies(Movie[] movieList)//Writes all movies in movie array.
            {
                Console.ForegroundColor = ConsoleColor.White;
                if (movieList.Length > 0)
                {
                    string movieString;
                    for (int i = 0; i < movieList.Length; i++)
                    {
                        string prefix;
                        if (selectionAlt.Value - 1 == i && selection.Value == 0)
                        {
                            Console.BackgroundColor = ConsoleColor.Gray;
                            Console.ForegroundColor = ConsoleColor.Black;
                            prefix = ">";
                        }
                        else
                        {
                            prefix = " ";
                        }

                        movieString = string.Format(prefix + "{0," + -menus[0].menuItems[0].Spacing + "}" + //Takes all variables from movie object and formats them to have spacing between them.
                                                    "{1," + -menus[0].menuItems[1].Spacing + "}" +
                                                    "{2," + -menus[0].menuItems[2].Spacing + "}" +
                                                    "{3:0}h{4:00}m",
                                                    movieList[i].title,
                                                    movieList[i].genre,
                                                    movieList[i].rating,
                                                    Math.Floor(movieList[i].length / 60),
                                                    movieList[i].length % 60);
                        movieString = movieString.PadRight(movieString.Length + 9) + (movieList[i].seen ? "x" : " ");

                        Console.WriteLine(movieString);
                        Console.BackgroundColor = ConsoleColor.Black;
                        Console.ForegroundColor = ConsoleColor.White;
                    }
                }
            }

            void DisplayGenres(Genres[] genres, int left, int top, string description)//Writes all genres in a genre array
            {
                Console.SetCursorPosition(left, top);
                Console.WriteLine(description);
                for (int i = 0; i < genres.Length; i++)
                {
                    Console.WriteLine(i + 1 + ": " + genres[i]);
                }
            }
        }