using System;
using System.Collections.Generic;
using FastReport.Code;
using FastReport.Utils;
namespace FastReport.AdvMatrix
{
///
/// Represents the storage of header descriptors and its values.
///
public class MatrixHeader : IFRSerializable
{
private AdvMatrixObject matrix;
private string name;
private int runningIndex;
///
/// Gets the root header descriptor.
///
public HeaderDescriptor Descriptor { get; private set; }
///
/// Gets the size of this header.
///
public int Size { get { return GetSize(Descriptor); } }
internal HeaderData Data { get; private set; }
internal int NextIndex
{
get
{
runningIndex++;
return runningIndex;
}
}
private void FillData(HeaderDescriptor descr, HeaderData data, List activeItems)
{
foreach (HeaderDescriptor d in descr.Items)
{
if (!String.IsNullOrEmpty(d.Filter))
{
if ((dynamic)matrix.Report.Calc(d.Filter) == false)
continue;
}
if (!String.IsNullOrEmpty(d.VisibleExpression))
{
d.Visible = (dynamic)matrix.Report.Calc(d.VisibleExpression);
}
HeaderData dataItem = data.Add(d);
activeItems.Add(dataItem);
if (matrix.DataSource != null)
dataItem.DataRowNo = matrix.DataSource.CurrentRowNo;
// set index for the newly added items
if (dataItem.Index == 0)
dataItem.Index = NextIndex;
if (d.SortAggregate != null)
d.SortAggregate.ProcessDataRow(dataItem.Index, 0, matrix.Report.Calc(d.SortAggregate.Expression));
FillData(d, dataItem, activeItems);
}
}
private int GetSize(HeaderDescriptor root)
{
int maxSize = -1;
foreach (HeaderDescriptor d in root.Items)
{
int size = GetSize(d);
if (size > maxSize)
maxSize = size;
}
return maxSize + (root.Stepped && root.Items.Count > 0 ? 0 : 1);
}
private void GetExpressions(HeaderDescriptor root, List expressions)
{
foreach (HeaderDescriptor d in root.Items)
{
if (!String.IsNullOrEmpty(d.Expression))
expressions.Add(d.Expression);
if (!String.IsNullOrEmpty(d.DisplayText))
expressions.AddRange(CodeUtils.GetExpressions(d.DisplayText, "[", "]"));
if (!String.IsNullOrEmpty(d.Filter))
expressions.Add(d.Filter);
if (!String.IsNullOrEmpty(d.VisibleExpression))
expressions.Add(d.VisibleExpression);
if (d.SortAggregate != null)
expressions.Add(d.SortAggregate.Expression);
// we don't need to add InteractiveSortAggregate expression because it's a reference to existing cell aggregate
GetExpressions(d, expressions);
}
}
private void InitAggregates(HeaderDescriptor root)
{
root.InitAggregates();
foreach (HeaderDescriptor d in root.Items)
{
InitAggregates(d);
}
}
internal void GetExpressions(List expressions)
{
InitAggregates(Descriptor);
GetExpressions(Descriptor, expressions);
}
internal void Init()
{
runningIndex = 0;
Data.Clear();
}
internal List ProcessDataRow()
{
List activeItems = new List();
FillData(Descriptor, Data, activeItems);
return activeItems;
}
///
public void Serialize(FRWriter writer)
{
writer.ItemName = name;
// do not write root item
foreach (HeaderDescriptor d in Descriptor.Items)
writer.Write(d);
}
///
public void Deserialize(FRReader reader)
{
reader.Read(Descriptor);
}
internal void Assign(MatrixHeader src)
{
Descriptor = src.Descriptor;
}
///
/// Initializes a new instance of the class.
///
public MatrixHeader(AdvMatrixObject matrix, string name)
{
this.matrix = matrix;
this.name = name;
Descriptor = new HeaderDescriptor();
Data = new HeaderData(null, null);
}
}
}