private void monoFlat_Button1_Click(object sender, EventArgs e)
        {
            testName              = textBox1.Text;
            exerciseAmount        = Convert.ToInt32(numericUpDown1.Value);
            testGroupsAmount      = Convert.ToInt32(numericUpDown2.Value);
            possibleAnswersAmount = Convert.ToInt32(numericUpDown3.Value);
            richTextBox1.Text.Trim();
            string answerKey = "";

            string[] lines = richTextBox1.Text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
            char     value;

            for (int i = 1; i <= lines.Length; i++)
            {
                string[] keyPair = lines[i - 1].Trim().Split(new[] { "-" }, StringSplitOptions.RemoveEmptyEntries);
                value      = keyPair[1][0];
                answerKey += i.ToString() + "-" + value + "\n";
            }
            AnswerSheet.Generate(testName, exerciseAmount, testGroupsAmount, possibleAnswersAmount, answerKey); // make it a non-void method and return and save / open the finished bitmap
            if (MessageBox.Show("Answer sheet with name " + testName + " successfully generated! Would you like to open it?", "Answer Sheet", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == DialogResult.Yes)
            {
                Process.Start(Application.StartupPath + $@"\{testName}.bmp");
            }
        }
        public string Generate(Test test)
        {
            List <string>          exercises      = new List <string>();
            List <string>          answers        = new List <string>();
            ConcurrentBag <string> bagOfAnswers   = new ConcurrentBag <string>();
            ConcurrentBag <string> bagOfExercises = new ConcurrentBag <string>(); // used when using multiple threads

            TestGeneratorForm.fr.progressBar1.Visible = true;
            TestGeneratorForm.fr.progressBar1.Value   = 0;
            TestGeneratorForm.fr.progressBar1.Maximum = TestGeneratorForm.fr.richTextBox2.Text.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Length;
            Dictionary <string, string> buffer = new Dictionary <string, string>();
            Random rndm = new Random();

            test.Result = ""; // reset the result property to prevent "stacking" of tests
            string suggestedAnswerKey = "";
            int    n = 1;

            while (n <= test.ExcerciseAmount && test.WordsAndTypes.Count > 0)
            {
                int    randomExercise = rndm.Next(0, test.WordsAndTypes.Count - 1);
                string key            = test.WordsAndTypes.ElementAt(randomExercise).Key;
                string value          = test.WordsAndTypes[key];
                KeyValuePair <string, string> pair = new KeyValuePair <string, string>(key, value);
                if (!Utility.IsValidEntry(pair, test.Type))
                {
                    test.WordsAndTypes.Remove(key);
                    continue;
                }
                buffer.Add(key, test.WordsAndTypes[key]);
                test.WordsAndTypes.Remove(key);
                n++;
            }
            test.WordsAndTypes = buffer;
            switch (TestGeneratorForm.generatingSpeed)
            {
            case "Normal":
                foreach (KeyValuePair <string, string> entry in test.WordsAndTypes)
                {
                    TestGeneratorForm.fr.progressBar1.Value++;
                    switch (test.Type)
                    {
                    case "Definitions":
                        exercises.Add(Read(Definitions.Get(entry.Value, entry.Key)));
                        answers.Add(entry.Key);
                        break;

                    case "Examples":
                        exercises.Add(Regex.Replace(Read(Examples.Get(entry.Value, entry.Key)), entry.Key, new string('_', entry.Key.Length), RegexOptions.IgnoreCase));
                        answers.Add(entry.Key);
                        break;

                    case "Words":
                        exercises.Add(entry.Key + new string('.', 50) + " (" + entry.Value.TrimEnd() + ")");
                        break;

                    case "Multi-Choices":
                        char answer = 'A';         // stores the correct answer for each exercise
                        exercises.Add(Regex.Replace(Read(Examples.Get(entry.Value, entry.Key)), entry.Key, new string('_', entry.Key.Length), RegexOptions.IgnoreCase) + "\n" + Synonyms.Request(entry.Key, out answer));
                        answers.Add(answer.ToString());
                        break;
                    }
                }
                break;

            case "Fast":
                System.Threading.Tasks.Parallel.ForEach(test.WordsAndTypes, entry =>
                {
                    switch (test.Type)
                    {
                    case "Definitions":
                        bagOfExercises.Add(Read(Definitions.Get(entry.Value, entry.Key)));
                        bagOfAnswers.Add(entry.Key);
                        break;

                    case "Examples":
                        bagOfExercises.Add(Regex.Replace(Read(Examples.Get(entry.Value, entry.Key)), entry.Key, new string('_', entry.Key.Length), RegexOptions.IgnoreCase));
                        bagOfAnswers.Add(entry.Key);
                        break;

                    case "Words":
                        bagOfExercises.Add(entry.Key + new string('.', 50) + " (" + entry.Value.TrimEnd() + ")");
                        break;

                    case "Multi-Choices":
                        char answer = 'A';         // stores the correct answer for each exercise
                        bagOfExercises.Add(Regex.Replace(Read(Examples.Get(entry.Value, entry.Key)), entry.Key, new string('_', entry.Key.Length), RegexOptions.IgnoreCase) + "\n" + Synonyms.Request(entry.Key, out answer));
                        bagOfAnswers.Add(answer.ToString());
                        break;
                    }
                });
                exercises = bagOfExercises.ToList();     // Converts the bagOfExercises variable to List and sets it to exercises variable
                answers   = bagOfAnswers.ToList();
                break;
            }
            foreach (var exercise in exercises.ToList())
            {
                if ((exercise.Contains("Couldn't find ") && (exercise.Contains("NotFound") || exercise.Contains("ERROR")) && answers.Any()) ||
                    (!(exercise.Contains("_")) && answers.Any() && (test.Type == "Examples" ||
                                                                    test.Type == "Multi-Choices"))) // remove all of the words that were not found in the Oxford Dictionary
                {
                    answers.RemoveAt(exercises.IndexOf(exercise));
                    exercises.Remove(exercise);
                }
            }
            if (exercises.Count - test.ExcerciseAmount < 0) // if there are not enough words to make a test, lower the exercise amount
            {
                test.ExcerciseAmount -= (test.ExcerciseAmount - exercises.Count);
            }
            test.Result        += "~~~~~" + test.Name + "~~~~~\n";
            suggestedAnswerKey += (answers.Any()) ? "~~~~~ Suggested Answer Key ~~~~~\n" : string.Empty;
            string answerKey = "";

            n = 1;
            while (n <= test.ExcerciseAmount)
            {
                int randomExercise = rndm.Next(0, exercises.Count);
                test.Result        += "------------------[Ex. " + n + "]------------------\n" + exercises[randomExercise] + "\n";
                suggestedAnswerKey += (answers.Any()) ? "[Ex. " + n + "] - " + answers[randomExercise] + "\n" : string.Empty;
                exercises.RemoveAt(randomExercise);
                if (answers.Any())
                {
                    if (test.Type == "Multi-Choices")
                    {
                        answerKey += n.ToString() + "-" + answers[randomExercise] + "\n";
                        AnswerSheet.Generate(test.Name, test.ExcerciseAmount, 1, 4, answerKey);
                    }
                    answers.RemoveAt(randomExercise);
                }
                n++;
            }
            test.Result += "\n" + suggestedAnswerKey;
            TestGeneratorForm.fr.progressBar1.Visible = false;
            return(test.Result);
        }