18using System.Collections;
19using System.Collections.Generic;
22using System.Threading.Tasks;
54 internal class GPALGrid<T> : IGPALGrid<T>
56 private List<List<T>> data;
59 private readonly
object rowLock =
new object();
66 internal bool UseDedupe {
get;
private set; } =
false;
73 public IGPALGrid<T> WithDedupeData(
bool useDedupe =
true)
75 UseDedupe = useDedupe;
84 data =
new List<List<T>>();
109 public IAllowGridActions<T> AddRow(List<T> row)
113 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
"Row is null in AddRow(List<T>). Skipping addition.",
this, GPALObjectType.Other);
135 internal void Add(List<T> row)
139 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
"Row is null in AddRow(List<T>). Skipping addition.",
this, GPALObjectType.Other);
145 public IAllowGridActions<T> Add(IGPALGrid<T> grid)
147 foreach (List<T> row
in grid)
180 public IAllowGridActions<T> AddRow(
object anonymousObject)
182 if (anonymousObject ==
null)
184 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
"Anonymous object is null in AddRow(object). Skipping addition.",
this, GPALObjectType.Other);
189 var values = anonymousObject.GetType()
191 .Select(prop => prop.GetValue(anonymousObject,
null))
197 int expectedColumns = Columns;
198 if (data.Count > 0 && values.Count != expectedColumns)
199 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"Anonymous object has [{values.Count}] values, but expected [{expectedColumns}]. Adding row as-is.",
this, GPALObjectType.Other);
203 var row =
new List<T>();
204 foreach (var value
in values)
213 row.Add((T)Convert.ChangeType(value, typeof(T)));
217 GPAL.PublishSimpleEvent(GPALEventType.ERROR, $
"Cannot convert value [{value}] to type [{typeof(T).Name}]. Using default value",
this, GPALObjectType.Other, ex);
255 public IAllowGridActions<T> AddRow(params T[] values)
259 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
"Values array is null in AddRow(params T[]). Skipping addition.",
this, GPALObjectType.Other);
266 int expectedColumns = Columns;
267 if (data.Count > 0 && values.Length != expectedColumns)
268 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"Params array has [{values.Length}] values, but expected [{expectedColumns}]. Adding row as-is.",
this, GPALObjectType.Other);
270 data.Add(
new List<T>(values));
298 public IAllowGridActions<T> DeleteRow(
int rowIdx)
300 if (rowIdx >= 0 && rowIdx < data.Count)
302 data.RemoveAt(rowIdx);
306 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"Invalid row index [{rowIdx}] in DeleteRow(int). Row count is [{data.Count}]. Skipping deletion.",
this, GPALObjectType.Other);
334 public IAllowGridActions<T> DeleteRow(RowPosition rowPosition = RowPosition.Last)
340 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
"Grid is empty in DeleteRow(RowPosition). Skipping deletion.",
this, GPALObjectType.Other);
344 if (rowPosition == RowPosition.First)
350 rowIdx = data.Count - 1;
353 data.RemoveAt(rowIdx);
383 public IAllowGridActions<T> AddColumn(List<T> column)
387 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
"Column is null in AddColumn. Skipping addition.",
this, GPALObjectType.Other);
391 for (
int i = 0; i < column.Count; i++)
395 data.Add(
new List<T>());
397 data[i].Add(column[i]);
405 public int Rows => data.Count;
417 foreach (var row
in data)
418 count = Math.Max(count, row.Count);
448 public IAllowGridActions<T> AddCell(T value,
int row,
int column)
450 if (row >= 0 && row < Rows && column >= 0 && column < Columns)
452 data[row][column] = value;
456 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"Invalid cell coordinates ([{row}], [{column}]) in AddCell. Grid size is [{Rows}]x[{Columns}]. Skipping operation.",
this, GPALObjectType.Other);
478 public T GetCell(
int row,
int column)
480 if (row >= 0 && row < Rows && column >= 0 && column < Columns)
482 return data[row][column];
485 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"Invalid cell coordinates ([{row}], [{column}]) in GetCell. Grid size is [{Rows}]x[{Columns}]. Returning default value.",
this, GPALObjectType.Other);
503 public IAllowGridActions<T> Clear()
505 data =
new List<List<T>>();
530 public List<T>
this[
int index]
534 if (index >= data.Count)
536 for (
int idx = index; idx >= data.Count; idx--)
537 data.Add(
new List<T>());
544 if (index >= data.Count)
546 for (
int idx = index; idx >= data.Count; idx--)
547 data.Add(
new List<T>());
552 GPAL.PublishSimpleEvent(GPALEventType.WARNING, $
"Value is null in indexer set at index [{index}]. Setting to empty list.",
this, GPALObjectType.Other);
553 data[index] =
new List<T>();
582 public T
this[
int row,
int column]
584 get {
return GetCell(row, column); }
585 set { AddCell(value, row, column); }
592 public IGPALGrid<T> ToGPALObject()
613 public bool Contains(T value)
617 GPAL.PublishSimpleEvent(GPALEventType.WARNING,
"Value is null in Contains. Returning false.",
this, GPALObjectType.Other);
621 string valueString = value.ToString();
622 foreach (List<T> list
in data)
623 foreach (T item
in list)
624 if (item !=
null && item.ToString().Contains(valueString))
634 public int Count() => data.Count();
640 public IEnumerator<List<T>> GetEnumerator()
642 return data.GetEnumerator();
649 IEnumerator IEnumerable.GetEnumerator()
651 return GetEnumerator();
673 public object Clone()
675 GPALGrid<T> clone =
new GPALGrid<T>();
677 foreach (List<T> row
in data)
679 List<T> clonedRow =
new List<T>();
680 foreach (T item
in row)
682 if (item is ICloneable cloneable)
684 clonedRow.Add((T)cloneable.Clone());
691 clone.AddRow(clonedRow);
703 public IAllowGridActions<T> InputFrom(GPALFile input)
705 FileHelper.TokenizeFile(input);
706 data = (List<List<T>>)((IGPALFileInternal)input).TokenList[0].Clone();
715 public IAllowGridActions<T> SaveTo(GPALFile output)
717 GPAL.Converter.WithInput(
this).SaveTo(output);
727 public IAllowGridActions<T> InputFrom(IGPALDatabase input)
729 throw new NotImplementedException();
738 public IAllowGridActions<T> SaveTo(IGPALDatabase output)
740 throw new NotImplementedException();
747 public List<T> ToList()
749 List<T> retVal =
new List<T>();
751 foreach (List<T> row
in data)
752 foreach (T col
in row)