using System;
using System.Collections.Generic;
using System.Linq;

namespace QC.CTDS.DM.SharedLibrary;

public class Table<T>
{
	private List<List<T>> internalTbl = new List<List<T>>();

	private Dictionary<string, int> columnDict = new Dictionary<string, int>(StringComparer.Ordinal);

	private List<int> headerRowIndicies = new List<int>();

	public List<int> HeaderRowIndicies
	{
		get
		{
			return headerRowIndicies;
		}
		set
		{
			value = headerRowIndicies;
		}
	}

	public int RowCount => internalTbl.Count;

	public int ColumnCount => columnDict.Count;

	public int AddColumn()
	{
		string text = "Column_" + columnDict.Keys.Count;
		if (!columnDict.ContainsKey(text))
		{
			return AddColumn(text);
		}
		return -1;
	}

	public int AddColumn(string columnName)
	{
		int num = -1;
		if (string.IsNullOrEmpty(columnName))
		{
			throw new ArgumentException("empty column names are not allowed");
		}
		if (columnDict.ContainsKey(columnName))
		{
			throw new Exception("Column with name" + columnName + " already present");
		}
		num = columnDict.Count;
		columnDict.Add(columnName, num);
		FillCurrentRowsForNewColumn();
		return num;
	}

	public string GetColumnName(int columnIndex)
	{
		for (int i = 0; i < columnDict.Count; i++)
		{
			if (columnDict.ElementAt(i).Value == columnIndex)
			{
				return columnDict.ElementAt(i).Key;
			}
		}
		return null;
	}

	public int GetColumnIndex(string columnName)
	{
		for (int i = 0; i < columnDict.Count; i++)
		{
			if (columnDict.ElementAt(i).Key == columnName)
			{
				return columnDict.ElementAt(i).Value;
			}
		}
		return -1;
	}

	private void FillCurrentRowsForNewColumn()
	{
		for (int i = 0; i < internalTbl.Count; i++)
		{
			internalTbl[i].Add(default(T));
		}
	}

	public T GetValue(int rowIndex, int columnIndex)
	{
		if (internalTbl.Count > rowIndex && internalTbl[rowIndex].Count > columnIndex)
		{
			return internalTbl[rowIndex][columnIndex];
		}
		throw new ArgumentException("row index or column index out of range");
	}

	public T GetValue(int rowIndex, string columnName)
	{
		if (columnDict.ContainsKey(columnName))
		{
			return GetValue(rowIndex, columnDict[columnName]);
		}
		throw new ArgumentException("Column " + columnName + " doesn't exist");
	}

	public void SetValue(T val, int rowIndex, int columnIndex)
	{
		if (internalTbl.Count > rowIndex)
		{
			if (internalTbl[rowIndex].Count > columnIndex)
			{
				internalTbl[rowIndex][columnIndex] = val;
				return;
			}
			throw new Exception("column index specified doesn't exist");
		}
		throw new Exception("row specifed doesn't exist");
	}

	public int AddNewRow()
	{
		List<T> list = new List<T>();
		for (int i = 0; i < columnDict.Count; i++)
		{
			list.Add(default(T));
		}
		internalTbl.Add(list);
		return internalTbl.IndexOf(list);
	}

	public bool ContainsColumn(string colName)
	{
		bool result = false;
		if (columnDict != null && columnDict.Count > 0 && columnDict.ContainsKey(colName))
		{
			result = true;
		}
		return result;
	}

	public void DeleteRow(int index)
	{
		if (internalTbl.Count > index)
		{
			internalTbl.RemoveAt(index);
			return;
		}
		throw new Exception("Invalid row index entered");
	}

	public void DeleteColumn(string colKey)
	{
		if (columnDict != null && columnDict.ContainsKey(colKey))
		{
			columnDict.Remove(colKey);
			return;
		}
		throw new Exception("Invalid row index entered");
	}
}
