using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace AdvertsingProfitControl
{
    public partial class frmMain : Form
    {
        private double _gActualTotaSalesCalculatedTotal = 0;
        private double _gActualTotalProfitReturnCalculatedTotal = 0;
        private double _gCostOfSalesCalculatedTotal = 0;
        private List<string> _gDateStringCollection = new List<string>();
        readonly LogConsole _console = LogConsole.GetStaticInstance;

        public frmMain()
        {
            InitializeComponent();

            //Set the maximum and minimum sizes for the form.
            MaximumSize = new Size(1200, 650);
            MinimumSize = new Size(1000, 550);
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            FillDateSuggestionComboBoxes();
            BuildAndFillDataGridTables();
            CalculateProfitAnalysis();
            CalculateGrossProfit();

            _console.Show();
        }

        private void UpdateDataGridViewInformation(object sender, EventArgs e)
        {
            string dateString = monthComboBox.Text + "/" + dayComboBox.Text + "/" + yearComboBox.Text;
            BuildAndFillDataGridTables(dateString);
            CalculateProfitAnalysis();
            CalculateGrossProfit();
        }

        /// <summary>
        /// Builds and fills the DataGridView tables on the main form 
        /// from the either the most recent date or the date specified in the parameter.
        /// </summary>
        /// <param name="dateString">The date of records to display to the user, if no date is specified then the most recent date is used.</param>
        private void BuildAndFillDataGridTables(string dateString = "")
        {
            //Deprecated
            var dataBaseReader = new RetrieveFromDatabase();
            //
            var dateId = "";

            //Check to see if a parameter has been passed.
            if (dateString == "")
            {
                //IF non were, then grab the most recent date ID from the database and use that.
                dateId = dataBaseReader.RetrieveMostRecentDateId();
                _console.WriteToLog(LogConsole.Level.Info,  dateId != "-1" ? "Most recent date ID is " + dateId : "Most recent date ID is unavailable.");
            }
            else
            {
                //ELSE IF one was passed, then use it's ID to build the tables.
                dateId = dataBaseReader.RetrieveDateIdByDateString(dateString);
                _console.WriteToLog(LogConsole.Level.Info, dateId != "-1" ? "Date ID for " + dateString + " is resolved to have the ID of " + dateId + "." : "The date " + dateString + " could not be found in the database.");
                if (dateId == "-1")
                {
                    _gDateStringCollection.Remove(dateString);
                }
            }
            //Now check to make sure there were no errors grabbing the ID, IF there were return.
            if (dateId == "-1") return;
            //Clear the class global variables to prevents calculation mishaps.
            _gActualTotaSalesCalculatedTotal = 0;
            _gActualTotalProfitReturnCalculatedTotal = 0;
            _gCostOfSalesCalculatedTotal = 0;
            //Clear all DataGridViews since the date supplied is valid and in the database.
            projectedSalesMainDataGrid.DataSource = null;
            inventoryDataGridView.DataSource = null;
            actualSalesMainDataGidView.DataSource = null;
            suppliersDataGridView.DataSource = null;
            weeklySalesDataGridView.DataSource = null;
            var indexOfAdSpecialRow = -1;
            var regexGroupCategoryparser = new Regex(@"^(\d)?\|\d");
            //Begin by grabbing the Projections table
            var tempTable = dataBaseReader.ReturnProjectionsTable(dateId);
            if (tempTable.Rows.Count > 0)
            {
                projectedSalesMainDataGrid.DataSource = SumSalesTable(tempTable);
                string adCategory = "";
                for (var i = 0; i < projectedSalesMainDataGrid.Rows.Count; i++)
                {
                    int castedValue = 0;
                    if ((string)projectedSalesMainDataGrid.Rows[i].Cells[7].EditedFormattedValue == "1")
                    {
                        projectedSalesMainDataGrid.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
                    }else if ((string) projectedSalesMainDataGrid.Rows[i].Cells[7].EditedFormattedValue == "2")
                    {
                        projectedSalesMainDataGrid.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
                    }
                    else if (
                        regexGroupCategoryparser.IsMatch(
                            (string) projectedSalesMainDataGrid.Rows[i].Cells[7].EditedFormattedValue))
                    {
                        string[] spam = new string[2];
                        spam = ParseAdSpecialRows(projectedSalesMainDataGrid.Rows[i].Cells[7].EditedFormattedValue.ToString());
                        if (spam.Length > 1)
                        {
                            adCategory = spam[1];
                        }
                        else
                        {
                            adCategory = spam[0];
                        }
                        if (indexOfAdSpecialRow == -1)
                        {
                             indexOfAdSpecialRow = i;   
                        }

                        if (spam[0] == "1")
                        {
                            projectedSalesMainDataGrid.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
                        }else if (spam[0] == "2")
                        {
                            projectedSalesMainDataGrid.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
                        }
                    }
                }
                var dataGridViewColumn = projectedSalesMainDataGrid.Columns["FK_GroupID"];
                if (dataGridViewColumn != null)
                    dataGridViewColumn.Visible = false;
            }

            //Grabbing the Inventory table
            tempTable = dataBaseReader.ReturnInventoryTable(dateId);
            if (tempTable.Rows.Count > 0)
            {
                inventoryDataGridView.DataSource = tempTable;
                string adCategory = "";
                for (var i = 0; i < inventoryDataGridView.Rows.Count; i++)
                {
                    int castedValue = 0;
                    if ((string)inventoryDataGridView.Rows[i].Cells[5].EditedFormattedValue == "1")
                    {
                        inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
                    }
                    else if ((string)inventoryDataGridView.Rows[i].Cells[5].EditedFormattedValue == "2")
                    {
                        inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
                    }
                    else if (
                        regexGroupCategoryparser.IsMatch(
                            (string)inventoryDataGridView.Rows[i].Cells[5].EditedFormattedValue))
                    {
                        string[] spam = new string[2];
                        spam = ParseAdSpecialRows(inventoryDataGridView.Rows[i].Cells[5].EditedFormattedValue.ToString());
                        if (spam.Length > 1)
                        {
                            adCategory = spam[1];
                        }
                        else
                        {
                            adCategory = spam[0];
                        }

                        if (spam[0] == "1")
                        {
                            inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
                        }
                        else if (spam[0] == "2")
                        {
                            inventoryDataGridView.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
                        }
                    }
                }
                var dataGridViewColumn = inventoryDataGridView.Columns["FK_GroupID"];
                if (dataGridViewColumn != null)
                    dataGridViewColumn.Visible = false;
            }

            //And the Actual Sales table
            tempTable = dataBaseReader.ReturnActualSales(dateId);
            if (tempTable.Rows.Count > 0)
            {
                actualSalesMainDataGidView.DataSource = SumSalesTable(tempTable);
                string adCategory = "";
                for (var i = 0; i < actualSalesMainDataGidView.Rows.Count; i++)
                {
                    int castedValue = 0;
                    if ((string)actualSalesMainDataGidView.Rows[i].Cells[7].EditedFormattedValue == "1")
                    {
                        actualSalesMainDataGidView.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
                    }
                    else if ((string)actualSalesMainDataGidView.Rows[i].Cells[7].EditedFormattedValue == "2")
                    {
                        actualSalesMainDataGidView.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
                    }
                    else if (
                        regexGroupCategoryparser.IsMatch(
                            (string)actualSalesMainDataGidView.Rows[i].Cells[7].EditedFormattedValue))
                    {
                        string[] spam = new string[2];
                        spam = ParseAdSpecialRows(actualSalesMainDataGidView.Rows[i].Cells[7].EditedFormattedValue.ToString());
                        if (spam.Length > 1)
                        {
                            adCategory = spam[1];
                        }
                        else
                        {
                            adCategory = spam[0];
                        }

                        if (spam[0] == "1")
                        {
                            actualSalesMainDataGidView.Rows[i].DefaultCellStyle.BackColor = Color.LightGray;
                        }
                        else if (spam[0] == "2")
                        {
                            actualSalesMainDataGidView.Rows[i].DefaultCellStyle.BackColor = Color.LightBlue;
                        }
                    }
                }
                var year = actualSalesMainDataGidView.Columns["FK_GroupID"];
                if (year != null)
                    year.Visible = false;
            }

            //Next the Invoices table
            tempTable = dataBaseReader.ReturnInvoiceTable(dateId);
            if (tempTable.Rows.Count > 0)
            {
                suppliersDataGridView.DataSource = SumCostOfSales(tempTable);
            }

            //And finally the weekly sales
            tempTable = dataBaseReader.ReturnWeeklySalesFromDateID(dateId);
            if (tempTable.Rows.Count > 0)
            {
                weeklySalesDataGridView.DataSource = tempTable;
            }

            commentsTextBox.Text = dataBaseReader.RetrieveComments(dateId);
        }

        private void CalculateProfitAnalysis(double shrink = 0.30)
        {
            if (Math.Abs(_gActualTotaSalesCalculatedTotal) < 1 || Math.Abs(_gActualTotalProfitReturnCalculatedTotal) < 1)
            {
                //Clear the labels...
                if (weeklySalesDataGridView.Rows.Count == 0 || weeklySalesDataGridView.Rows[0].Cells[7].EditedFormattedValue.ToString() == "0.0000")
                {
                    departmentSalesLabel.Text = "Department Sales: No Weekly Sales Found.";
                    departmentSalesLabel.ForeColor = Color.Red;
                }

                if (_gActualTotaSalesCalculatedTotal == 0)
                {
                    salesProducedLabel.Text = "Sales Produced By Ad Items (A): No Values to Total.";
                    salesProducedLabel.ForeColor = Color.Red;
                }

                remainingSalesLabel.Text = "Remaining Sales: ";
                if (_gActualTotalProfitReturnCalculatedTotal == 0)
                {
                    totalProfitFromAdItemsLabel.Text = "Total Profit Return From Ad Items (B): No Values to Total.";
                    totalProfitFromAdItemsLabel.ForeColor = Color.Red;
                }

                totalProfitReturnFromRemaingLabel.Text = "Total Profit Return From Remaining Sales: ";
                totalProfitReturnLabel.Text = "Total Profit Return: ";
                return;
            }
            double departmentSales = 0;
            Double.TryParse(weeklySalesDataGridView.Rows[0].Cells[7].EditedFormattedValue.ToString(), out departmentSales);
            //Since there are department sales, change the label's color to make sure it doesn't appear as an error.
            departmentSalesLabel.ForeColor = Color.Black;
            departmentSalesLabel.Text = "Department Sales: " + departmentSales.ToString("C");
            //Assume that the sales produced is larger then zero (0).
            salesProducedLabel.ForeColor = Color.Black;
            salesProducedLabel.Text = "Sales Produced By Ad Items (A): " + _gActualTotaSalesCalculatedTotal.ToString("C");

            double remainingSales = departmentSales - _gActualTotaSalesCalculatedTotal;
            remainingSalesLabel.Text = "Remaining Sales: " + remainingSales.ToString("C");
            //Again assume the total profit return is larger then zero (0).
            totalProfitFromAdItemsLabel.ForeColor = Color.Black;
            totalProfitFromAdItemsLabel.Text = "Total Profit Return From Ad Items (B): " + _gActualTotalProfitReturnCalculatedTotal.ToString("C");
            //Shrink is being used as a place holder for Cross Profit % which is obtained by dividing gActualTotalProfitReturnCalculatedTotal by the department weekly retail sales.
            double totalProfitReturnFromRemainingSales = shrink * remainingSales;
            //
            totalProfitReturnFromRemaingLabel.Text = "Total Profit Return From Remaining Sales: " + totalProfitReturnFromRemainingSales.ToString("C");
            double totalProfitReturn = _gActualTotalProfitReturnCalculatedTotal + totalProfitReturnFromRemainingSales;
            totalProfitReturnLabel.Text = "Total Profit Return: " + totalProfitReturn.ToString("C");
        }

        private void CalculateCostOfSales()
        {
            //?
        }

        private void CalculateGrossProfit()
        {
            if (Math.Abs(_gCostOfSalesCalculatedTotal) < 1)
            {
                //IF Cost of Sales hasn't been calculated, then clear labels and return.
                if (weeklySalesDataGridView.Rows.Count == 0 || weeklySalesDataGridView.Rows[0].Cells[7].EditedFormattedValue.ToString() == "0.0000")
                {
                    grossProfitTotalSales.Text = "Total Sales: No Weekly Sales Found.";
                    grossProfitTotalSales.ForeColor = Color.Red;
                }
                grossProfitLessCostOfSales.Text = "Less Cost of Sales: ";
                grossProfitDollarGrossProfitLabel.Text = "Dollar Gross Profit: ";
                perfectGrossProfitLabel.Text = "Percent Gross Profit: ";
                return;
            }

            double totalSales = Convert.ToDouble(weeklySalesDataGridView.Rows[0].Cells[7].EditedFormattedValue.ToString());
            grossProfitTotalSales.ForeColor = Color.Black;
            grossProfitTotalSales.Text = "Total Sales: " + totalSales.ToString("C");
            grossProfitLessCostOfSales.Text = "Less Cost of Sales: " + _gCostOfSalesCalculatedTotal.ToString("C");
            double dollarGrossProfit = totalSales - _gCostOfSalesCalculatedTotal;
            grossProfitDollarGrossProfitLabel.Text = "Dollar Gross Profit: " + dollarGrossProfit.ToString("C");
            double grossProfitPercent = dollarGrossProfit / totalSales;
            perfectGrossProfitLabel.Text = "Percent Gross Profit: " + grossProfitPercent.ToString("P");
        }

        private void addRecordToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmAddRecord recordForm = new frmAddRecord();
            recordForm.ShowDialog();
            FillDateSuggestionComboBoxes();
            BuildAndFillDataGridTables();
            CalculateProfitAnalysis();
            CalculateGrossProfit();
        }

        /// <summary>
        /// Appends a new "Totals" row to the end of the DataTable that is passed in
        /// and sums up the Total Sales and Total Profit Return columns as well as 
        /// storing the Total Sales and Total Profit Return in their respective 
        /// class wide variables for use with other functions.
        /// </summary>
        /// <param name="table">The sales table to be summed up.</param>
        /// <returns></returns>
        private DataTable SumSalesTable(DataTable table)
        {
            //IF the table is null OR has an invalid column count then return.
            if (table == null || table.Columns.Count < 7) return table;

            //Both Projections and Actual tables have the Total Sales and Total Profit Return columns in the same position,
            //indexes three (3) and six (6) respectively.
            double totalSalesSum = 0;
            double totalProfitReturnSum = 0;

            for (var i = 0; i < table.Rows.Count; i++)
            {
                totalSalesSum += Convert.ToDouble(table.Rows[i][3]);
                totalProfitReturnSum += Convert.ToDouble(table.Rows[i][6]);
            }

            //Once the totals have been calculated store them in the class wide variables so other methods can use them.
            _gActualTotaSalesCalculatedTotal = totalSalesSum;
            _gActualTotalProfitReturnCalculatedTotal = totalProfitReturnSum;
            //Create an object array to store the summed values and add them at the end to the table before returning it.
            object[] rowContents = new object[table.Columns.Count];
            rowContents[0] = "Total";
            rowContents[3] = totalSalesSum;
            rowContents[6] = totalProfitReturnSum;
            table.Rows.Add(rowContents);
            return table;
        }

        /// <summary>
        /// Appends a new "Totals" row to the end of the Invoice table that is passed in
        /// and sums up the Net Cost of Invoices column as well as storing the total Costs of Sales
        /// into the class wide variable for use with other functions.
        /// </summary>
        /// <param name="invoiceTable">The Invoice table to summed.</param>
        /// <returns></returns>
        private DataTable SumCostOfSales(DataTable invoiceTable)
        {
            //Check for a null parameter OR if the column count is less then six (6) as any less means the database isn't returning correctly.
            if(invoiceTable == null || invoiceTable.Columns.Count < 6) return invoiceTable;
            double costOfSalesSum = 0;

            for (var i = 0; i < invoiceTable.Rows.Count; i++)
            {
                costOfSalesSum += Convert.ToDouble(invoiceTable.Rows[i][4]);
            }

            _gCostOfSalesCalculatedTotal = costOfSalesSum;

            object[] invoiceTotalRow = new object[invoiceTable.Columns.Count];
            invoiceTotalRow[0] = "Total Purchases";
            invoiceTotalRow[4] = costOfSalesSum;
            invoiceTable.Rows.Add(invoiceTotalRow);

            return invoiceTable;
        }

        private void showHideConsoleHelpMainMenu_Click(object sender, EventArgs e)
        {
            if (_console.IsVisable)
            {
                _console.Hide();
            }
            else
            {
                _console.Show();
            }
 
        }

        /// <summary>
        /// Grabs all dates from the database and splits the returned strings 
        /// into months, days, and years and stores them in their respective 
        /// combo boxes to display to the user. Also stores the list of dates
        /// inside a class wide variable.
        /// </summary>
        private void FillDateSuggestionComboBoxes()
        {
            //Create a connection to the database retrieval class.
            var dbReader = new RetrieveFromDatabase();
            //Grab the most recent date in the database.
            var mostRecentDateTime = dbReader.ReturnMostRecentDateString();
            var mostRecentDateString = mostRecentDateTime.ToString("MM/dd/yyyy");
            //Check to see if the return value is null and IF so log the error and return.
            if(mostRecentDateString == ""){ _console.WriteToLog(LogConsole.Level.Error, "No dates could be found in the database."); return;}
            //Otherwise, if there was a return date, split it into a array.
            var mostRecentDateParts = mostRecentDateString.Split('/');
            //Grab only the most recent years in the database (only say 2015) and fill a table with the dates. Indexes are as follows: [0] is Month, [1] is Day and [2] is Year.
            DataTable oneYearDatesTable = dbReader.ReturnDateStringsLike(mostRecentDateParts[0] + "/" + mostRecentDateParts[1] + "/" + mostRecentDateParts[2]);
            //Suspend the control's drawing so the user doesn't see any ugly enumeration and index changing.
            DrawingControl.SuspendDrawing(dateSelectorPanel);
            //Considering there was a return value for the most recent date, its safe to assume there is at least one date in the database, so clear the class's date collection.
            _gDateStringCollection.Clear();
            monthComboBox.Items.Clear();
            dayComboBox.Items.Clear();
            yearComboBox.Items.Clear();
            monthComboBox.SelectedIndexChanged -= UpdateDaysOfMonth;
            dayComboBox.SelectedIndexChanged -= UpdateDataGridViewInformation;
            yearComboBox.SelectedIndexChanged -= UpdateDaysOfMonthByYear;
            //Now spin through the oneYearDatesTable and fill the class wide object with all the dates for the most recent year.
            for (var i = 0; i < oneYearDatesTable.Rows.Count; i ++)
            {
                var fullDateTime = (DateTime) oneYearDatesTable.Rows[i][0];
                var fullDateString = fullDateTime.ToString("MM/dd/yyyy");
                //Check for nulls just to be paranoid.
                if (fullDateString == "")
                {
                    return;
                }
                //IF the date string collection already contains the date, then continue to the next iteration.
                if (_gDateStringCollection.Contains(fullDateString))
                {
                    continue;
                }
                _gDateStringCollection.Add(fullDateString);
            }

            var dayBasedOnMonthAndYeaRegex = new Regex("^0?" + mostRecentDateParts[0] + @"/\d{2}/" + mostRecentDateParts[2]);
            var monthBasedOnYearRegex = new Regex(@"^\d{2}/\d{2}/" + mostRecentDateParts[2]);
            for (var i = 0; i < _gDateStringCollection.Count; i++)
            {
                string[] dateArray = _gDateStringCollection[i].Split('/');
                var month = dateArray[0];
                var day =dateArray[1];

                if (dayBasedOnMonthAndYeaRegex.IsMatch(_gDateStringCollection[i]))
                {
                    dayComboBox.Items.Add(day);
                }
                if (monthBasedOnYearRegex.IsMatch(_gDateStringCollection[i]))
                {
                    if (!monthComboBox.Items.Contains(month))
                    {
                        monthComboBox.Items.Add(month);
                    }
                }
            }

            var yearsInDatabase = dbReader.ReturnUniqueYearsList();

            foreach (var year in yearsInDatabase)
            {
                yearComboBox.Items.Add(year);
            }

            if (dayComboBox.Items.Count >= 1 && yearComboBox.Items.Count >= 1 && monthComboBox.Items.Count >= 1)
            {
                monthComboBox.SelectedIndex = monthComboBox.Items.Count - 1;
                dayComboBox.SelectedIndex = dayComboBox.Items.Count - 1;
                yearComboBox.SelectedIndex = yearComboBox.Items.Count - 1;
                monthComboBox.Enabled = true;
                dayComboBox.Enabled = true;
                yearComboBox.Enabled = true;
            }
            else
            {
                monthComboBox.Enabled = false;
                dayComboBox.Enabled = false;
                yearComboBox.Enabled = false;
            }
            monthComboBox.SelectedIndexChanged += UpdateDaysOfMonth;
            dayComboBox.SelectedIndexChanged += UpdateDataGridViewInformation;
            yearComboBox.SelectedIndexChanged += UpdateDaysOfMonthByYear;
            DrawingControl.ResumeDrawing(dateSelectorPanel);
        }

        private void UpdateDaysOfMonth(object sender, EventArgs e)
        {
            if (yearComboBox.SelectedIndex == -1) return; 
            var year = yearComboBox.SelectedItem.ToString();
            var month = monthComboBox.SelectedItem.ToString();
            var dateParserPattern = new Regex("^" + month + @"\/\d{2}\/" + year);

            dayComboBox.Items.Clear();

            for (var i = 0; i < _gDateStringCollection.Count; i++)
            {
                if (dateParserPattern.IsMatch(_gDateStringCollection[i]))
                {
                    var dateArray = _gDateStringCollection[i].Split('/');
                    var day = dateArray[1];
                    dayComboBox.Items.Add(day);
                }
            }

            if (dayComboBox.Items.Count > 0)
            {
                dayComboBox.SelectedIndex = dayComboBox.Items.Count - 1;
            }

            CalculateProfitAnalysis();
            CalculateGrossProfit();
        }
        /// <summary>
        /// Fires when the Year combo box's index changes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UpdateDaysOfMonthByYear(object sender, EventArgs e)
        {
            //Obligatory database retrieval call...
            var dbReader = new RetrieveFromDatabase();
            //First, grab the year and the month from their respective combo boxes.
            var year = yearComboBox.SelectedItem.ToString();
            var month = monthComboBox.SelectedItem.ToString();
            //Since we can more or less be certain that nothing is null, clear the current date collection.
            _gDateStringCollection.Clear();
            var months = dbReader.ReturnUniqueMonthsList(month + "/" + dayComboBox.SelectedItem + "/" + year);
            var mostRecentMonth = months.Max();
            if (mostRecentMonth.Length == 1)
            {
                mostRecentMonth = "0" + mostRecentMonth;
            }
            var selectedYearDates = dbReader.ReturnDateStringsLike(month + "/" + dayComboBox.SelectedItem + "/" + year);
  
            for (var i = 0; i < selectedYearDates.Rows.Count; i++)
            {
                var trimmedDateString = (DateTime) selectedYearDates.Rows[i][0];
                _gDateStringCollection.Add(trimmedDateString.ToString("MM/dd/yyyy"));
            }

            //Clear the month and day combo boxes and unregister their event handlers.
            dayComboBox.Items.Clear();
            monthComboBox.Items.Clear();
            monthComboBox.SelectedIndexChanged -= UpdateDaysOfMonth;
            dayComboBox.SelectedIndexChanged -= UpdateDataGridViewInformation;
            for (var i = 0; i < _gDateStringCollection.Count; i ++)
            {
                var dateArray = _gDateStringCollection[i].Split('/');
                month = dateArray[0];
                //Declare the patterns to look for when enumerating the combo boxes.
                var dayBasedOnMonthAndYeaRegex = new Regex(@"^(" + mostRecentMonth + @"\/\d{2}\/" + year + ")"); //Only allows days that are actually part of the month and year.
                var day = dateArray[1];

                if (dayBasedOnMonthAndYeaRegex.IsMatch(_gDateStringCollection[i]))
                {
                    dayComboBox.Items.Add(day);
                }

                if (!monthComboBox.Items.Contains(month))
                {
                    monthComboBox.Items.Add(month);   
                }
            }

            if (dayComboBox.Items.Count > 0)
            {
                dayComboBox.SelectedIndex = dayComboBox.Items.Count - 1;
            }
            if (monthComboBox.Items.Count > 0)
            {
                monthComboBox.SelectedIndex = monthComboBox.Items.Count - 1;
            }

            //Now re-register the event handlers
            monthComboBox.SelectedIndexChanged += UpdateDaysOfMonth;
            dayComboBox.SelectedIndexChanged += UpdateDataGridViewInformation;

            BuildAndFillDataGridTables(monthComboBox.SelectedItem + "/" + dayComboBox.SelectedItem + "/" + year);
            CalculateProfitAnalysis();
            CalculateGrossProfit();
        }

        private string[] ParseAdSpecialRows(string groupIdentifier)
        {
            var groupCategory = new string[2];
            var dbReader = new RetrieveFromDatabase();
            var patternForOnlyPipeAndAdSpecial = new Regex(@"^\|\d{1}");
            var patternForBothNumbersOnPipe = new Regex(@"^\d{1}\|\d{1}");

            if (patternForOnlyPipeAndAdSpecial.IsMatch(groupIdentifier))
            {
                groupCategory[0] = groupIdentifier;
                if (groupIdentifier[0].ToString() != "")
                {
                    groupCategory[0] = groupCategory[0].Replace("|", "");
                    groupCategory[0] = dbReader.ReturnGroupNameFromGroupId(groupCategory[0]);
                }      
            }else if (patternForBothNumbersOnPipe.IsMatch(groupIdentifier))
            {
                string[] temp = groupIdentifier.Split('|');
                groupCategory[0] = temp[0];
                groupCategory[1] = temp[1];

                groupCategory[1] = dbReader.ReturnGroupNameFromGroupId(groupCategory[1]);
            }

            return groupCategory;
        }

        private void adSpecialKeyWordsToolsMainMenu_Click(object sender, EventArgs e)
        {
            var keyWordRegister = new frmAdSpecialRegister();
            keyWordRegister.ShowDialog();
        }

        private void deleteRecordsMainMenu_Click(object sender, EventArgs e)
        {
            var frmDeleteRecord = new frmDeleteRecord();
            frmDeleteRecord.ShowDialog();
            FillDateSuggestionComboBoxes();
            BuildAndFillDataGridTables();
            CalculateProfitAnalysis();
            CalculateGrossProfit();
        }
    }

    //http://stackoverflow.com/questions/487661/how-do-i-suspend-painting-for-a-control-and-its-children
    class DrawingControl
    {
        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);

        private const int WM_SETREDRAW = 11;

        public static void SuspendDrawing(Control parent)
        {
            SendMessage(parent.Handle, WM_SETREDRAW, false, 0);
        }

        public static void ResumeDrawing(Control parent)
        {
            SendMessage(parent.Handle, WM_SETREDRAW, true, 0);
            parent.Refresh();
        }
    }
}
