/// <summary> Button to save current network settings </summary>
        private void NetworkSaveBtn_Click(object sender, EventArgs e)
        {
            //Setup paths and lists.
            string dataFile = "";
            string path     = "";

            //Normalise file.
            List <string> outputTitles = GetFile(false, ref path, ref dataFile, (int)(outputsUpDown.Value));
            List <string> inputTitles  = new List <string>();

            if (outputTitles == null)
            {
                return;
            }

            if (nameTxt.Text?.Length == 0)
            {
                MessageBox.Show("You must give your network a name.", "No Network Name.");
                return;
            }

            char[] dirty = Path.GetInvalidFileNameChars();

            foreach (char c in dirty)
            {
                if (nameTxt.Text.Contains(c.ToString()))
                {
                    MessageBox.Show("Your name contains invalid characters. Error at character " + c, "Invalid Network Name.");
                    return;
                }
            }

            //False when percentage split, true when cross validation.
            const bool validation = true;

            //Setup dataset.
            Data info = new Data();

            info = info.ReturnInfo(path + @"normal\" + dataFile.Replace(".csv", "Normal.csv"), outputTitles, 0, validation);

            //Load analyst from earlier.
            var analyst = new EncogAnalyst();

            analyst.Load(new FileInfo(path + @"normal\" + "normalizationData" + dataFile.Replace(".csv", "") + ".ega"));

            var sourcefile = new FileInfo(path + dataFile);

            var norm = new AnalystNormalizeCSV();

            norm.Analyze(sourcefile, true, CSVFormat.English, analyst);

            //Store input headings from analyst.
            for (int i = 0; i < analyst.Script.Fields.Length - outputTitles.Count; i++)
            {
                inputTitles.Add(analyst.Script.Fields[i].Name);
            }

            //Setup network.
            NeuralNetwork network;

            //If to decide which network type to use.
            if (radBtnEncog.Checked)
            {
                if (!deepNetworkBox.Checked)
                {
                    output.Text += "\n@Encog:\n\n";
                    network      = new EncogNeuralNetwork();
                }
                else
                {
                    output.Text += "\n@Deep Encog:\n\n";
                    network      = new EncogDeepNeuralNetwork();
                }
            }
            else
            {
                if (!deepNetworkBox.Checked)
                {
                    output.Text += "\n@Accord:\n\n";
                    network      = new AccordNeuralNetwork();
                }
                else
                {
                    output.Text += "\n@Deep Accord:\n\n";
                    network      = new AccordDeepNeuralNetwork();
                }
            }

            //Create network.
            network.Create(info.InputNumber, layersBar.Value, neuronsBar.Value, info.OutputNumber);

            //Save network to file.
            if (!Directory.Exists(path + "networks"))
            {
                Directory.CreateDirectory(path + "networks");
            }

            //network.Save(path + @"networks\" + nameTxt.Text);

            if ((path + @"networks\" + nameTxt.Text)?.Length < 260)
            {
                network.Save(path + @"networks\" + nameTxt.Text);
            }
            else
            {
                MessageBox.Show("Your file name or total file path is too long for the windows limit of 260.", "Invalid Network Name Size.");
                return;
            }

            //Save network data to object.
            NetworkSaveData networkSave = new NetworkSaveData
            {
                NetworkFile    = path + @"networks\" + nameTxt.Text,
                NetworkType    = network.GetType().ToString().Replace("ENP1.", ""), //"ENP1" must change to reflect solution name (name.) if ever changed.
                AnalystFile    = path + @"normal\" + "normalizationData.ega",
                CsvFile        = dataFile,
                Path           = path,
                InputHeadings  = inputTitles,
                OutputHeadings = outputTitles,
                Name           = nameTxt.Text,

                //Train network.
                Inaccuracy = Math.Round(network.Train(info, (float)(learningRateBar.Value) / 10, (float)(momentumBar.Value) / 10), 5).ToString()
            };

            //Write network object to json file.
            using (var sw = new StreamWriter(path + @"networks\networks.json", true))
            {
                using (var jsw = new JsonTextWriter(sw))
                {
                    //jsw.Formatting = Formatting.Indented;
                    JsonSerializer serial = new JsonSerializer();
                    serial.Serialize(jsw, networkSave);
                    sw.WriteLine();
                }
            }

            output.Text += "Successfully saved network " + nameTxt.Text + " with a training inaccuracy of: " + networkSave.Inaccuracy;
        }
        /// <summary> Button to test network settings. </summary>
        private void NetworkBtn_Click(object sender, EventArgs e)
        {
            //Setup paths and lists.
            string dataFile = "";
            string path     = "";

            //Normalise file.
            List <string> outputTitles = GetFile(false, ref path, ref dataFile, (int)(outputsUpDown.Value));

            if (outputTitles == null)
            {
                return;
            }

            //False when percentage split, true when cross validation.
            bool validation = !radBtnSplit.Checked;

            //Setup training dataset.
            Data info = new Data(); info = info.ReturnInfo(path + @"normal\" + dataFile.Replace(".csv", "Normal.csv"), outputTitles, sampleBar.Value, validation);

            if (info == null)
            {
                return;
            }

            //Load analyst from earlier.
            var analyst = new EncogAnalyst();

            analyst.Load(new FileInfo(path + @"normal\" + "normalizationData" + dataFile.Replace(".csv", "") + ".ega"));

            var sourcefile = new FileInfo(path + dataFile);

            var norm = new AnalystNormalizeCSV();

            norm.Analyze(sourcefile, true, CSVFormat.English, analyst);

            //Setup network.
            NeuralNetwork network;

            //If to decide which network type to use.
            if (radBtnEncog.Checked)
            {
                if (!deepNetworkBox.Checked)
                {
                    output.Text += "\n@Encog:\n\n";
                    network      = new EncogNeuralNetwork();
                }
                else
                {
                    output.Text += "\n@Deep Encog:\n\n";
                    network      = new EncogDeepNeuralNetwork();
                }
            }
            else
            {
                if (!deepNetworkBox.Checked)
                {
                    output.Text += "\n@Accord:\n\n";
                    network      = new AccordNeuralNetwork();
                }
                else
                {
                    output.Text += "\n@Deep Accord:\n\n";
                    network      = new AccordDeepNeuralNetwork();
                }
            }

            //If using cross-validation.
            if (validation)
            {
                //Setup pool size.
                decimal tmpPoolSize = info.InputData.Length * decimal.Divide(sampleBar.Value, 100);
                int     poolSize    = (int)tmpPoolSize;

                double[][] arrayIn = info.InputData; double[][] arrayOut = info.OutputData;

                info.InputData  = Data.CreateArray <double>(poolSize, info.InputData[0].Length);
                info.OutputData = Data.CreateArray <double>(poolSize, info.OutputData[0].Length);

                //Random to randomise pool selection.
                Random rnd = new Random();

                int[] index = new int[poolSize];

                //Radomly allocate items for training pool.
                for (int j = 0; j < info.InputData.Length; j++)
                {
                    index[j]          = rnd.Next(0, arrayIn.Length);
                    info.InputData[j] = arrayIn[index[j]]; info.OutputData[j] = arrayOut[index[j]];
                }

                //Remove pooled items from array.
                arrayIn  = Data.RemoveFromArray(arrayIn, index, poolSize);
                arrayOut = Data.RemoveFromArray(arrayOut, index, poolSize);

                //Start allocating sample pools.
                for (int i = 0; i <= arrayIn.Length / poolSize; i++)
                {
                    info.InputDataSample  = Data.CreateArray <double>(poolSize, arrayIn[0].Length);
                    info.OutputDataSample = Data.CreateArray <double>(poolSize, arrayOut[0].Length);

                    //Radomly allocate items for [i] sample pool.
                    for (int j = 0; j < info.InputDataSample.Length; j++)
                    {
                        index[j] = rnd.Next(0, arrayIn.Length);
                        info.InputDataSample[j] = arrayIn[index[j]]; info.OutputDataSample[j] = arrayOut[index[j]];
                    }

                    arrayIn  = Data.RemoveFromArray(arrayIn, index, poolSize);
                    arrayOut = Data.RemoveFromArray(arrayOut, index, poolSize);

                    //Create network.
                    network.Create(info.InputNumber, layersBar.Value, neuronsBar.Value, info.OutputNumber);
                    output.Text += "Training complete with an inaccuracy of: " + Math.Round(network.Train(info, (float)(learningRateBar.Value) / 10, (float)(momentumBar.Value) / 10), 10) + "\n\n";

                    double[][] answers = Data.CreateArray <double>(poolSize, info.InputData[0].Length);

                    //Compute outputs.
                    for (int j = 0; j < answers.Length; j++)
                    {
                        if (radBtnAccord.Checked)
                        {
                            if (!deepNetworkBox.Checked)
                            {
                                answers[j] = network.AccordNetwork.Compute(info.InputDataSample[j]);
                            }
                            else if (deepNetworkBox.Checked)
                            {
                                answers[j] = network.DeepAccordNetwork.Compute(info.InputDataSample[j]);
                            }
                        }
                        else
                        {
                            network.EncogNetwork.Compute(info.InputDataSample[j], answers[j]);
                        }
                    }

                    //Display network.
                    output.Text += network.Display(answers, analyst, info, outputTitles, path + @"normal\" + dataFile.Replace(".csv", "Normal.csv"));
                }
            }
            //Else percentage split.
            else
            {
                //Create network.
                network.Create(info.InputNumber, layersBar.Value, neuronsBar.Value, info.OutputNumber);
                output.Text += "Training complete with an inaccuracy of: " + Math.Round(network.Train(info, (float)(learningRateBar.Value) / 10, (float)(momentumBar.Value) / 10), 5) + "\n\n";

                double[][] answers = Data.CreateArray <double>(info.InputDataSample.Length, info.InputDataSample[0].Length);

                //Compute outputs.
                for (int i = 0; i < answers.Length; i++)
                {
                    if (radBtnAccord.Checked)
                    {
                        if (!deepNetworkBox.Checked)
                        {
                            answers[i] = network.AccordNetwork.Compute(info.InputDataSample[i]);
                        }
                        else if (deepNetworkBox.Checked)
                        {
                            answers[i] = network.DeepAccordNetwork.Compute(info.InputDataSample[i]);
                        }
                    }
                    else
                    {
                        network.EncogNetwork.Compute(info.InputDataSample[i], answers[i]);
                    }
                }

                //Display network.
                output.Text += network.Display(answers, analyst, info, outputTitles, path + @"normal\" + dataFile.Replace(".csv", "Normal.csv"));
            }
        }
        /// <summary> Predict network outputs. </summary>
        private void NetworkBtn_Click(object sender, EventArgs e)
        {
            if (networkSaveDataList.Count == 0)
            {
                MessageBox.Show("You must select a network file first. If you do not have one you can create one in the network creater window", "No Network File Error");
                return;
            }

            notIncluded.Clear();

            //Setup network.
            NeuralNetwork network;

            //Switch to set network type based on type stored in json file.
            switch (networkSaveDataList[selectedNetwork].NetworkType)
            {
            case "EncogNeuralNetwork":
            {
                network = new EncogNeuralNetwork();
                break;
            }

            case "EncogDeepNeuralNetwork":
            {
                network = new EncogDeepNeuralNetwork();
                break;
            }

            case "AccordNeuralNetwork":
            {
                network = new AccordNeuralNetwork();
                break;
            }

            default:
            {
                network = new AccordDeepNeuralNetwork();
                break;
            }
            }

            //Initialize variables
            info = new Data();
            string dataFile = networkSaveDataList[selectedNetwork].CsvFile;
            string path     = networkSaveDataList[selectedNetwork].Path;

            double[][] answers;

            if (!Directory.Exists(path + "normal"))
            {
                MessageBox.Show("You have no \"normal\" folder, please ensure that you are selecting the same csv as the one used in network creation. It may also be the case that you have moved the working directory of the csv file without also moving its dependant folders.", "File Access Error");
                return;
            }

            if (!Directory.Exists(path + "networks"))
            {
                MessageBox.Show("You have no \"networks\" folder, please ensure that you have created at least one network. It may also be the case that you have moved the working directory of the csv file without also moving its dependant folders.", "File Access Error");
                return;
            }

            //Load analyst from earlier.
            analyst = new EncogAnalyst();
            analyst.Load(new FileInfo(path + @"normal\normalizationData" + dataFile.Replace(".csv", ".ega")));

            FileInfo sourcefile = new FileInfo(path + dataFile);

            AnalystNormalizeCSV norm = new AnalystNormalizeCSV();

            //norm.InputHeadings = networkSaveDataList[selectedNetwork].Headings.ToArray();
            network.Load(networkSaveDataList[selectedNetwork].NetworkFile);

            List <bool> vb = new List <bool>();

            foreach (string heading in networkSaveDataList[selectedNetwork].InputHeadings)
            {
                vb.Add(false);
            }

            notIncluded.Add(vb);

            if (!csvBox.Checked)
            {
                string outString = "";

                for (int i = 0; i < items[selectedNetwork].Count; i++)
                {
                    notIncluded[0][i] = string.IsNullOrWhiteSpace(items[selectedNetwork][i]);

                    outString += items[selectedNetwork][i] + ",";
                }

                outString += ",";

                outString.Remove(outString.Length - 1);

                if (File.Exists(path + dataFile.Replace(".csv", "Temp.csv")))
                {
                    File.Delete(path + dataFile.Replace(".csv", "Temp.csv"));
                }

                using (var sw = new StreamWriter(path + dataFile.Replace(".csv", "Temp.csv"), true))
                {
                    for (int i = 0; i < networkSaveDataList[selectedNetwork].InputHeadings.Count; i++)
                    {
                        sw.Write(networkSaveDataList[selectedNetwork].InputHeadings[i] + ",");
                    }

                    for (int i = 0; i < networkSaveDataList[selectedNetwork].OutputHeadings.Count; i++)
                    {
                        if (i != networkSaveDataList[selectedNetwork].OutputHeadings.Count - 1)
                        {
                            sw.Write(networkSaveDataList[selectedNetwork].OutputHeadings[i] + ",");
                        }
                        else
                        {
                            sw.Write(networkSaveDataList[selectedNetwork].OutputHeadings[i]);
                        }
                    }

                    sw.WriteLine();
                    sw.WriteLine(outString);
                }

                var inputFile     = new FileInfo(path + dataFile.Replace(".csv", "Temp.csv"));
                var inputFileNorm = new FileInfo(path + @"normal\" + dataFile.Replace(".csv", "TempNormal.csv"));
                norm.Analyze(inputFile, true, CSVFormat.English, analyst);

                try
                {
                    norm.Normalize(inputFileNorm);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message + "\n\nThe inputs you have entered do not correctly follow the current normalisation data. This may because you " +
                                    "have entered values above or below the currently stored highs and lows for numbers. It is also possible you have " +
                                    "entered a textual word that has not been used before. Finally it is possible that you are have not used the correct " +
                                    "case for a word as they are case sensitive.", "Normalisation Failure");
                    return;
                }

                info    = info.ReturnInfo(path + @"normal\" + dataFile.Replace(".csv", "TempNormal.csv"), networkSaveDataList[selectedNetwork].OutputHeadings, 0, true);
                answers = Data.CreateArray <double>(1, info.OutputNumber);
            }
            else
            {
                //Reset paths.
                path = null; dataFile = null;

                //Get csv path.
                openFileDialog1.Filter = "csv files (*.csv)|*.csv";
                DialogResult dialogResult = openFileDialog1.ShowDialog();

                //Exit function if file selection was cancelled.
                if (dialogResult == DialogResult.Cancel)
                {
                    output.Text += "Cancelling File Selection. . .\n";
                    return;
                }

                //Check the file is .csv format.
                if (!openFileDialog1.SafeFileName.EndsWith(".csv"))
                {
                    MessageBox.Show("The file you have selected is not in the correct format (.csv)", "File Access Error");
                    return;
                }

                //Setup paths from file.
                dataFile = openFileDialog1.SafeFileName;
                path     = openFileDialog1.FileName.Replace(openFileDialog1.SafeFileName, "");
                var sourceFile = new FileInfo(openFileDialog1.FileName);
                var normalFile = new FileInfo(openFileDialog1.FileName.Replace(openFileDialog1.SafeFileName, @"normal\" + openFileDialog1.SafeFileName.Replace(".csv", "Normal.csv")));

                output.Text += "Loading File: " + dataFile + ". . .\n";

                Data.Normalise(sourceFile, normalFile, path, dataFile, networkSaveDataList[selectedNetwork].OutputHeadings.Count, false);

                norm.Analyze(sourceFile, true, CSVFormat.English, analyst);

                try
                {
                    norm.Normalize(normalFile);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message + "\n\nThe inputs you have entered do not correctly follow the current normalisation data. This may because you " +
                                    "have entered values above or below the currently stored highs and lows for numbers. It is also possible you have " +
                                    "entered a textual word that has not been used before. Finally it is possible that you are have not used the correct" +
                                    "case for a word as they are case sensitive.", "Normalisation Failure");
                    return;
                }

                info = info.ReturnInfo(path + @"normal\" + dataFile.Replace(".csv", "Normal.csv"), networkSaveDataList[selectedNetwork].OutputHeadings, 0, true);

                answers = Data.CreateArray <double>(info.InputData.Length, networkSaveDataList[selectedNetwork].OutputHeadings.Count);

                //Get length of CSV, Inputs and Outputs.
                using (var reader = new StreamReader(openFileDialog1.FileName))
                {
                    reader.ReadLine();
                    int lineNo = 0;

                    while (!reader.EndOfStream)
                    {
                        var line   = reader.ReadLine();
                        var values = line.Split(',');

                        if (lineNo > 0)
                        {
                            notIncluded.Add(new List <bool>(vb));
                        }

                        for (int i = 0; i < notIncluded[0].Count; i++)
                        {
                            notIncluded[lineNo][i] = string.IsNullOrWhiteSpace(values[i]);
                        }

                        lineNo++;
                    }
                }
            }

            //Compute network predictions.
            for (int i = 0; i < answers.Length; i++)
            {
                //Switch to set network type based on type stored in json file.
                switch (networkSaveDataList[selectedNetwork].NetworkType)
                {
                case "AccordNeuralNetwork":
                {
                    answers[i] = network.AccordNetwork.Compute(info.InputData[i]);
                    break;
                }

                case "AccordDeepNeuralNetwork":
                {
                    answers[i] = network.DeepAccordNetwork.Compute(info.InputData[i]);
                    break;
                }

                default:
                {
                    network.EncogNetwork.Compute(info.InputData[i], answers[i]);
                    break;
                }
                }
            }

            info.Prediction = answers;

            //Output answers to text box.
            output.Text += network.Display(answers, analyst, networkSaveDataList[selectedNetwork].OutputHeadings, path + @"normal\" + dataFile.Replace(".csv", "Normal.csv"));
        }