private void btnReinitializeProductPriceHistory_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show("Delete product price history and reinitialize from the original product prices? Are you sure?", "This will delete all product price history!", MessageBoxButtons.OKCancel);

            if (result == DialogResult.OK)
            {
                ProductPriceHist.InitializeProductPriceHistAndCopyFromFromProductTable(Config.earliestPossibleDate);
            }
        }
        private void btnCalcNewProductPrice_Click(object sender, EventArgs e)
        {
            // ProductPriceHist.AddProductPriceHist(Config.random); // Add a new price for a random product/store. This isn't all that useful.

            DialogResult result = MessageBox.Show("Update all product prices at all stores for " + txtStartDate.Text + "? Are you sure?", "This could take a while.", MessageBoxButtons.OKCancel);

            if (result == DialogResult.OK)
            {
                try {
                    DateTime myStartDate = DateTime.Parse(txtStartDate.Text);
                    ProductPriceHist.UpdateAllProductStorePrices(Config.random, txtProductPriceHist, DateTime.Parse(txtStartDate.Text));
                } catch (Exception ex) {
                    Utils.Log(ex.Message);
                    MessageBox.Show("Start Date is invalid. Cannot process product price history.", "Check start date");
                }
            }
        }
        private void btnStartTransactionSimulator_Click(object sender, EventArgs e)
        {
            TextBox.CheckForIllegalCrossThreadCalls = false;    // We will spawn a thread that writes to a control on this thread.
            Boolean  validInput = true;
            DateTime startDate = DateTime.Now, throughDate = DateTime.Now;

            switch (Config.mode)
            {
            case Config.modeEnum.idle:
                try {
                    // Check to see if the user wants to run for a period of elapsed time or run forever
                    if (cbIgnoreElapsedTime.Checked == true)
                    {
                        Config.elapsedMinutesToRun = 0;         // zero means ignore this limit
                    }
                    else
                    {
                        int      hours = 0, minutes = 0;
                        String[] split = txtElapsedTimeToRun.Text.Trim().Split(':');
                        hours = Convert.ToInt32(split[0]);
                        if (split.Length == 2)
                        {
                            minutes = Convert.ToInt32(split[1]);
                        }
                        Config.elapsedMinutesToRun = hours * 60 + minutes;
                    }
                } catch (Exception ex) {
                    validInput = false;
                    MessageBox.Show("Input error: " + ex.Message, "Check Hours:Minutes to run.");
                }
                try {
                    Config.setTransactionDelay(Convert.ToInt32(txtTransactionDelay.Text));
                } catch (Exception ex) {
                    MessageBox.Show("Input error: " + ex.Message, "Check Transaction Delay.");
                    Utils.Log(ex.Message);
                    validInput = false;
                }
                if (validInput && !cbUseCurrentDateStampForTransaction.Checked)
                {
                    try {
                        // Don't store these values in the Config object unless both are valid.
                        startDate   = Convert.ToDateTime(txtStartDate.Text);
                        throughDate = Convert.ToDateTime(txtThroughDate.Text);
                        if ((throughDate - startDate).TotalDays < 0)
                        {
                            throw new Exception("Through Date must follow or equal Start Date.");
                        }
                        if (startDate < Config.earliestPossibleDate)
                        {
                            throw new Exception("Start date cannot be earlier than " + Config.earliestPossibleDate.ToShortDateString());
                        }
                    } catch (Exception ex) {
                        validInput = false;
                        MessageBox.Show("Input error: " + ex.Message, "Check Start Date and Through Date.");
                    }
                }
                if (validInput)
                {
                    Config.useCurrentDateStampForTransaction = cbUseCurrentDateStampForTransaction.Checked;
                    Config.startDate              = startDate;
                    Config.throughDate            = throughDate;
                    Config.mode                   = Config.modeEnum.running;
                    Config.server                 = txtServer.Text;
                    Config.login                  = txtLogin.Text;
                    Config.password               = txtPassword.Text;
                    Config.database               = txtDatabase.Text;
                    Config.useCoupons             = cbUseCoupons.Checked;
                    Config.executeFailSafeOptions = cbExecuteFailSafe.Checked;
                    // This is tricky: the index of the selected item in the combo box must map to a specific enum. Be sure both are zero based:
                    Config.storeCheckInterval   = (Config.enum_availableCheckIntervals)cbStoreCheckInterval.SelectedIndex;
                    Config.emplCheckInterval    = (Config.enum_availableCheckIntervals)cbEmplCheckInterval.SelectedIndex;
                    Config.productCheckInterval = (Config.enum_availableCheckIntervals)cbProductCheckInterval.SelectedIndex;
                    Config.couponCheckInterval  = (Config.enum_availableCheckIntervals)cbCouponCheckInterval.SelectedIndex;
                    String[] tmp = cbCouponAmountToAdd.SelectedItem.ToString().Split();
                    Config.couponAmountToAdd = Convert.ToInt32(tmp[0]);
                    int numOfTransactionsToAdd;
                    if (cbRunForever.Checked == true)
                    {
                        numOfTransactionsToAdd = 0;     // Zero means run forever
                    }
                    else
                    {
                        try {
                            numOfTransactionsToAdd = Convert.ToInt32(txtNumOfTransactionsToAdd.Text);
                        } catch (Exception ex) {
                            MessageBox.Show("Enter the number of transactions to add or select Run Forever", "Invalid Number");
                            txtNumOfTransactionsToAdd.Focus();
                            Utils.Log(ex.Message);
                            return;
                        }
                    }
                    try {
                        if (Config.executeFailSafeOptions)
                        {
                            ProductPriceHist.CopyFromFromProductTableIntoProductPriceHist(Config.startDate); // Config.earliestPossibleDate);     // Fail-safe strategy
                            Empl.MakeAllEmplAvailableToWork(Config.startDate);                               // Config.earliestPossibleDate);                                   // Fail-safe strategy
                            Store.MakeAllStoreOpenForBusiness(Config.startDate);                             // Config.earliestPossibleDate);                                 // Fail-safe strategy
                        }
                        sg.StartTransactionSimulation(numOfTransactionsToAdd, Config.random, txtResults, lblStatus);
                    } catch (Exception ex) {
                        txtResults.Text += "btnGo_Click:" + "sg.StartSimulation: " + ex.Message;
                    }
                    btnStartTransactionSimulator.Text = "Halt";
                    watch = Stopwatch.StartNew();
                    lblElapsedTime.Text = "";
                    ShowTimerControls(true);
                    timer1.Enabled    = true;
                    txtSeed.Enabled   = false;
                    lblStartTime.Text = (String.Format("{0:hh\\:mm\\:ss tt}", DateTime.Now));
                }
                break;

            case Config.modeEnum.running:
                Config.mode = Config.modeEnum.idle;
                btnStartTransactionSimulator.Text = "Go";
                sg.Halt();
                watch           = null;
                timer1.Enabled  = false;
                txtSeed.Enabled = true;
                break;
            }
        }