using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using FastReport.Utils;
namespace FastReport.Matrix
{
///
/// Represents a collection of matrix data descriptors used in the .
///
public class MatrixCells : CollectionBase, IFRSerializable
{
private List[] rows;
private string name;
///
/// Gets or sets the element at the specified index.
///
/// Index of an element.
/// The element at the specified index.
public MatrixCellDescriptor this[int index]
{
get { return List[index] as MatrixCellDescriptor; }
set { List[index] = value; }
}
internal string Name
{
get { return name; }
set { name = value; }
}
internal bool IsEmpty
{
get { return rows == null; }
}
///
/// Adds the specified descriptors to the end of this collection.
///
/// Array of descriptors to add.
public void AddRange(MatrixCellDescriptor[] range)
{
foreach (MatrixCellDescriptor s in range)
{
Add(s);
}
}
///
/// Adds a descriptor to the end of this collection.
///
/// Descriptor to add.
/// Index of the added descriptor.
public int Add(MatrixCellDescriptor value)
{
return List.Add(value);
}
///
/// Inserts a descriptor into this collection at the specified index.
///
/// The zero-based index at which value should be inserted.
/// The descriptor to insert.
public void Insert(int index, MatrixCellDescriptor value)
{
List.Insert(index, value);
}
///
/// Removes the specified descriptor from the collection.
///
/// Descriptor to remove.
public void Remove(MatrixCellDescriptor value)
{
int i = IndexOf(value);
if (i != -1)
List.RemoveAt(i);
}
///
/// Returns the zero-based index of the first occurrence of a descriptor.
///
/// The descriptor to locate in the collection.
/// The zero-based index of the first occurrence of descriptor within
/// the entire collection, if found; otherwise, -1.
public int IndexOf(MatrixCellDescriptor value)
{
return List.IndexOf(value);
}
///
/// Determines whether a descriptor is in the collection.
///
/// The descriptor to locate in the collection.
/// true if descriptor is found in the collection; otherwise, false.
public bool Contains(MatrixCellDescriptor value)
{
return List.Contains(value);
}
///
/// Copies the elements of this collection to a new array.
///
/// An array containing copies of this collection elements.
public MatrixCellDescriptor[] ToArray()
{
MatrixCellDescriptor[] result = new MatrixCellDescriptor[Count];
for (int i = 0; i < Count; i++)
{
result[i] = this[i];
}
return result;
}
private void CheckIndices(int columnIndex, int rowIndex, List rows)
{
// append rows if row index is out of bounds
if (rowIndex >= rows.Count)
{
int delta = rowIndex - rows.Count + 1;
for (int i = 0; i < delta; i++)
{
rows.Add(new ArrayList());
}
}
ArrayList row = rows[rowIndex];
if (columnIndex >= row.Count)
{
int delta = columnIndex - row.Count + 1;
for (int i = 0; i < delta; i++)
{
row.Add(null);
}
}
}
private void AddValue(int columnIndex, int rowIndex, object value, List rows)
{
// do not put null values to the matrix!
if (value == null || value == DBNull.Value)
return;
CheckIndices(columnIndex, rowIndex, rows);
ArrayList row = rows[rowIndex];
object oldValue = row[columnIndex];
if (oldValue == null)
{
// initial state - the cell is empty. Put the value into the cell
row[columnIndex] = value;
}
else if (oldValue is ArrayList)
{
// cell contains a list of values. Add a new value to the list
(oldValue as ArrayList).Add(value);
}
else
{
// cell contains single value, we need to create a list of values
ArrayList valuesList = new ArrayList();
valuesList.Add(oldValue);
valuesList.Add(value);
row[columnIndex] = valuesList;
}
}
private void SetValue(int columnIndex, int rowIndex, object value, List rows)
{
CheckIndices(columnIndex, rowIndex, rows);
rows[rowIndex][columnIndex] = value;
}
internal void AddValue(int columnIndex, int rowIndex, object[] value)
{
if (value == null)
throw new ArgumentNullException("value");
if (value.Length != Count)
throw new MatrixValueException(Count);
if (rows == null)
rows = new List[Count];
for (int i = 0; i < Count; i++)
{
if (rows[i] == null)
rows[i] = new List();
AddValue(columnIndex, rowIndex, value[i], rows[i]);
}
}
// return value(s) contained in a cell.
// in case of empty cell, return null.
internal object GetValue(int columnIndex, int rowIndex, int cellIndex)
{
if (rows == null ||
cellIndex >= rows.Length ||
rowIndex >= rows[cellIndex].Count ||
columnIndex >= rows[cellIndex][rowIndex].Count)
return null;
// cell may contain either null, single value, or ArrayList containing several values.
object value = rows[cellIndex][rowIndex][columnIndex];
return value;
}
// return value(s) contained in a cell as ArrayList, even if there is only one value.
// in case of empty cell, return null.
internal ArrayList GetValues(int columnIndex, int rowIndex, int cellIndex)
{
object value = GetValue(columnIndex, rowIndex, cellIndex);
if (value == null)
return null;
if (value is ArrayList)
return (ArrayList)value;
ArrayList list = new ArrayList();
list.Add(value);
return list;
}
// replaces the list of values in a cell by the single value
internal void SetValues(int columnIndex, int rowIndex, object[] cellValues)
{
// do not put all nulls into the matrix
bool allNulls = true;
for (int i = 0; i < Count; i++)
{
if (cellValues[i] != null)
allNulls = false;
}
if (!allNulls)
{
if (rows == null)
rows = new List[Count];
for (int i = 0; i < Count; i++)
{
if (rows[i] == null)
rows[i] = new List();
SetValue(columnIndex, rowIndex, cellValues[i], rows[i]);
}
}
}
internal void Reset()
{
rows = null;
}
///
public void Serialize(FRWriter writer)
{
writer.ItemName = Name;
foreach (MatrixCellDescriptor d in this)
{
writer.Write(d);
}
}
///
public void Deserialize(FRReader reader)
{
Clear();
while (reader.NextItem())
{
MatrixCellDescriptor d = new MatrixCellDescriptor();
reader.Read(d);
Add(d);
}
}
internal MatrixCells()
{
}
}
}