private void butAddOrUpdate_Click(object sender, EventArgs e)
        {
            List <PayPlanEdit.PayPlanEntry> listSelectedEntries = new List <PayPlanEdit.PayPlanEntry>();

            for (int i = 0; i < gridMain.SelectedIndices.Count(); i++)          //add all of the currently selected entries to this list.
            {
                listSelectedEntries.Add((PayPlanEdit.PayPlanEntry)(gridMain.ListGridRows[gridMain.SelectedIndices[i]].Tag));
            }
            if (listSelectedEntries.Count <= 1)            //validation (doesn't matter if multiple are selected)
            {
                if (string.IsNullOrEmpty(textAmt.Text) || textAmt.errorProvider1.GetError(textAmt) != "" || PIn.Double(textAmt.Text) == 0)
                {
                    MsgBox.Show(this, "Please enter a valid amount.");
                    return;
                }
                if (textDate.Text != "" && textDate.errorProvider1.GetError(textDate) != "")
                {
                    MsgBox.Show(this, "Please enter a valid date.");
                    return;
                }
            }
            if (textDate.Text == "")
            {
                textDate.Text = DateTime.Today.ToShortDateString();
            }
            if (Security.IsGlobalDateLock(Permissions.PayPlanEdit, PIn.Date(textDate.Text)))
            {
                return;
            }
            if (listSelectedEntries.Count == 0)
            {
                if (PrefC.GetInt(PrefName.RigorousAccounting) == (int)RigorousAccounting.EnforceFully)                //if they have none selected
                {
                    MsgBox.Show(this, "All treatment credits (excluding adjustments) must have a procedure.");
                    return;
                }
                //add an unattached charge only if not on enforce fully
                PayPlanCharge addCharge = PayPlanEdit.CreateUnattachedCredit(textDate.Text, _patCur.PatNum, textNote.Text, _payPlanCur.PayPlanNum,
                                                                             PIn.Double(textAmt.Text));
                ListPayPlanCreditsCur.Add(addCharge);
            }
            else if (listSelectedEntries.Count == 1)            //if they have one selected
            {
                PayPlanEdit.PayPlanEntry selectedEntry = listSelectedEntries[0];
                if (selectedEntry.Proc != null && _listPayPlanLinksForProcs.Select(x => x.FKey).Contains(selectedEntry.Proc.ProcNum))
                {
                    MsgBox.Show(this, "This procedure is already linked to a dynamic payment plan.");
                    return;
                }
                if (PrefC.GetInt(PrefName.RigorousAccounting) == (int)RigorousAccounting.EnforceFully)
                {
                    if ((selectedEntry.Proc == null || selectedEntry.Proc.ProcNum == 0) &&
                        !(selectedEntry.Charge != null && selectedEntry.Charge.IsCreditAdjustment))
                    {
                        MsgBox.Show(this, "All treatment credits (excluding adjustments) must have a procedure.");
                        return;
                    }
                }
                PayPlanCharge selectedCharge = new PayPlanCharge();
                if (selectedEntry.IsChargeOrd)
                {
                    //get the charge from the grid.
                    //DO NOT use PayPlanChargeNum. They are not pre-inserted so they will all be 0 if new.
                    selectedCharge = ((PayPlanEdit.PayPlanEntry)(gridMain.ListGridRows[gridMain.SelectedIndices[0]].Tag)).Charge;
                }
                ListPayPlanCreditsCur = PayPlanEdit.CreateOrUpdateChargeForSelectedEntry(selectedEntry, ListPayPlanCreditsCur, PIn.Double(textAmt.Text), textNote.Text, textDate.Text
                                                                                         , _patCur.PatNum, _payPlanCur.PayPlanNum, selectedCharge);
            }
            else if (listSelectedEntries.Count > 1)            //if they have more than one entry selected
            //remove everythig that doesn't have a procnum from the list
            {
                List <PayPlanEdit.PayPlanEntry> listSelectedProcs = listSelectedEntries.Where(x => !x.IsChargeOrd).Where(x => x.Proc != null).ToList();
                if (listSelectedEntries.Count == 0)                //if the list is then empty, there's nothing to do.
                {
                    MsgBox.Show(this, "You must have at least one procedure selected.");
                    return;
                }
                if (!MsgBox.Show(this, MsgBoxButtons.OKCancel,
                                 "Add a payment plan credit for each of the selected procedure's remaining amount?  Selected credits will be ignored."))
                {
                    return;
                }
                List <PayPlanEdit.PayPlanEntry> listValidSelectedProcs =
                    listSelectedProcs.FindAll(x => !_listPayPlanLinksForProcs.Select(y => y.FKey).Contains(x.Proc.ProcNum));
                int countProcsSkipped = listSelectedProcs.Count - listValidSelectedProcs.Count;
                ListPayPlanCreditsCur = PayPlanEdit.CreateCreditsForAllSelectedEntries(listValidSelectedProcs, _listPayPlanEntries, DateTimeOD.Today
                                                                                       , _patCur.PatNum, _payPlanCur.PayPlanNum, ListPayPlanCreditsCur);
                if (countProcsSkipped > 0)
                {
                    MsgBox.Show(this, "Credits were not made for " + countProcsSkipped + " procedure(s) because they are linked to one or more dynamic payment plans.");
                }
            }
            textAmt.Text  = "";
            textDate.Text = "";
            textNote.Text = "";
            FillGrid();
            SetTextBoxes();
        }
        private void SetTextBoxes()
        {
            List <PayPlanEdit.PayPlanEntry> listSelectedEntries = new List <PayPlanEdit.PayPlanEntry>();

            for (int i = 0; i < gridMain.SelectedIndices.Count(); i++)          //fill the list with all the selected items in the grid.
            {
                listSelectedEntries.Add((PayPlanEdit.PayPlanEntry)(gridMain.ListGridRows[gridMain.SelectedIndices[i]].Tag));
            }
            bool isUpdateButton = false;          //keep track of the state of the button, if it is add or update.

            if (listSelectedEntries.Count == 0)   //if there are no entries selected
            //button should say Add, textboxes should be editable. No attached procedure.
            {
                butAddOrUpdate.Text = Lan.g(this, "Add");
                textAmt.Text        = "";
                textDate.Text       = "";
                textCode.Text       = Lan.g(this, "None");
                textNote.Text       = "";
                textAmt.ReadOnly    = false;
                textDate.ReadOnly   = false;
                textNote.ReadOnly   = false;
            }
            else if (listSelectedEntries.Count == 1)                             //if there is one entry selected
            {
                PayPlanEdit.PayPlanEntry selectedEntry = listSelectedEntries[0]; //all textboxes should be editable
                textAmt.ReadOnly  = false;
                textDate.ReadOnly = false;
                textNote.ReadOnly = false;
                if (selectedEntry.IsChargeOrd)                  //if it's a PayPlanCharge
                //button should say Update, text boxes should fill with info from that charge.
                {
                    butAddOrUpdate.Text = Lan.g(this, "Update");
                    isUpdateButton      = true;
                    textAmt.Text        = selectedEntry.AmtStr;
                    textNote.Text       = selectedEntry.NoteStr;
                    if (selectedEntry.ProcStatOrd == ProcStat.TP && selectedEntry.ProcNumOrd != 0)                 //if tp, grey out the date textbox. it should always be maxvalue.
                    //tp and procnum==0 means that it's the unattached row, in which case we don't want to make the text boxes ready-only.
                    {
                        textDate.ReadOnly = true;
                        textDate.Text     = "";
                    }
                    else
                    {
                        textDate.Text = selectedEntry.CredDateStr;
                    }
                    if (selectedEntry.Proc == null)                    //selected charge could be unattached.
                    {
                        textCode.Text = Lan.g(this, "Unattached");
                    }
                    else
                    {
                        textCode.Text = ProcedureCodes.GetStringProcCode(selectedEntry.Proc.CodeNum);
                    }
                }
                else                  // selected line item is a procedure (or the "Unattached" entry)
                                      //button should say "Add", text boxes should fill with info from that procedure (or "unattached").
                {
                    butAddOrUpdate.Text = Lan.g(this, "Add");
                    if (selectedEntry.Proc == null)
                    {
                        textCode.Text = Lan.g(this, "Unattached");
                        textAmt.Text  = "0.00";
                        textNote.Text = "";
                        textDate.Text = DateTimeOD.Today.ToShortDateString();
                    }
                    else                       //if it is a procedure (and not the "unattached" row)
                    {
                        List <PayPlanEdit.PayPlanEntry> listEntriesForProc = _listPayPlanEntries
                                                                             .Where(x => x.ProcNumOrd == selectedEntry.ProcNumOrd)
                                                                             .Where(x => x.IsChargeOrd == true).ToList();
                        if (listEntriesForProc.Count == 0)          //if there are no other charges attached to the procedure
                        {
                            textAmt.Text = selectedEntry.RemBefStr; //set textAmt to the value in RemBefore
                        }
                        else                                        //if there are other charges attached, fill the amount textbox with the minimum value in the RemAftr column.
                        {
                            textAmt.Text = listEntriesForProc.Min(x => PIn.Double(x.RemAftStr)).ToString("f");
                        }
                        textDate.Text = DateTimeOD.Today.ToShortDateString();
                        textNote.Text = ProcedureCodes.GetStringProcCode(selectedEntry.Proc.CodeNum) + ": " + Procedures.GetDescription(selectedEntry.Proc);
                        textCode.Text = ProcedureCodes.GetStringProcCode(selectedEntry.Proc.CodeNum);
                    }
                }
            }
            else if (listSelectedEntries.Count > 1)            //if they selected multiple line items
            //change the button to say "add"
            //blank out and make read-only all text boxes.
            {
                butAddOrUpdate.Text = Lan.g(this, "Add");
                textAmt.Text        = "";
                textDate.Text       = "";
                textNote.Text       = "";
                textCode.Text       = Lan.g(this, "Multiple");
                textAmt.ReadOnly    = true;
                textDate.ReadOnly   = true;
                textNote.ReadOnly   = true;
            }
            if (listSelectedEntries.Any(x => Security.IsGlobalDateLock(Permissions.PayPlanEdit, x.DateOrd, true)))
            {
                if (isUpdateButton)
                {
                    butAddOrUpdate.Enabled = false;                  //only disallow them from updating a tx credit, adding a new one is okay.
                }
                else
                {
                    butAddOrUpdate.Enabled = true;
                }
                butDelete.Enabled = false;
            }
            else
            {
                butAddOrUpdate.Enabled = true;
                butDelete.Enabled      = true;
            }
        }