/// <summary>
 /// Determines whether the specified row index is associated with TableSummaryRow.
 /// </summary>
 /// <param name="dataGrid">
 /// The SfDataGrid.
 /// </param>
 /// <param name="rowIndex">
 /// The corresponding rowIndex to determine the TableSummaryRow.
 /// </param>
 /// <returns>
 /// Returns <b>true</b> if the specified row index is TableSummaryRow; otherwise, <b>false</b>.
 /// </returns>
 public static bool IsTableSummaryIndex(this SfDataGrid dataGrid, int rowIndex)
 {
     if (rowIndex < dataGrid.HeaderLineCount)
     {
         var frozenCount            = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Top, false);
         var topTableSummariesCount = dataGrid.GetTableSummaryCount(TableSummaryRowPosition.Top);
         var tableSummaryStartIndex = dataGrid.StackedHeaderRows.Count + frozenCount + 1; //1 added for Column Header
         var tableSummaryEndIndex   = dataGrid.StackedHeaderRows.Count + frozenCount + topTableSummariesCount + 1;
         if (rowIndex >= tableSummaryStartIndex && rowIndex < tableSummaryEndIndex)
         {
             return(true);
         }
     }
     else
     {
         var footerCount            = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Bottom, true);
         var tableSummaryEndIndex   = dataGrid.VisualContainer.RowCount - footerCount;
         var tableSummaryStartIndex = dataGrid.VisualContainer.RowCount - (dataGrid.GetTableSummaryCount(TableSummaryRowPosition.Bottom) + footerCount);
         if (rowIndex >= tableSummaryStartIndex && rowIndex < tableSummaryEndIndex)
         {
             return(true);
         }
     }
     return(false);
 }
        /// <summary>
        /// Gets the UnBoundRow for the specified row index.
        /// </summary>
        /// <param name="dataGrid">
        /// The SfDataGrid.
        /// </param>
        /// <param name="rowIndex">
        /// The row index to get the UnBoundRow.
        /// </param>
        /// <returns>
        /// Returns the corresponding <see cref="Syncfusion.UI.Xaml.Grid.GridUnBoundRow"/> for the specified row index.
        /// </returns>
        public static GridUnBoundRow GetUnBoundRow(this SfDataGrid dataGrid, int rowIndex)
        {
            if (!dataGrid.UnBoundRows.Any())
            {
                return(null);
            }

            var row = dataGrid.UnBoundRows.FirstOrDefault(urow => urow.RowIndex == rowIndex);

            if (row != null)
            {
                return(row);
            }
            else
            {
                var frozenCount     = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Top, false);    //, RowRegion.Header);
                var footerCount     = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Bottom, true);  //, RowRegion.Footer);
                var topBodyCount    = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Top, true);     //, RowRegion.Body);
                var bottomBodyCount = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Bottom, false); //, RowRegion.Body);

                var topTableSummaryRowsCount    = dataGrid.GetTableSummaryCount(TableSummaryRowPosition.Top);
                var bottomTableSummaryRowsCount = !dataGrid.HasView ? 0 : dataGrid.GetTableSummaryCount(TableSummaryRowPosition.Bottom);
                var gridRows = !dataGrid.HasView ? 0 : (dataGrid.AddNewRowPosition == AddNewRowPosition.Top ? 1 : 0)
                               + (dataGrid.FilterRowPosition == FilterRowPosition.Top ? 1 : 0);
                var headerLineCount = (!dataGrid.HasView ? dataGrid.VisualContainer.FrozenRows : dataGrid.HeaderLineCount) + gridRows;
                var headerIndex     = !dataGrid.HasView ? dataGrid.StackedHeaderRows.Count : dataGrid.GetHeaderIndex();

                var rowCount        = dataGrid.VisualContainer.RowCount;
                var bottomAddNewRow = !dataGrid.HasView ? 0 : dataGrid.AddNewRowPosition == AddNewRowPosition.Bottom ? 1 : 0;
                bottomAddNewRow += !dataGrid.HasView ? 0 : dataGrid.FilterRowPosition == FilterRowPosition.Bottom ? 1 : 0;

                if (rowIndex > headerIndex && rowIndex <= (headerIndex + frozenCount)) // FrozenCount Condition Checking
                {
                    return(dataGrid.UnBoundRows.FirstOrDefault(item => !item.ShowBelowSummary && item.Position == UnBoundRowsPosition.Top && item.UnBoundRowIndex == (rowIndex - (headerIndex + 1))));
                }

                else if (rowIndex >= headerLineCount && rowIndex < (headerLineCount + topBodyCount)) // TopBodyCount Condition Checking
                {
                    return(dataGrid.UnBoundRows.FirstOrDefault(item => item.ShowBelowSummary && item.Position == UnBoundRowsPosition.Top && item.UnBoundRowIndex == (rowIndex - headerLineCount)));
                }

                else if (rowIndex >= (rowCount - footerCount) && rowIndex < rowCount) // Footer count condition checking.
                {
                    return(dataGrid.UnBoundRows.FirstOrDefault(item => item.ShowBelowSummary && item.Position == UnBoundRowsPosition.Bottom && item.UnBoundRowIndex == ((rowIndex + footerCount) - rowCount)));
                }

                else if ((rowIndex < (rowCount - (bottomTableSummaryRowsCount + footerCount + bottomAddNewRow))) && (rowIndex >= (rowCount - (bottomTableSummaryRowsCount + footerCount + bottomBodyCount + bottomAddNewRow)))) // Bootom body condition chceking
                {
                    return(dataGrid.UnBoundRows.FirstOrDefault(item => !item.ShowBelowSummary && item.Position == UnBoundRowsPosition.Bottom && item.UnBoundRowIndex == ((rowIndex + bottomBodyCount + bottomAddNewRow + bottomTableSummaryRowsCount + footerCount) - rowCount)));
                }
            }
            return(null);
        }
        /// <summary>
        /// Gets the header index of SfDataGrid.
        /// </summary>
        /// <param name="grid">
        /// The SfDataGrid.
        /// </param>
        /// <returns>
        /// Returns the header index of the SfDataGrid.
        /// </returns>
        public static int GetHeaderIndex(this SfDataGrid grid)
        {
            var frozenCount = grid.GetUnBoundRowsCount(UnBoundRowsPosition.Top, false);//, RowRegion.Header);
            int rowCount    = (grid.AddNewRowPosition == AddNewRowPosition.FixedTop ? 1 : 0) + (grid.FilterRowPosition == FilterRowPosition.FixedTop ? 1 : 0);

            return((grid.HeaderLineCount - (rowCount + 1))
                   - (grid.GetTableSummaryCount(TableSummaryRowPosition.Top)) - frozenCount);
        }
        /// <summary>
        /// Determines whether the specified row index is associated with any UnBoundRow's.
        /// </summary>
        /// <param name="dataGrid">
        /// The SfDataGrid.
        /// </param>
        /// <param name="rowIndex">
        /// The corresponding rowIndex to determine the UnBoundRow.
        /// </param>
        /// <returns>
        /// Returns <b>true</b> if the specified row index is UnBoundRow; otherwise, <b>false</b>.
        /// </returns>
        public static bool IsUnBoundRow(this SfDataGrid dataGrid, int rowIndex)
        {
            if (!dataGrid.UnBoundRows.Any())
            {
                return(false);
            }

            var topUnBoundDataRowsCount    = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Top);
            var bottomUnBoundDataRowsCount = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Bottom);
            var rowCount = dataGrid.VisualContainer.RowCount;

            var topTableSummaryRowsCount    = dataGrid.GetTableSummaryCount(TableSummaryRowPosition.Top);
            var bottomTableSummaryRowsCount = dataGrid.View == null ? 0 : dataGrid.GetTableSummaryCount(TableSummaryRowPosition.Bottom);

            var frozenCount     = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Top, false);    //, RowRegion.Header);
            var footerCount     = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Bottom, true);  //,RowRegion.Footer);
            var topBodyCount    = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Top, true);     //, RowRegion.Body);
            var bottomBodyCount = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Bottom, false); //, RowRegion.Body);
            var bottomAddNewRow = !dataGrid.HasView ? 0 : dataGrid.AddNewRowPosition == AddNewRowPosition.Bottom ? 1 : 0;

            bottomAddNewRow += !dataGrid.HasView ? 0 : dataGrid.FilterRowPosition == FilterRowPosition.Bottom ? 1 : 0;
            var gridRows = !dataGrid.HasView ? 0 : (dataGrid.AddNewRowPosition == AddNewRowPosition.Top ? 1 : 0)
                           + (dataGrid.FilterRowPosition == FilterRowPosition.Top ? 1 : 0);
            var headerLineCount = (!dataGrid.HasView ? dataGrid.VisualContainer.FrozenRows : dataGrid.HeaderLineCount)
                                  + gridRows;
            var headerIndex = !dataGrid.HasView ? dataGrid.StackedHeaderRows.Count : dataGrid.GetHeaderIndex();

            if
            ((rowIndex >= headerLineCount && rowIndex < (headerLineCount + topBodyCount))                                                                                                                            // TopBodyCount Condition Checking
             ||
             (rowIndex > headerIndex && rowIndex <= (headerIndex + frozenCount))                                                                                                                                     // FrozenCount Condition Checking
             ||
             ((rowIndex < (rowCount - (bottomTableSummaryRowsCount + footerCount + bottomAddNewRow))) && (rowIndex >= (rowCount - (bottomTableSummaryRowsCount + footerCount + bottomBodyCount + bottomAddNewRow)))) // Bootom body condition chceking
             ||
             (rowIndex >= (rowCount - footerCount) && rowIndex < rowCount))                                                                                                                                          // Footer count condition checking.
            {
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// Gets the corresponding row index of the FilterRow.
        /// </summary>
        /// <param name="dataGrid">
        /// The SfDataGrid.
        /// </param>
        /// <returns>
        /// Returns an index of a FilterRow.
        /// </returns>
        public static int GetFilterRowIndex(this SfDataGrid dataGrid)
        {
            var footerCount = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Bottom, true);
            var frozenCount = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Top, false);

            if (dataGrid.FilterRowPosition == FilterRowPosition.FixedTop)
            {
                return(dataGrid.HeaderLineCount - (1 + (dataGrid.AddNewRowPosition == AddNewRowPosition.FixedTop ? 1 : 0)));
            }
            else if (dataGrid.FilterRowPosition == FilterRowPosition.Top)
            {
                return(dataGrid.HeaderLineCount);
            }
            else if (dataGrid.FilterRowPosition == FilterRowPosition.Bottom)
            {
                return(dataGrid.VisualContainer.RowCount - (dataGrid.GetTableSummaryCount(TableSummaryRowPosition.Bottom) + 1 + footerCount));
            }
            return(-1);
        }
        /// <summary>
        /// Resolves the table summary index corresponding to the specified row index in SfDataGrid.
        /// </summary>
        /// <param name="dataGrid">
        /// The SfDataGrid.
        /// </param>
        /// <param name="rowIndex">
        /// Specifies the corresponding row index to get its table summary index.
        /// </param>
        /// <returns>
        /// The table summary index corresponding to the specified row index ; returns -1 , if the VisualContainer of the SfDataGrid is null.
        /// </returns>
        public static int ResolveToTableSummaryIndex(this SfDataGrid dataGrid, int rowIndex)
        {
            if (dataGrid.VisualContainer != null)
            {
                var endindex   = dataGrid.VisualContainer.RowCount - 1;
                var startindex = dataGrid.VisualContainer.RowCount
                                 - dataGrid.GetTableSummaryCount(TableSummaryRowPosition.Bottom)
                                 - dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Bottom, true);

                if (rowIndex >= startindex && rowIndex <= endindex)
                {
                    return(rowIndex - startindex);
                }

                if (rowIndex >= 0)
                {
                    return(rowIndex);
                }
            }
            return(-1);
        }
        /// <summary>
        /// Gets the row index of the AddNewRow.
        /// </summary>
        /// <returns>
        /// Returns row index of the AddNewRow.
        /// </returns>
        public int GetAddNewRowIndex()
        {
            if (dataGrid.AddNewRowPosition == AddNewRowPosition.None)
            {
                return(-1);
            }

            var footerCount = dataGrid.GetUnBoundRowsCount(UnBoundRowsPosition.Bottom, true)
                              + (dataGrid.FilterRowPosition == FilterRowPosition.Bottom ? 1 : 0);//, RowRegion.Footer);

            if (dataGrid.AddNewRowPosition == AddNewRowPosition.FixedTop)
            {
                return(dataGrid.HeaderLineCount - 1);
            }
            else if (dataGrid.AddNewRowPosition == AddNewRowPosition.Top)
            {
                return(dataGrid.HeaderLineCount + (dataGrid.FilterRowPosition == FilterRowPosition.Top ? 1 : 0));
            }
            else
            {
                return(dataGrid.VisualContainer.RowCount - (dataGrid.GetTableSummaryCount(TableSummaryRowPosition.Bottom) + 1 + footerCount));
            }
        }
        /// <summary>
        /// Resolves row index for the specified <see cref="Syncfusion.UI.Xaml.Grid.GridUnBoundRow"/>.
        /// </summary>
        /// <param name="DataGrid">
        /// The SfDataGrid.
        /// </param>
        /// <param name="unBoundRow">
        /// Specifies the UnBoundRow to get its corresponding row index.
        /// </param>
        /// <returns>
        /// Returns the row index of the specified UnBoundRow.
        /// </returns>
        public static int ResolveUnboundRowToRowIndex(this SfDataGrid DataGrid, GridUnBoundRow unBoundRow)
        {
            if (!DataGrid.UnBoundRows.Any())
            {
                return(-1);
            }

            if (unBoundRow.Position == UnBoundRowsPosition.Top)
            {
                //var rows = DataGrid.UnBoundRows.Where(ubr => ubr.Position == unBoundRow.Position && ubr.ShowBelowSummary == unBoundRow.ShowBelowSummary);
                if (!unBoundRow.ShowBelowSummary)
                {
                    return(DataGrid.GetHeaderIndex() + unBoundRow.UnBoundRowIndex + 1);
                }
                else
                {
                    return(DataGrid.HeaderLineCount + (DataGrid.AddNewRowPosition == AddNewRowPosition.Top ? 1 : 0) +
                           (DataGrid.FilterRowPosition == FilterRowPosition.Top ? 1 : 0) + unBoundRow.UnBoundRowIndex);
                }
            }
            else
            {
                if (!unBoundRow.ShowBelowSummary)
                {
                    return(DataGrid.VisualContainer.RowCount -
                           (DataGrid.GetTableSummaryCount(TableSummaryRowPosition.Bottom) +
                            (DataGrid.AddNewRowPosition == AddNewRowPosition.Bottom ? 1 : 0) +
                            (DataGrid.FilterRowPosition == FilterRowPosition.Bottom ? 1 : 0) +
                            DataGrid.GetUnBoundRowsCount(unBoundRow.Position))
                           + unBoundRow.UnBoundRowIndex);
                }
                else
                {
                    return(DataGrid.VisualContainer.RowCount - DataGrid.UnBoundRows.FooterUnboundRowCount + unBoundRow.UnBoundRowIndex);
                }
            }
        }
        /// <summary>
        /// Gets the total number of table summary rows in SfDataGrid according to the specified <see cref="Syncfusion.UI.Xaml.Grid.TableSummaryRowPosition"/>.
        /// </summary>
        /// <param name="grid">
        /// The SfDataGrid.
        /// </param>
        /// <param name="position">
        /// Specifies the position of table summary row to get its count.
        /// </param>
        /// <returns>
        /// Returns the number of table summary rows in SfDataGrid.
        /// </returns>
        public static int GetTableSummaryCount(this SfDataGrid grid, TableSummaryRowPosition position)
        {
            //WPF-20773 avoid Designer Issue
            if (grid != null && grid.HasView && grid.TableSummaryRows != null)
            {
                return(position == TableSummaryRowPosition.Top ? (grid.View.TableSummaryRows.Where(row => (row is GridTableSummaryRow && (row as GridTableSummaryRow).Position == TableSummaryRowPosition.Top)).Count()) : (grid.View.TableSummaryRows.Count - grid.GetTableSummaryCount(TableSummaryRowPosition.Top)));
            }

            return(0);
        }