//---------------------------------------------------//
        // Determine the row and column indices of a TextBox
        //---------------------------------------------------//
        static public ROWCOL MatchIndex(TextBox[][] MatrixTextbox, TextBox TB, ROWCOL LastIndex)
        {
            ROWCOL rc;
            for(rc.row = LastIndex.row; rc.row<MatrixTextbox.Length; rc.row++)
            {
                for(rc.col = LastIndex.col; rc.col<MatrixTextbox[rc.row].Length; rc.col++)
                    if(MatrixTextbox[rc.row][rc.col].Name == TB.Name)
                        return rc;
                rc.col = 0;
            }

            for(rc.row = 0; rc.row < MatrixTextbox.Length; rc.row++)
                for(rc.col = 0; rc.col < MatrixTextbox[rc.row].Length; rc.col++)
                    if(MatrixTextbox[rc.row][rc.col].Name == TB.Name)
                        return rc;

            // Failed to match index.
            rc.row = rc.col = -1;
            return rc;
        }
        private void MatrixTextBox_MouseEnter(object sender, MouseEventArgs e)
        {
            int row = m_matrixLastIndex.row;
            m_matrixLastIndex = GuiUtils.MatchIndex(m_matrixTextBox, (TextBox)sender, m_matrixLastIndex);
            if(m_matrixLastIndex.row == -1 || m_matrixLastIndex.col == -1)
            {
                m_matrixLastIndex.col = 0;
                m_matrixLastIndex.row = GuiUtils.MatchIndex(m_T50TextBox, (TextBox)sender);

                if(m_matrixLastIndex.row == -1)
                {
                    m_matrixLastIndex.row = GuiUtils.MatchIndex(m_slopeTextBox, (TextBox)sender);

                    if(m_matrixLastIndex.row == -1)
                    {
                        m_matrixLastIndex.row = 0;
                        return;
                    }
                }
            }

            if(row == m_matrixLastIndex.row)
                return;
            GuiControlsToMatrixModel();
            m_activeMatrixRowIndex = m_matrixLastIndex.row;
            ManageMatrixControls();

        }
        private void MatrixText_Leave(object sender, EventArgs e)
        {
            //double MAXVALUE = 1.0;
            int row, col;

            m_matrixLastIndex = GuiUtils.MatchIndex(m_matrixTextBox, (TextBox)sender, m_matrixLastIndex);
            col = m_matrixLastIndex.col;
            row = m_matrixLastIndex.row;

            //-----------------//
            // Debug assertions
            //-----------------//
            // Assert valid rows and columns.  Column is checked against 1 instead of
            // zero because the zero-th matrix isn't currently used or modified.
            Debug.Assert(row >= 0 && row <m_matrixTextBox.Length);
            Debug.Assert(col >= 1 && col <m_matrixTextBox[row].Length);
            // TODO: Add error handling.

                
            // Nothing to do if no error was detected.
            if(m_bMatrixError[row][col] == false || m_matrixCheckPasses == false)
                return;

            // The following are the only conditions this callback function handles and
            // each of these conditions must have set the matrix error flag to true.
            Debug.Assert(m_matrixTextBox[row][col].Text == "" ||
                m_matrixTextBox[row][col].Text == "." ||
                CStringUtil.SzToDouble(m_matrixTextBox[row][col].Text) > MATRIXELEMENTMAX);

            // If any matrix element error flag is set to false the OK button must have
            // been set to false.
            Debug.Assert(m_matrixCheckPasses == false);
            Debug.Assert(MyOKButton.Enabled == false);

            // This function will correct the errors it handles so set the error flag
            // associated with this matrix element to false.
            m_bMatrixError[row][col] = false;

            // Handle the errors.
            if(CStringUtil.SzToDouble(m_matrixTextBox[row][col].Text) > MATRIXELEMENTMAX)
                m_matrixTextBox[row][col].Text = String.Format("{0:0.0000}", MATRIXELEMENTMAX);
            else if(m_matrixTextBox[row][col].Text == "" || m_matrixTextBox[row][col].Text == ".")
                m_matrixTextBox[row][col].Text = String.Format("{0:0.0000}", 0);
        }
        private ROWCOL m_matrixLastIndex;  // Just a variable to make matix index matching faster.  Serves no other purpose.
        private void MatrixText_Changed(object sender, EventArgs e)
        {
            double val;
            String sz;
            int row, col;


            m_matrixLastIndex = GuiUtils.MatchIndex(m_matrixTextBox, (TextBox)sender, m_matrixLastIndex);
            col = m_matrixLastIndex.col;
            row = m_matrixLastIndex.row;

            // Only interested in changes to the text made by the user.  If entered by
            // user this text box will be focused.
            if(m_matrixTextBox[row][col].Focused == false)
                return;

            //-----------------//
            // Debug assertions
            //-----------------//
            // Assert valid rows and columns.  Column is checked against 1 instead of
            // zero because the zero-th matrix isn't currently used or modified.
            Debug.Assert(row >= 0 && row <m_matrixTextBox.Length);
            Debug.Assert(col >= 1 && col <m_matrixTextBox[row].Length);
            // TODO: Add error handling.

            // User has modified the value in the text box so indicate a change that
            // prevents user from exiting the associated dialog box without changing
            // without confirmation.
            SetModified();

            //--------------------------------------------------------------------------//
            // Verify that a valid floating point number was entered.
            //------------------------------------------------------//
            // Verify string entered by user is a valid float by grabbing a copy of the
            // text box's sting and forcing it into a valid float format then compare
            // to original string.  If strings don't match the value entered by the user
            // was not valid.  If not valid set the text box string to the valid value
            // then return.
            // Important here is that by setting the string to the new value causes this
            // function to be called again so the process starts over again.
            sz = CStringUtil.SzEnforceDoubleFmt(m_matrixTextBox[row][col].Text);
            if(m_matrixTextBox[row][col].Text != sz)
            {
                m_matrixTextBox[row][col].Text = sz;
                return;
            }

            // Verify the float string is within limits by comparing against allowed
            // warning limit and maximum limit.  While editing the user is allowed to
            // momentarily have floating point value held in the edit box higher than the
            // actual maximum allowed when done editing (so the warning value will be
            // higher than the maximum value).
            sz = m_matrixTextBox[row][col].Text;
            if((val = CStringUtil.SzToDouble(sz)) > MATRIXELEMENTWARNING)
            {
                // The value entered is higher than the maximum warning value.  Reset the
                // entered value to the maximum warning value (which will cause this
                // callback function to be called again) and return.
                m_matrixTextBox[row][col].Text = String.Format("{0:0.0000}", MATRIXELEMENTWARNING);
                return;
            }

            // If the user has entered a value exceeding the maximum value, an empty
            // string, or a ".", set and display error conditions.
            if(val > MATRIXELEMENTMAX || sz == "" || sz == ".")
            {
                m_matrixTextBox[row][col].BackColor = Color.Salmon;
                m_bMatrixError[row][col] = true;
                m_matrixCheckPasses = false;

                // CheckEnableOKButtonStatus() with the matrix not passing
                // (m_matrixCheckPasses set to false) disables the OK (return) button for
                // the associated dialog box.
                CheckEnableOKButtonStatus();
                return;
            }

            //------------------------------------------------------------------
            // At this point the user entry is a valid floating point number within
            // acceptable limits.

            // If previously a bad value was associate with the matrix element update
            // its status to show the error is clear then run an error check to see
            // if OK button can be enabled.
            if(m_bMatrixError[row][col] == true) // set during a previous call
            {                                             // to this function.
                m_bMatrixError[row][col] = false;
                RunErrorCheck();
            }
            MatrixTextChangeCheckTransitionRow(row, col);
            return; // String is properly modified
        }