using System;
namespace FastReport.AdvMatrix
{
///
/// Holds context required for aggregate functions evaluation.
///
public class Context
{
internal CellDescriptor Descriptor;
internal HeaderData ColumnItem;
internal HeaderData RowItem;
internal AggregateExpressionPair Aggregate;
private dynamic Div(dynamic value, dynamic divBy)
{
if (divBy == null || divBy == 0)
return null;
if (value is float || value is double || value is decimal)
return value / divBy;
return value / (double)divBy;
}
private bool CheckAggregate()
{
// in case we provide no arguments to the special method call, use the first aggregate in a cell
if (Aggregate == null)
{
if (Descriptor != null && Descriptor.Aggregates.Count > 0)
Aggregate = Descriptor.Aggregates[0];
}
return Aggregate != null;
}
private dynamic GetAggregateValue(int columnIndex, int rowIndex)
{
return Aggregate.GetValue(columnIndex, rowIndex);
}
///
/// Gets aggregate value. This method is for internal use only.
///
/// Name of aggregate.
/// Expression.
/// Aggregate value.
public dynamic GetAggregate(string aggregateName, string expression)
{
if (Descriptor == null)
return null;
Aggregate = Descriptor.Aggregates.Find(aggregateName, expression);
if (Aggregate == null)
return null;
return GetAggregateValue(ColumnItem.Index, RowItem.Index);
}
///
/// Gets value of the specific column. This method is for internal use only.
///
/// The column value.
/// Dummy parameter.
/// The value or null.
public dynamic GetSpecificColumn(object value, object dummy = null)
{
HeaderData columnItem = ColumnItem.GetSpecificItem(value);
if (columnItem == null)
return null;
if (!CheckAggregate())
return null;
return GetAggregateValue(columnItem.Index, RowItem.Index);
}
///
/// Gets value of the specific row. This method is for internal use only.
///
/// The row value.
/// Dummy parameter.
/// The value or null.
public dynamic GetSpecificRow(object value, object dummy = null)
{
HeaderData rowItem = RowItem.GetSpecificItem(value);
if (rowItem == null)
return null;
if (!CheckAggregate())
return null;
return GetAggregateValue(ColumnItem.Index, rowItem.Index);
}
///
/// Gets value of the first column. This method is for internal use only.
///
/// Dummy parameter.
/// Determines if the interactive sort must be respected.
/// Determines if the same level group should be used to search for item.
/// The value or null.
public dynamic GetFirstColumn(object dummy = null, bool useIneractiveSort = false, bool useThisGroup = true)
{
HeaderData firstColumnItem = ColumnItem.GetFirstItem(useIneractiveSort, useThisGroup);
if (firstColumnItem == null)
return null;
if (!CheckAggregate())
return null;
return GetAggregateValue(firstColumnItem.Index, RowItem.Index);
}
///
/// Gets value of the last column. This method is for internal use only.
///
/// Dummy parameter.
/// Determines if the interactive sort must be respected.
/// Determines if the same level group should be used to search for item.
/// The value or null.
public dynamic GetLastColumn(object dummy = null, bool useIneractiveSort = false, bool useThisGroup = true)
{
HeaderData lastColumnItem = ColumnItem.GetLastItem(useIneractiveSort, useThisGroup);
if (lastColumnItem == null)
return null;
if (!CheckAggregate())
return null;
return GetAggregateValue(lastColumnItem.Index, RowItem.Index);
}
///
/// Gets value of the first row. This method is for internal use only.
///
/// Dummy parameter.
/// Determines if the interactive sort must be respected.
/// Determines if the same level group should be used to search for item.
/// The value or null.
public dynamic GetFirstRow(object dummy = null, bool useIneractiveSort = false, bool useThisGroup = true)
{
HeaderData firstRowItem = RowItem.GetFirstItem(useIneractiveSort, useThisGroup);
if (firstRowItem == null)
return null;
if (!CheckAggregate())
return null;
return GetAggregateValue(ColumnItem.Index, firstRowItem.Index);
}
///
/// Gets value of the last row. This method is for internal use only.
///
/// Dummy parameter.
/// Determines if the interactive sort must be respected.
/// Determines if the same level group should be used to search for item.
/// The value or null.
public dynamic GetLastRow(object dummy = null, bool useIneractiveSort = false, bool useThisGroup = true)
{
HeaderData lastRowItem = RowItem.GetLastItem(useIneractiveSort, useThisGroup);
if (lastRowItem == null)
return null;
if (!CheckAggregate())
return null;
return GetAggregateValue(ColumnItem.Index, lastRowItem.Index);
}
///
/// Gets value of previous column. This method is for internal use only.
///
/// Dummy parameter.
/// Determines if the interactive sort must be respected.
/// Determines if the same level group should be used to search for item.
/// The value or null.
public dynamic GetPreviousColumn(object dummy = null, bool useIneractiveSort = false, bool useThisGroup = true)
{
HeaderData previousColumnItem = ColumnItem.GetPreviousItem(useIneractiveSort, useThisGroup);
if (previousColumnItem == null)
return null;
if (!CheckAggregate())
return null;
return GetAggregateValue(previousColumnItem.Index, RowItem.Index);
}
///
/// Gets value of previous row. This method is for internal use only.
///
/// Dummy parameter.
/// Determines if the interactive sort must be respected.
/// Determines if the same level group should be used to search for item.
/// The value or null.
public dynamic GetPreviousRow(object dummy = null, bool useIneractiveSort = false, bool useThisGroup = true)
{
HeaderData previousRowItem = RowItem.GetPreviousItem(useIneractiveSort, useThisGroup);
if (previousRowItem == null)
return null;
if (!CheckAggregate())
return null;
return GetAggregateValue(ColumnItem.Index, previousRowItem.Index);
}
///
/// Gets value of next column. This method is for internal use only.
///
/// Dummy parameter.
/// Determines if the interactive sort must be respected.
/// Determines if the same level group should be used to search for item.
/// The value or null.
public dynamic GetNextColumn(object dummy = null, bool useIneractiveSort = false, bool useThisGroup = true)
{
HeaderData nextColumnItem = ColumnItem.GetNextItem(useIneractiveSort, useThisGroup);
if (nextColumnItem == null)
return null;
if (!CheckAggregate())
return null;
return GetAggregateValue(nextColumnItem.Index, RowItem.Index);
}
///
/// Gets value of next row. This method is for internal use only.
///
/// Dummy parameter.
/// Determines if the interactive sort must be respected.
/// Determines if the same level group should be used to search for item.
/// The value or null.
public dynamic GetNextRow(object dummy = null, bool useIneractiveSort = false, bool useThisGroup = true)
{
HeaderData nextRowItem = RowItem.GetNextItem(useIneractiveSort, useThisGroup);
if (nextRowItem == null)
return null;
if (!CheckAggregate())
return null;
return GetAggregateValue(ColumnItem.Index, nextRowItem.Index);
}
///
/// Gets column total value. This method is for internal use only.
///
/// Dummy parameter.
/// The value or null.
public dynamic GetGrandColumnTotal(object dummy = null)
{
if (!CheckAggregate())
return null;
return GetAggregateValue(ColumnItem.Index, Descriptor.RowIndex);
}
///
/// Gets row total value. This method is for internal use only.
///
/// Dummy parameter.
/// The value or null.
public dynamic GetGrandRowTotal(object dummy = null)
{
if (!CheckAggregate())
return null;
return GetAggregateValue(Descriptor.ColumnIndex, RowItem.Index);
}
///
/// Gets grand total value. This method is for internal use only.
///
/// Dummy parameter.
/// The value or null.
public dynamic GetGrandTotal(object dummy = null)
{
if (!CheckAggregate())
return null;
return GetAggregateValue(Descriptor.ColumnIndex, Descriptor.RowIndex);
}
///
/// Gets column group total value. This method is for internal use only.
///
/// Dummy parameter.
/// The value or null.
public dynamic GetColumnTotal(object dummy = null)
{
if (!CheckAggregate())
return null;
int rowIndex = RowItem.Parent.Index;
if (rowIndex == 0)
rowIndex = Descriptor.RowIndex;
return GetAggregateValue(ColumnItem.Index, rowIndex);
}
///
/// Gets row group total value. This method is for internal use only.
///
/// Dummy parameter.
/// The value or null.
public dynamic GetRowTotal(object dummy = null)
{
if (!CheckAggregate())
return null;
int columnIndex = ColumnItem.Parent.Index;
if (columnIndex == 0)
columnIndex = Descriptor.ColumnIndex;
return GetAggregateValue(columnIndex, RowItem.Index);
}
///
/// Gets column group max value. This method is for internal use only.
///
/// Dummy parameter.
/// The value or null.
public dynamic GetColumnMaxValue(object dummy = null)
{
if (!CheckAggregate())
return null;
dynamic maxValue = null;
HeaderDataList parent = RowItem.GetGroup();
if (parent != null)
{
foreach (HeaderData d in parent)
{
dynamic value = GetAggregateValue(ColumnItem.Index, d.Index);
if (maxValue == null || maxValue < value)
maxValue = value;
}
}
return maxValue;
}
///
/// Gets column group min value. This method is for internal use only.
///
/// Dummy parameter.
/// The value or null.
public dynamic GetColumnMinValue(object dummy = null)
{
if (!CheckAggregate())
return null;
dynamic minValue = null;
HeaderDataList parent = RowItem.GetGroup();
if (parent != null)
{
foreach (HeaderData d in parent)
{
dynamic value = GetAggregateValue(ColumnItem.Index, d.Index);
if (minValue == null || minValue > value)
minValue = value;
}
}
return minValue;
}
///
/// Gets row group max value. This method is for internal use only.
///
/// Dummy parameter.
/// The value or null.
public dynamic GetRowMaxValue(object dummy = null)
{
if (!CheckAggregate())
return null;
dynamic maxValue = null;
HeaderDataList parent = ColumnItem.GetGroup();
if (parent != null)
{
foreach (HeaderData d in parent)
{
dynamic value = GetAggregateValue(d.Index, RowItem.Index);
if (maxValue == null || maxValue < value)
maxValue = value;
}
}
return maxValue;
}
///
/// Gets row group min value. This method is for internal use only.
///
/// Dummy parameter.
/// The value or null.
public dynamic GetRowMinValue(object dummy = null)
{
if (!CheckAggregate())
return null;
dynamic minValue = null;
HeaderDataList parent = ColumnItem.GetGroup();
if (parent != null)
{
foreach (HeaderData d in parent)
{
dynamic value = GetAggregateValue(d.Index, RowItem.Index);
if (minValue == null || minValue > value)
minValue = value;
}
}
return minValue;
}
///
/// Gets percent of column total. This method is for internal use only.
///
/// Dummy parameter.
/// The value.
public dynamic GetPercentOfColumnTotal(object dummy = null)
{
if (!CheckAggregate())
return null;
return Div(GetAggregateValue(ColumnItem.Index, RowItem.Index), GetColumnTotal());
}
///
/// Gets percent of row total. This method is for internal use only.
///
/// Dummy parameter.
/// The value.
public dynamic GetPercentOfRowTotal(object dummy = null)
{
if (!CheckAggregate())
return null;
return Div(GetAggregateValue(ColumnItem.Index, RowItem.Index), GetRowTotal());
}
///
/// Gets percent of grand total. This method is for internal use only.
///
/// Dummy parameter.
/// The value.
public dynamic GetPercentOfGrandTotal(object dummy = null)
{
if (!CheckAggregate())
return null;
return Div(GetAggregateValue(ColumnItem.Index, RowItem.Index), GetGrandTotal());
}
///
/// Gets percent of previous column. This method is for internal use only.
///
/// Dummy parameter.
/// Determines if the interactive sort must be respected.
/// Determines if the same level group should be used to search for item.
/// The value or null.
public dynamic GetPercentOfPreviousColumn(object dummy = null, bool useIneractiveSort = false, bool useThisGroup = true)
{
if (!CheckAggregate())
return null;
return Div(GetAggregateValue(ColumnItem.Index, RowItem.Index), GetPreviousColumn(dummy, useIneractiveSort, useThisGroup));
}
///
/// Gets percent of previous row. This method is for internal use only.
///
/// Dummy parameter.
/// Determines if the interactive sort must be respected.
/// Determines if the same level group should be used to search for item.
/// The value or null.
public dynamic GetPercentOfPreviousRow(object dummy = null, bool useIneractiveSort = false, bool useThisGroup = true)
{
if (!CheckAggregate())
return null;
return Div(GetAggregateValue(ColumnItem.Index, RowItem.Index), GetPreviousRow(dummy, useIneractiveSort, useThisGroup));
}
}
}