private void tabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (logTab.Items.Count > 0)
            {
                rxList.ItemsSource = allMessageLists[logTab.SelectedIndex].messageGroups;
            }

            if (logTab.SelectedIndex != -1)
            {
                string[] firstLastDate = allMessageLists[logTab.SelectedIndex].firstLastDates;  //Throws ArgumentOutOfRangeException when doing fresh run after first run (SelectedIndex = -1)
                runLabel.Content       = "Run Time: " + firstLastDate[0] + " to " + firstLastDate[1];
                runLengthLabel.Content = "Run Lasted: " + LogAnalyzerLogic.getTimeStringInRun(firstLastDate);
            }

            if (doubleFilter)
            {
                readyToSearch = true;
                CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(rxList.ItemsSource);
                view.Filter = ZeroFilter;
            }
            else
            {
                readyToSearch = true;
                CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(rxList.ItemsSource);
                view.Filter = LogFilter;
            }
        }
        // analyzes the log files, returning a Dictionary of string and List of strings
        private async Task analyzeLogs(string[] runFileNames, int messageListIndex)
        {
            ConcurrentDictionary <string, List <string> > messages = new ConcurrentDictionary <string, List <string> >();
            //add all regexexpressions as keys so no conflicts later, empty string list as value

            Dictionary <string, List <string> > fullLinesDict = regexExpressions.Item2;

            foreach (KeyValuePair <string, List <string> > kvp in fullLinesDict)
            {
                for (int i = 0; i < kvp.Value.Count; i++)
                {
                    if (!messages.ContainsKey(kvp.Value[i]))
                    {
                        messages.GetOrAdd(kvp.Value[i], new List <string>());
                    }
                }
            }
            //go through all files of run
            int threadsForFiles = Environment.ProcessorCount - 1; // NUMBER OF FILES TO CHECK AT THE SAME TIME (cores - 1), - 1 for main thread

            for (int i = 0; i < runFileNames.Length; i += threadsForFiles)
            {
                if (i + threadsForFiles > runFileNames.Length)
                {
                    threadsForFiles = runFileNames.Length - i;
                }
                Task[] tasks = new Task[threadsForFiles];
                for (int j = 0; j < threadsForFiles; j++)
                {
                    int indx = i + j;
                    tasks[j] = Task.Run(() => LogAnalyzerLogic.parseFile(runFileNames[indx], regexExpressions, messages, classAndNumDict));
                }
                await Task.WhenAll(tasks);

                messagesList[messageListIndex] = messages.ToDictionary(kvp => kvp.Key,
                                                                       kvp => kvp.Value); // set messages list after each file parse

                //change UI

                filesProcessedText.Text = (i + threadsForFiles) + "/" + runs[messageListIndex].Length + "  Files of Run Processed";
                updateRxList(messageListIndex);
            }

            //  return messages;
        }
        private void fileButton_Click(object sender, RoutedEventArgs e)
        {
            // Create OpenFileDialog
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();

            Nullable <bool> result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox
            if (result == true)
            {
                //show file name
                string filename = dlg.FileName;
                classAndNumDict        = LogAnalyzerLogic.getClassAndNum(filename);
                regexExpressions       = LogAnalyzerLogic.getRegEx(filename);
                fileNameBox.Text       = filename;
                buildNo                = "Build No. " + LogAnalyzerLogic.getBuildNo(filename);
                buildLabel.Content     = buildNo;
                folderButton.IsEnabled = true;
            }
        }
        private void updateRxList(int index)
        {
            List <MessageGroup> mg = new List <MessageGroup>();
            Dictionary <string, List <string> > dict    = messagesList[index];
            Dictionary <string, bool>           checker = new Dictionary <string, bool>();

            foreach (KeyValuePair <string, List <string> > kvp in regexExpressions.Item2)
            {
                double seconds = LogAnalyzerLogic.getSecondsInRun(allMessageLists[index].firstLastDates);
                double minutes = seconds / 60;
                //prints out the date and corresponding message for now; change later
                for (int i = 0; i < kvp.Value.Count; i++)
                {
                    int avgCountSec = (int)((dict[kvp.Value[i]].Count) / seconds);
                    int avgCountMin = (int)((dict[kvp.Value[i]].Count) / minutes);
                    if (!checker.ContainsKey(regexExpressions.Item2[kvp.Key][i]))
                    {
                        mg.Add(new MessageGroup(avgCountSec, dict[kvp.Value[i]].Count,
                                                regexExpressions.Item2[kvp.Key][i], kvp.Value[i], avgCountMin, dict[kvp.Value[i]]));
                        checker.Add(regexExpressions.Item2[kvp.Key][i], true);
                    }
                }
            }
            allMessageLists[index].messageGroups = mg;
            rxList.ItemsSource = allMessageLists[logTab.SelectedIndex].messageGroups;


            if (doubleFilter)
            {
                readyToSearch = true;
                CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(rxList.ItemsSource);
                view.Filter = ZeroFilter;
            }
            else
            {
                readyToSearch = true;
                CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(rxList.ItemsSource);
                view.Filter = LogFilter;
            }
        }
        private void analyzeButton_Click(object sender, RoutedEventArgs e)
        {
            string[] fileNames         = Directory.GetFiles(folderSelectedPath);
            string[] fileNamesOnlyLogs = LogAnalyzerLogic.removeNonLogFiles(fileNames).ToArray();
            runs = LogAnalyzerLogic.runSplitter(fileNamesOnlyLogs);

            logTab.Visibility = Visibility.Visible;
            messagesList      = null;
            logTab.Items.Clear(); // clear all tabs if usre pressed analyze again on new things

            logTab.SelectedIndex = 0;

            messagesList = new List <Dictionary <string, List <string> > >();

            List <string[]> firstLastDate = LogAnalyzerLogic.getFirstLastDates(runs);

            runLabel.Content       = "Run Time: " + firstLastDate[0][0] + " to " + firstLastDate[0][1];
            runLengthLabel.Content = "Run Lasted: " + LogAnalyzerLogic.getTimeStringInRun(firstLastDate[0]);

            // CREATE ALL MESSAGE LIST AND INITIALIZE WITH BLANK LISTS
            allMessageLists = new List <RunMessageList>();
            for (int i = 0; i < runs.Count; i++)
            {
                allMessageLists.Add(new RunMessageList(new List <MessageGroup>(), LogAnalyzerLogic.getRunName(runs[i][0]), firstLastDate[i], buildNo));
            }

            runsProcessedText.Text  = 0 + "/" + runs.Count + "  Runs Processed";
            filesProcessedText.Text = 0 + "/" + runs[0].Length + "  Files of Run Processed";

            // disable all buttons while analyzing
            analyzeButton.IsEnabled  = false;
            folderButton.IsEnabled   = false;
            fileButton.IsEnabled     = false;
            graphAllButton.IsEnabled = false;

            analyzeAllLogs();
        }