using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using QC.CorpTest.Libraries.ExcelLibrary;
using QC.QTMInterface;
using QTMDataFormat;

namespace QC.TestResultsLite;

public class ExportToExcel : IDisposable
{
	private StringBuilder nonCriticalErrorMessage = new StringBuilder();

	private StringBuilder errorMessage = new StringBuilder();

	private DataTable resultsDT;

	private ArrayList testerConfigs;

	private SerialConfig dataLoggingConfig;

	private string fileCreated;

	private List<string> loopConditionsColumns;

	private string serialNo = "NA";

	public StringBuilder NonCriticalErrorMessage
	{
		get
		{
			return nonCriticalErrorMessage;
		}
		set
		{
			nonCriticalErrorMessage = value;
		}
	}

	public StringBuilder ErrorMessage
	{
		get
		{
			return errorMessage;
		}
		set
		{
			errorMessage = value;
		}
	}

	public DataTable ResultsDT
	{
		get
		{
			return resultsDT;
		}
		set
		{
			resultsDT = value;
		}
	}

	public ArrayList TesterConfigs
	{
		get
		{
			return testerConfigs;
		}
		set
		{
			testerConfigs = value;
		}
	}

	public SerialConfig DataLoggingConfig
	{
		get
		{
			return dataLoggingConfig;
		}
		set
		{
			dataLoggingConfig = value;
		}
	}

	public string FileCreated
	{
		get
		{
			return fileCreated;
		}
		set
		{
			fileCreated = value;
		}
	}

	public ExportToExcel(DataTable resultsData, ArrayList configs, SerialConfig loggingConfig, string strUnitSN)
	{
		ResultsDT = resultsData;
		DataLoggingConfig = loggingConfig;
		if (!string.IsNullOrEmpty(strUnitSN))
		{
			serialNo = strUnitSN;
		}
		if (configs.Count == 0)
		{
			TesterConfigs = new ArrayList();
			TesterConfigs.Add(new TesterConfigurationInfo("UUT_SN", serialNo));
		}
		else
		{
			TesterConfigs = configs;
		}
		StartExportToExcel();
	}

	private void StartExportToExcel()
	{
		if (ResultsDT != null && ResultsDT.Rows.Count > 0)
		{
			switch (DataLoggingConfig.ViewType)
			{
			case SerialConfig.ViewTypes.SingleUnitWideView:
				GetData(wideView: true);
				GenerateSingleUnitFormat();
				break;
			case SerialConfig.ViewTypes.SingleUnitView:
				GetData(wideView: false);
				GenerateSingleUnitFormat();
				break;
			case SerialConfig.ViewTypes.AllUnitsInOneSheet:
				if (DataLoggingConfig.AllUnitsFormatOption == SerialConfig.AllUnitsFormatOptions.WideFormat)
				{
					GetData(wideView: true);
				}
				else if (DataLoggingConfig.AllUnitsFormatOption == SerialConfig.AllUnitsFormatOptions.LongWideFormat)
				{
					GetLongWideView();
				}
				else
				{
					GetData(wideView: false);
				}
				GenerateAllUnitsFormat();
				break;
			case SerialConfig.ViewTypes.NoExcelLogging:
				break;
			}
			return;
		}
		throw new Exception("No data to export");
	}

	public void Dispose()
	{
		ResultsDT.Dispose();
		loopConditionsColumns = null;
		ExcelManager.ReleaseExcel();
		GC.Collect();
	}

	public static string GetFormattedTimeStamp(DateTime dtime)
	{
		return dtime.ToString("MM") + dtime.ToString("dd") + dtime.ToString("yy") + dtime.ToString("HH") + dtime.ToString("mm") + dtime.ToString("ss");
	}

	public void DisplayDataInExcelForSingleUnit(string sheetName, string fileName, ExcelCell configStartCell, ExcelCell dataStartCell)
	{
		try
		{
			ExcelManager.OpenExcel(showexcel: false);
			OpenWorkbookArguments openWorkbookArguments = new OpenWorkbookArguments();
			openWorkbookArguments.Filename = fileName;
			if (DataLoggingConfig.FileOption != 0 && File.Exists(fileName))
			{
				openWorkbookArguments.CreateNew = false;
			}
			else
			{
				openWorkbookArguments.CreateNew = true;
			}
			ExcelManager.OpenWorkBook(openWorkbookArguments);
			AddSheet(sheetName);
			InsertConfigInfo(configStartCell);
			InsertData(dataStartCell);
			ExcelManager.SelectWorkSheet(sheetName);
			SelectViewRange(1);
			ExcelManager.SaveCurrentWorkBook();
			if (DataLoggingConfig.OpenExcelAfterTestRun)
			{
				ExcelManager.SetExcelVisibility(excelVisible: true);
				ExcelManager.ReleaseExcel();
			}
			else
			{
				ExcelManager.CloseExcel();
			}
			FileCreated = fileName;
		}
		catch (Exception ex)
		{
			throw new Exception("DisplayDataInExcelForSingleUnit failed, " + ex.ToString());
		}
		finally
		{
			ExcelManager.ReleaseExcel();
		}
	}

	private void SelectViewRange(int colIndex)
	{
		try
		{
			ExcelRange excelRange = new ExcelRange(new ExcelCell(1, colIndex), new ExcelCell(2, colIndex + 1));
			ExcelManager.SelectRangeSelect(excelRange);
		}
		catch (Exception ex)
		{
			NonCriticalErrorMessage.Append("SelectViewRange failed, " + ex.Message);
		}
	}

	public void DisplayDataInExcelForAllUnitsView(string fileName)
	{
		try
		{
			ExcelManager.OpenExcel(showexcel: false);
			OpenWorkbookArguments openWorkbookArguments = new OpenWorkbookArguments();
			openWorkbookArguments.Filename = fileName;
			if (File.Exists(fileName))
			{
				openWorkbookArguments.CreateNew = false;
			}
			else
			{
				openWorkbookArguments.CreateNew = true;
			}
			ExcelManager.OpenWorkBook(openWorkbookArguments);
			ExcelCell dataStartCell = new ExcelCell(3, 1);
			List<string> sheetNames = ExcelManager.GetSheetNames();
			if (sheetNames.Contains(DataLoggingConfig.GroupName))
			{
				ExcelManager.SelectWorkSheet(DataLoggingConfig.GroupName);
				ExcelRange usedRange = ExcelManager.GetUsedRange();
				if (DataLoggingConfig.ViewType == SerialConfig.ViewTypes.AllUnitsInOneSheet && DataLoggingConfig.AllUnitsFormatOption == SerialConfig.AllUnitsFormatOptions.LongWideFormat)
				{
					InsertLongWideViewData(sheetExisted: true, dataStartCell);
				}
				else if (IsDataTheSame(usedRange))
				{
					dataStartCell = new ExcelCell(usedRange.EndCell.RowIndex + 1, usedRange.StartCell.ColumnIndex);
					AppendResultData(dataStartCell);
				}
				else
				{
					GetNewGroupName();
					InsertDataForAllUnits(dataStartCell);
				}
			}
			else
			{
				InsertDataForAllUnits(dataStartCell);
			}
			ExcelManager.SaveCurrentWorkBook();
			if (DataLoggingConfig.OpenExcelAfterTestRun)
			{
				ExcelManager.SetExcelVisibility(excelVisible: true);
				ExcelManager.ReleaseExcel();
			}
			else
			{
				ExcelManager.CloseExcel();
			}
			FileCreated = fileName;
		}
		catch (Exception ex)
		{
			throw new Exception("DisplayDataInExcel failed.\n " + ex.Message);
		}
		finally
		{
			ExcelManager.ReleaseExcel();
		}
	}

	private void GetNewGroupName()
	{
		ExcelGroupName excelGroupName = new ExcelGroupName();
		List<string> sheetNames = ExcelManager.GetSheetNames();
		if (DataLoggingConfig.PromptInvalidGroupName)
		{
			excelGroupName.GroupName = DataLoggingConfig.GroupName;
			excelGroupName.ShowDialog();
			while (sheetNames.Contains(excelGroupName.GroupName))
			{
				MessageBox.Show("Please choose a different group name, " + excelGroupName.GroupName + " already existed");
				excelGroupName.ShowDialog();
			}
		}
		else
		{
			excelGroupName.GroupName = DataLoggingConfig.GroupName + 1;
			while (sheetNames.Contains(excelGroupName.GroupName))
			{
				Random random = new Random();
				excelGroupName.GroupName = DataLoggingConfig.GroupName + random.Next(100);
			}
		}
		DataLoggingConfig.GroupName = excelGroupName.GroupName;
	}

	private List<string> GetDataRowFromExcel(string colName)
	{
		try
		{
			ExcelRange usedRange = ExcelManager.GetUsedRange();
			ExcelManager.FindFirstCellWithValue(colName, CellAddressType.R1C1, out var celladdress, out var _);
			if (!string.IsNullOrEmpty(celladdress))
			{
				int rowIndex = Convert.ToInt16(celladdress.Substring(1, celladdress.IndexOf("C") - 1)) + 1;
				int columnIndex = Convert.ToInt16(celladdress.Substring(celladdress.IndexOf("C") + 1));
				ExcelRange range = new ExcelRange(new ExcelCell(rowIndex, columnIndex), new ExcelCell(usedRange.EndCell.RowIndex, columnIndex));
				object[,] dataAsTwoDimensionalArray = ExcelManager.GetDataAsTwoDimensionalArray(range);
				List<string> list = new List<string>();
				object[,] array = dataAsTwoDimensionalArray;
				foreach (object obj in array)
				{
					list.Add(Convert.ToString(obj));
				}
				return list;
			}
		}
		catch (Exception ex)
		{
			NonCriticalErrorMessage.Append("GetDataFromExcel failed, " + ex.Message);
		}
		return new List<string>();
	}

	private DataTable GetDataTableFromExcel(string colName)
	{
		DataTable dataTable = new DataTable();
		try
		{
			ExcelRange usedRange = ExcelManager.GetUsedRange();
			ExcelManager.FindFirstCellWithValue(colName, CellAddressType.R1C1, out var celladdress, out var text);
			ExcelManager.FindFirstCellWithValue("LowerLimit", CellAddressType.R1C1, out var celladdress2, out text);
			if (!string.IsNullOrEmpty(celladdress) && !string.IsNullOrEmpty(celladdress2))
			{
				int rowIndex = Convert.ToInt16(celladdress.Substring(1, celladdress.IndexOf("C") - 1));
				int columnIndex = Convert.ToInt16(celladdress.Substring(celladdress.IndexOf("C") + 1));
				int columnIndex2 = Convert.ToInt16(celladdress2.Substring(celladdress2.IndexOf("C") + 1)) - 1;
				ExcelRange range = new ExcelRange(new ExcelCell(rowIndex, columnIndex), new ExcelCell(usedRange.EndCell.RowIndex, columnIndex2));
				object[,] dataAsTwoDimensionalArray = ExcelManager.GetDataAsTwoDimensionalArray(range);
				CreateDataTable(dataTable, dataAsTwoDimensionalArray);
				return dataTable;
			}
		}
		catch
		{
			NonCriticalErrorMessage.Append("GetDataTableFromExcel failed.");
		}
		return dataTable;
	}

	private void CreateDataTable(DataTable excelData, object[,] colDataValues)
	{
		for (int i = 1; i <= colDataValues.GetLength(1); i++)
		{
			DataColumn dataColumn = new DataColumn();
			dataColumn.ColumnName = Convert.ToString(colDataValues[1, i]).Replace(" ", "");
			excelData.Columns.Add(dataColumn);
		}
		for (int j = 2; j <= colDataValues.GetLength(0); j++)
		{
			DataRow dataRow = excelData.NewRow();
			for (int k = 1; k <= colDataValues.GetLength(1); k++)
			{
				dataRow[k - 1] = Convert.ToString(colDataValues[j, k]);
			}
			excelData.Rows.Add(dataRow);
		}
	}

	private List<string> GetDataRowFromDT(string colName)
	{
		try
		{
			List<string> list = new List<string>();
			foreach (DataRow row in ResultsDT.Rows)
			{
				list.Add(row[colName].ToString());
			}
			return list;
		}
		catch (Exception ex)
		{
			NonCriticalErrorMessage.Append("GetDataFromDT failed, " + ex.Message);
		}
		return new List<string>();
	}

	private void InsertLongWideViewData(bool sheetExisted, ExcelCell dataStartCell)
	{
		try
		{
			if (sheetExisted)
			{
				if (IsDataTheSameForLWView())
				{
					AppendLongWideViewData(dataStartCell);
					return;
				}
				GetNewGroupName();
				AddSheet(DataLoggingConfig.GroupName);
				InsertData(dataStartCell);
			}
			else
			{
				AddSheet(DataLoggingConfig.GroupName);
				InsertData(dataStartCell);
			}
		}
		catch (Exception ex)
		{
			throw new Exception("InsertLongWideViewData failed, " + ex.Message);
		}
	}

	private void AppendLongWideViewData(ExcelCell dataStartCell)
	{
		ExcelRange usedRange = ExcelManager.GetUsedRange();
		dataStartCell.ColumnIndex = usedRange.EndCell.ColumnIndex + 1;
		using DataTable dataTable = new DataTable();
		string columnName = ResultsDT.Columns[ResultsDT.Columns.Count - 1].ColumnName;
		dataTable.Columns.Add(columnName, ResultsDT.Columns[columnName].DataType);
		foreach (DataRow row in ResultsDT.Rows)
		{
			DataRow dataRow2 = dataTable.NewRow();
			dataRow2[columnName] = row[columnName];
			dataTable.Rows.Add(dataRow2);
		}
		ExcelManager.InsertDataTableUsingArray(dataTable, dataStartCell);
		ExcelRange excelRange = new ExcelRange(dataStartCell, new ExcelCell(usedRange.EndCell.RowIndex, dataStartCell.ColumnIndex));
		ExcelManager.ColumnAutoFit(excelRange);
		ExcelManager.SetRangeFontBold(new ExcelRange(dataStartCell, dataStartCell), enableBold: true);
		ExcelManager.SetRangeBackcolor(new ExcelRange(dataStartCell, dataStartCell), ConstantNames.TITLE_COLOR);
		ExcelManager.ClearAutoFilter();
		excelRange.StartCell.ColumnIndex = usedRange.StartCell.ColumnIndex;
		ExcelManager.SetAutoFilter(excelRange);
		if (DataLoggingConfig.EnableExcelCellColoring)
		{
			ColorParamNumValueForLWView(excelRange);
		}
	}

	private string GetStrValue(string colName, int rowIndex)
	{
		try
		{
			return ResultsDT.Rows[rowIndex][colName].ToString();
		}
		catch
		{
			return "";
		}
	}

	private bool IsSubSetForLWView()
	{
		try
		{
			DataTable dataTableFromExcel = GetDataTableFromExcel("TestName");
			DataColumn dataColumn = new DataColumn(ResultsDT.Columns[ResultsDT.Columns.Count - 1].ColumnName);
			dataColumn.DataType = typeof(string);
			dataColumn.DefaultValue = "";
			dataTableFromExcel.Columns.Add(dataColumn);
			DataTable dataTable = dataTableFromExcel.DefaultView.ToTable(true, "TestName");
			dataTable.PrimaryKey = new DataColumn[1] { dataTable.Columns[0] };
			DataTable dataTable2 = ResultsDT.DefaultView.ToTable(true, "TestName");
			foreach (DataRow row in dataTable2.Rows)
			{
				if (!dataTable.Rows.Contains(row["TestName"].ToString()))
				{
					return false;
				}
			}
			foreach (DataRow row2 in ResultsDT.Rows)
			{
				StringBuilder stringBuilder = new StringBuilder();
				for (int i = 0; i < loopConditionsColumns.Count + 2; i++)
				{
					if (stringBuilder.Length > 0)
					{
						stringBuilder.Append(" AND ");
					}
					string arg = ResultsDT.Columns[i].ColumnName.Replace(" ", "");
					string arg2 = Convert.ToString(row2[i]);
					stringBuilder.Append($"{arg} = '{arg2}'");
				}
				DataRow[] array = dataTableFromExcel.Select(stringBuilder.ToString());
				if (array.Length > 0)
				{
					DataRow[] array2 = array;
					foreach (DataRow dataRow3 in array2)
					{
						_ = array[0].ItemArray;
						dataRow3[ResultsDT.Columns[ResultsDT.Columns.Count - 1].ColumnName] = row2[ResultsDT.Columns.Count - 1].ToString();
					}
					continue;
				}
				return false;
			}
			ResultsDT = dataTableFromExcel;
			return true;
		}
		catch
		{
			return false;
		}
	}

	private bool IsDataTheSameForLWView()
	{
		try
		{
			string cellAddress = "$A$3";
			ExcelManager.GetCellContent(cellAddress, CellValue.Text, out var cellContent, out var _);
			if (!string.IsNullOrEmpty(cellContent) && cellContent == "TestName")
			{
				ExcelManager.GetUsedRange();
				List<string> dataRowFromExcel = GetDataRowFromExcel("TestName");
				List<string> dataRowFromDT = GetDataRowFromDT("TestName");
				if (!CompareLists(dataRowFromExcel, dataRowFromDT))
				{
					if (dataRowFromDT.Count < dataRowFromExcel.Count && IsSubSetForLWView())
					{
						return true;
					}
					return false;
				}
				return true;
			}
			return false;
		}
		catch
		{
			NonCriticalErrorMessage.Append("IsDataTheSameForLWView failed. ");
			return false;
		}
	}

	private string GetStrLimit(double limit)
	{
		try
		{
			if (limit.ToString() == "NaN")
			{
				return "";
			}
			return limit.ToString();
		}
		catch
		{
			return "";
		}
	}

	private void InsertLimitsAndUnits()
	{
		try
		{
			ExcelManager.FindFirstCellWithValue("UOM", CellAddressType.A1, FindOption.Whole, out var celladdress, out var text);
			ExcelManager.FindFirstCellWithValue("LowerLimit", CellAddressType.A1, FindOption.Whole, out var celladdress2, out text);
			ExcelManager.FindFirstCellWithValue("UpperLimit", CellAddressType.A1, FindOption.Whole, out var celladdress3, out text);
			if (string.IsNullOrEmpty(celladdress) && string.IsNullOrEmpty(celladdress2) && string.IsNullOrEmpty(celladdress3))
			{
				return;
			}
			Dictionary<string, ParameterInfo> currentParamInfoDictionary = FormatFunctions.CurrentParamInfoDictionary;
			object[,] array = new object[3, currentParamInfoDictionary.Keys.Count];
			int num = 0;
			string text2 = null;
			foreach (string key in currentParamInfoDictionary.Keys)
			{
				text2 = text2 ?? key;
				ParameterInfo parameterInfo = currentParamInfoDictionary[key];
				array[0, num] = GetStrLimit(parameterInfo.LowerLimit);
				array[1, num] = GetStrLimit(parameterInfo.UpperLimit);
				array[2, num] = parameterInfo.Units;
				num++;
			}
			ExcelManager.FindFirstCellWithValue(text2, CellAddressType.R1C1, FindOption.Whole, out var celladdress4, out text);
			int rowIndex = Convert.ToInt16(celladdress2.Substring(celladdress2.LastIndexOf("$") + 1));
			int columnIndex = Convert.ToInt16(celladdress4.Substring(celladdress4.IndexOf("C") + 1));
			ExcelManager.InsertTwoDimensionalArray(array, new ExcelCell(rowIndex, columnIndex));
		}
		catch
		{
			NonCriticalErrorMessage.Append("InsertLimitsAndUnits failed. ");
		}
	}

	private void InsertDataForAllUnits(ExcelCell dataStartCell)
	{
		if (DataLoggingConfig.AllUnitsFormatOption == SerialConfig.AllUnitsFormatOptions.WideFormat)
		{
			AddExcelTemplate();
			ExcelRange usedRange = ExcelManager.GetUsedRange();
			dataStartCell = new ExcelCell(usedRange.EndCell.RowIndex + 1, 1);
			InsertRangeForFormulasToExtend(dataStartCell);
			CopyFormulasToOtherColumns();
			ClearStatsForNonDataCols();
			InsertData(dataStartCell);
			InsertLimitsAndUnits();
		}
		else if (DataLoggingConfig.AllUnitsFormatOption == SerialConfig.AllUnitsFormatOptions.LongWideFormat)
		{
			InsertLongWideViewData(sheetExisted: false, dataStartCell);
		}
		else
		{
			AddSheet(DataLoggingConfig.GroupName);
			InsertData(dataStartCell);
		}
		SelectViewRange(1);
	}

	private void ClearStatsForNonDataCols()
	{
		try
		{
			ExcelRange usedRange = ExcelManager.GetUsedRange();
			if (loopConditionsColumns.Count > 0)
			{
				ExcelRange range = new ExcelRange(new ExcelCell(usedRange.StartCell.RowIndex, 2), new ExcelCell(usedRange.EndCell.RowIndex, loopConditionsColumns.Count - 1 + 2));
				ExcelManager.ClearContents(range);
			}
			ExcelRange range2 = new ExcelRange(new ExcelCell(usedRange.StartCell.RowIndex, usedRange.EndCell.ColumnIndex - (testerConfigs.Count - 1)), new ExcelCell(usedRange.EndCell.RowIndex, usedRange.EndCell.ColumnIndex));
			ExcelManager.ClearContents(range2);
		}
		catch
		{
			NonCriticalErrorMessage.Append("CopyFormulaToOtherColumns failed");
		}
	}

	private void AddExcelTemplate()
	{
		if (!string.IsNullOrEmpty(DataLoggingConfig.ExcelTemplate) && File.Exists(DataLoggingConfig.ExcelTemplate))
		{
			AddSheetArguments addSheetArguments = new AddSheetArguments();
			addSheetArguments = new AddSheetArguments();
			addSheetArguments.SheetName = DataLoggingConfig.GroupName;
			addSheetArguments.TypeAsString = DataLoggingConfig.ExcelTemplate;
			List<string> sheetNames = ExcelManager.GetSheetNames();
			addSheetArguments.BeforeAsString = sheetNames[0].ToString();
			ExcelManager.AddSheet(addSheetArguments);
			ExcelManager.SelectWorkSheet(addSheetArguments.SheetName);
		}
		else
		{
			AddSheet(DataLoggingConfig.GroupName);
			ErrorMessage.Append("Test Results: Excel template specified in Data Collection Configuration is not valid ");
		}
		ExcelRange usedRange = ExcelManager.GetUsedRange();
		ExcelCell excelCell = new ExcelCell(usedRange.EndCell.RowIndex + 1, usedRange.StartCell.ColumnIndex);
		ExcelManager.SetCellValue(excelCell, "LowerLimit");
		excelCell.RowIndex++;
		ExcelManager.SetCellValue(excelCell, "UpperLimit");
		excelCell.RowIndex++;
		ExcelManager.SetCellValue(excelCell, "UOM");
	}

	private void CopyFormulasToOtherColumns()
	{
		try
		{
			ExcelRange usedRange = ExcelManager.GetUsedRange();
			ExcelRange sourceRange = new ExcelRange(new ExcelCell(usedRange.StartCell.RowIndex, 2), new ExcelCell(usedRange.EndCell.RowIndex, 2));
			ExcelRange destinationRange = new ExcelRange(new ExcelCell(usedRange.StartCell.RowIndex, 2), new ExcelCell(usedRange.EndCell.RowIndex, ResultsDT.Columns.Count + 1));
			ExcelManager.CopyRange(sourceRange, destinationRange);
		}
		catch
		{
			NonCriticalErrorMessage.Append("CopyFormulaToOtherColumns failed");
		}
	}

	private static void AddSheet(string sheetName)
	{
		AddSheetArguments addSheetArguments = new AddSheetArguments();
		addSheetArguments.SheetName = sheetName;
		List<string> sheetNames = ExcelManager.GetSheetNames();
		addSheetArguments.BeforeAsString = sheetNames[0].ToString();
		ExcelManager.AddSheet(addSheetArguments);
		ExcelManager.SelectWorkSheet(addSheetArguments.SheetName);
	}

	private void InsertRangeForFormulasToExtend(ExcelCell startCell)
	{
		try
		{
			ExcelRange excelRange = new ExcelRange(new ExcelCell(startCell.RowIndex, 1), new ExcelCell(ResultsDT.Rows.Count + startCell.RowIndex, ResultsDT.Columns.Count));
			ExcelManager.SelectRangeAndInsert(excelRange);
		}
		catch (Exception ex)
		{
			NonCriticalErrorMessage.Append("InsertRangeForFormulasToExtend failed " + ex.Message);
		}
	}

	private void ColorParamNumValue(ExcelRange dataRange)
	{
		if (dataRange == null)
		{
			return;
		}
		try
		{
			ExcelManager.FindFirstCellWithValue("NumValue", CellAddressType.A1, out var celladdress, out var text);
			ExcelManager.FindFirstCellWithValue("LowerLimit", CellAddressType.A1, out var celladdress2, out text);
			ExcelManager.FindFirstCellWithValue("UpperLimit", CellAddressType.A1, out var celladdress3, out text);
			ExcelManager.FindFirstCellWithValue("TestResult", CellAddressType.A1, out var celladdress4, out text);
			ExcelManager.FindFirstCellWithValue("ParamResult", CellAddressType.A1, out var _, out text);
			if (!string.IsNullOrEmpty(celladdress) && !string.IsNullOrEmpty(celladdress2) && !string.IsNullOrEmpty(celladdress3) && !string.IsNullOrEmpty(celladdress4))
			{
				ExcelManager.FindFirstCellWithValue("NumValue", CellAddressType.R1C1, out var celladdress6, out text);
				int columnIndex = Convert.ToInt16(celladdress6.Substring(celladdress6.IndexOf('C') + 1));
				ExcelRange range = new ExcelRange(new ExcelCell(dataRange.StartCell.RowIndex, columnIndex), new ExcelCell(dataRange.EndCell.RowIndex, columnIndex));
				celladdress = celladdress.Substring(1, celladdress.LastIndexOf("$") - 1) + dataRange.StartCell.RowIndex;
				celladdress3 = celladdress3.Substring(1, celladdress3.LastIndexOf("$") - 1) + dataRange.StartCell.RowIndex;
				celladdress2 = celladdress2.Substring(1, celladdress2.LastIndexOf("$") - 1) + dataRange.StartCell.RowIndex;
				celladdress4 = celladdress4.Substring(1, celladdress4.LastIndexOf("$") - 1) + dataRange.StartCell.RowIndex;
				string text2 = $"OR({celladdress}>{celladdress3},{celladdress}<{celladdress2})";
				string formula = string.Format("=AND(AND({0}=\"{1}\", {2}),NOT(ISBLANK({3})))", celladdress4, "Passed", text2, celladdress);
				string formula2 = string.Format("=AND(AND({0}=\"{1}\", {2}),NOT(ISBLANK({3})))", celladdress4, "Failed", text2, celladdress);
				ExcelManager.SetConditionalFormatting(range, FormattingRuleType.Formula, formula, Color.Black, Color.Salmon);
				ExcelManager.SetConditionalFormatting(range, FormattingRuleType.Formula, formula2, Color.Black, Color.Red);
				return;
			}
			throw new ArgumentException("Can't find LowerLimit, UpperLimit, NumValue or TestResult column from the provided dataRange.");
		}
		catch (Exception ex)
		{
			throw new ExcelException($"ColorParamNumValue failed, {ex.Message}, {ex.Source}");
		}
	}

	private void ColorParamNumValueForLWView(ExcelRange dataRange)
	{
		if (dataRange == null)
		{
			return;
		}
		try
		{
			ExcelManager.FindFirstCellWithValue("LowerLimit", CellAddressType.A1, out var celladdress, out var text);
			ExcelManager.FindFirstCellWithValue("UpperLimit", CellAddressType.A1, out var celladdress2, out text);
			string cellAddress = $"R{dataRange.StartCell.RowIndex + 1}C{dataRange.EndCell.ColumnIndex}";
			cellAddress = ExcelManager.ConvertCellAddress(cellAddress, CellAddressType.R1C1, CellAddressType.A1);
			if (!string.IsNullOrEmpty(cellAddress) && !string.IsNullOrEmpty(celladdress) && !string.IsNullOrEmpty(celladdress2))
			{
				ExcelRange range = new ExcelRange(new ExcelCell(dataRange.StartCell.RowIndex + 1, dataRange.EndCell.ColumnIndex), new ExcelCell(dataRange.EndCell.RowIndex, dataRange.EndCell.ColumnIndex));
				cellAddress = cellAddress.Replace("$", "");
				celladdress2 = celladdress2.Substring(1, celladdress2.LastIndexOf("$") - 1) + (dataRange.StartCell.RowIndex + 1);
				celladdress = celladdress.Substring(1, celladdress.LastIndexOf("$") - 1) + (dataRange.StartCell.RowIndex + 1);
				string formula = $"=OR({cellAddress}>{celladdress2},{cellAddress}<{celladdress})";
				ExcelManager.SetConditionalFormatting(range, FormattingRuleType.Formula, formula, Color.Black, Color.Red);
				return;
			}
			throw new ArgumentException("Can't find LowerLimit, UpperLimit,or NumValue column from the provided dataRange.");
		}
		catch (Exception ex)
		{
			throw new ExcelException($"ColorParamNumValue failed, {ex.Message}, {ex.Source}");
		}
	}

	private void InsertData(ExcelCell startCell)
	{
		ExcelManager.InsertDataTableUsingArray(ResultsDT, startCell);
		ExcelRange usedRange = ExcelManager.GetUsedRange();
		ExcelRange excelRange = new ExcelRange(startCell, new ExcelCell(usedRange.EndCell.RowIndex, ResultsDT.Columns.Count));
		ExcelManager.SetAutoFilter(excelRange);
		if (DataLoggingConfig.EnableExcelCellColoring && (DataLoggingConfig.ViewType == SerialConfig.ViewTypes.SingleUnitView || (DataLoggingConfig.ViewType == SerialConfig.ViewTypes.AllUnitsInOneSheet && DataLoggingConfig.AllUnitsFormatOption == SerialConfig.AllUnitsFormatOptions.LongFormat)))
		{
			ColorParamNumValue(excelRange);
		}
		if (DataLoggingConfig.EnableExcelCellColoring && DataLoggingConfig.ViewType == SerialConfig.ViewTypes.AllUnitsInOneSheet && DataLoggingConfig.AllUnitsFormatOption == SerialConfig.AllUnitsFormatOptions.LongWideFormat)
		{
			ColorParamNumValueForLWView(excelRange);
		}
		ExcelRange excelRange2 = new ExcelRange();
		excelRange2.StartCell = excelRange.StartCell.Copy();
		excelRange2.EndCell = new ExcelCell(excelRange2.StartCell.RowIndex, excelRange.EndCell.ColumnIndex);
		ExcelManager.SetRangeFontBold(excelRange2, enableBold: true);
		ExcelManager.SetRangeBackcolor(excelRange2, ConstantNames.TITLE_COLOR);
		ExcelManager.ColumnAutoFit(excelRange2);
		SetColumnWidth("TreeFileName", 40);
	}

	private void AppendResultData(ExcelCell startCell)
	{
		if (DataLoggingConfig.AllUnitsFormatOption == SerialConfig.AllUnitsFormatOptions.WideFormat)
		{
			InsertRangeForFormulasToExtend(startCell);
		}
		ExcelManager.InsertDataTableUsingArray(ResultsDT, startCell);
		ExcelRange usedRange = ExcelManager.GetUsedRange();
		ExcelRange excelRange = new ExcelRange(startCell, new ExcelCell(usedRange.EndCell.RowIndex, ResultsDT.Columns.Count));
		ExcelManager.DeleteEntireRow(startCell.RowIndex, shiftRows: true);
		ExcelManager.ColumnAutoFit(excelRange);
		if (DataLoggingConfig.EnableExcelCellColoring && (DataLoggingConfig.ViewType == SerialConfig.ViewTypes.SingleUnitView || (DataLoggingConfig.ViewType == SerialConfig.ViewTypes.AllUnitsInOneSheet && DataLoggingConfig.AllUnitsFormatOption == SerialConfig.AllUnitsFormatOptions.LongFormat)))
		{
			ColorParamNumValue(excelRange);
		}
		SelectViewRange(1);
	}

	private void SetColumnWidth(string colName, int width)
	{
		if (ResultsDT.Columns.Contains(colName))
		{
			int num = ResultsDT.Columns.IndexOf(colName);
			ExcelManager.SetColumnWidth(num + 1, width);
		}
	}

	private void InsertConfigInfo(ExcelCell configStartCell)
	{
		ExcelManager.InsertTwoDimensionalArray(TwoDimArrayConfigs(), configStartCell);
		ExcelRange usedRange = ExcelManager.GetUsedRange();
		ExcelRange excelRange = new ExcelRange();
		excelRange.StartCell = usedRange.StartCell.Copy();
		excelRange.EndCell = new ExcelCell(excelRange.StartCell.RowIndex, usedRange.EndCell.ColumnIndex);
		ExcelManager.SetRangeFontBold(excelRange, enableBold: true);
		ExcelManager.ColumnAutoFit(usedRange);
		ExcelManager.SetRangeBackcolor(excelRange, ConstantNames.TITLE_COLOR);
	}

	public string[,] TwoDimArrayConfigs()
	{
		string[,] array = new string[2, TesterConfigs.Count];
		try
		{
			for (int i = 0; i < TesterConfigs.Count; i++)
			{
				array[0, i] = ((TesterConfigurationInfo)TesterConfigs[i]).Name;
				if (((TesterConfigurationInfo)TesterConfigs[i]).Name == "UUT_SN")
				{
					array[1, i] = serialNo;
				}
				else
				{
					array[1, i] = ((TesterConfigurationInfo)TesterConfigs[i]).Value;
				}
			}
		}
		catch (Exception ex)
		{
			NonCriticalErrorMessage.Append("ConvertToTwoDimArray failed, " + ex.Message);
		}
		return array;
	}

	public void GenerateSingleUnitFormat()
	{
		if (GetFileNameForSingleUnit(out var SheetName, out var ExcelWorkbookName) && IsDirectoryValid(ExcelWorkbookName))
		{
			ExcelCell configStartCell = new ExcelCell(1, 1);
			ExcelCell dataStartCell = new ExcelCell(4, 1);
			DisplayDataInExcelForSingleUnit(SheetName, ExcelWorkbookName, configStartCell, dataStartCell);
		}
	}

	private string GetFileName(string fName)
	{
		FileInfo fileInfo = new FileInfo(fName);
		if (string.IsNullOrEmpty(fileInfo.Name))
		{
			throw new Exception($"File Name {fileInfo.FullName} is invalid.");
		}
		if (!fileInfo.Name.Contains(".xls") && !fileInfo.Name.Contains(".xlsx"))
		{
			fName += ".xlsx";
		}
		return fName;
	}

	public void GenerateAllUnitsFormat()
	{
		try
		{
			if (IsDirectoryValid(DataLoggingConfig.OutputFile))
			{
				AddConfigColumnsToResultsDT();
				DisplayDataInExcelForAllUnitsView(GetFileName(DataLoggingConfig.OutputFile));
			}
		}
		catch (Exception ex)
		{
			throw new Exception("GenerateAllUnitsFormat failed, " + ex.Message);
		}
	}

	private void AddConfigColumnsToResultsDT()
	{
		try
		{
			if (DataLoggingConfig.ViewType == SerialConfig.ViewTypes.AllUnitsInOneSheet && DataLoggingConfig.AllUnitsFormatOption == SerialConfig.AllUnitsFormatOptions.LongWideFormat)
			{
				return;
			}
			foreach (TesterConfigurationInfo testerConfig in TesterConfigs)
			{
				DataColumn dataColumn = new DataColumn();
				dataColumn.ColumnName = testerConfig.Name;
				if (testerConfig.Name == "UUT_SN")
				{
					dataColumn.DefaultValue = serialNo;
				}
				else
				{
					dataColumn.DefaultValue = testerConfig.Value.ToString();
				}
				dataColumn.DataType = typeof(string);
				if (!ResultsDT.Columns.Contains(dataColumn.ColumnName))
				{
					ResultsDT.Columns.Add(dataColumn);
				}
			}
			if (ResultsDT.Columns.Contains("UUT_SN"))
			{
				ResultsDT.Columns["UUT_SN"].SetOrdinal(0);
			}
		}
		catch (Exception ex)
		{
			NonCriticalErrorMessage.Append("AddConfigColumnsToResultsDT failed, " + ex.Message);
		}
	}

	private void GetData(bool wideView)
	{
		if (wideView && ResultsDT != null && ResultsDT.Rows.Count > 0)
		{
			using DataTable resultsDTCopy = ResultsDT.Copy();
			GetWideView(resultsDTCopy);
			RemoveColumn("UOM");
			RemoveColumn("TestResult");
			RemoveColumn("ParamResult");
		}
		else if (!wideView && ResultsDT != null && ResultsDT.Rows.Count > 0)
		{
			RemoveColumn("ArrayParamCharResult");
			RemoveColumn("ArrayLowerLimit");
			RemoveColumn("ArrayResult");
			RemoveColumn("ArrayUpperLimit");
			RemoveColumn("ArrayParamIndex");
			RemoveColumn("Array Param Name");
		}
		ParseLoopConditions("ScnValue");
		RemoveColumn("ScnValue");
		RemoveColumn("UUT_SN");
		RemoveColumn("SessionDataRID");
		ReOrganizeColsIndex(wideView);
	}

	private void RemoveColumn(string colName)
	{
		try
		{
			if (ResultsDT.Columns.Contains(colName))
			{
				ResultsDT.Columns.Remove(colName);
			}
		}
		catch (Exception ex)
		{
			NonCriticalErrorMessage.Append("RemoveColumn failed, " + ex.Message);
		}
	}

	private bool IsDirectoryValid(string fileName)
	{
		string directoryName = Path.GetDirectoryName(fileName);
		if (!Directory.Exists(directoryName))
		{
			try
			{
				Directory.CreateDirectory(directoryName);
			}
			catch (Exception ex)
			{
				throw new DirectoryNotFoundException("\n Error exporting to excel - Error creating output directory" + ex.Message);
			}
		}
		return true;
	}

	private void ParseLoopConditions(string loopConditionName)
	{
		string text = "";
		ResultsDT = FormatFunctions.ParseLoopConditions(ResultsDT, loopConditionName, removedelimitedcolumn: false, out loopConditionsColumns, out text);
		if (text.Length > 0)
		{
			NonCriticalErrorMessage.Append($"Error parsing loop conditions - {text}");
		}
	}

	private void ReOrganizeColsIndex(bool wideView)
	{
		if (wideView)
		{
			int num = 0;
			foreach (string loopConditionsColumn in loopConditionsColumns)
			{
				SetColumnIndex(loopConditionsColumn, num);
				num++;
			}
			SetColumnIndex("UOM", ResultsDT.Columns.Count - 1);
			SetColumnIndex("TestResult", ResultsDT.Columns.Count - 1);
			SetColumnIndex("ParamResult", ResultsDT.Columns.Count - 1);
			return;
		}
		int num2 = 2;
		foreach (string loopConditionsColumn2 in loopConditionsColumns)
		{
			SetColumnIndex(loopConditionsColumn2, num2);
			num2++;
		}
	}

	private void SetColumnIndex(string colName, int newIndex)
	{
		try
		{
			ResultsDT.Columns[colName].SetOrdinal(newIndex);
		}
		catch
		{
			NonCriticalErrorMessage.Append($"SetColumnIndex for {colName} failed, ");
		}
	}

	private void GetWideView(DataTable resultsDTCopy)
	{
		resultsDTCopy.Columns.Remove("ParameterName");
		resultsDTCopy.Columns["Array Param Name"].ColumnName = "ParameterName";
		resultsDTCopy.Columns.Remove("SessionDataRID");
		DataColumn dataColumn = new DataColumn("SessionDataRID", typeof(int));
		dataColumn.DefaultValue = 0;
		resultsDTCopy.Columns.Add(dataColumn);
		FormatFunctions.ResetViews();
		FormatArgs fargs = new FormatArgs();
		fargs.DataSource = resultsDTCopy;
		fargs.EnableColumnSelection = false;
		fargs.IgnoreLimits = false;
		fargs.IgnoreLoopConditions = false;
		fargs.IncludeParamRunTimeLimits = false;
		fargs.IsQMTDatabase = false;
		fargs.SelectedFormatOption = FormatFunctions.FormatOptions.WideView;
		bool isCancelled = false;
		ResultsDT = FormatFunctions.GetDataInExpandedOrWideView(ref fargs, out var text, ref isCancelled);
		if (ResultsDT == null || text != "")
		{
			throw new Exception("Error retrieving wide view");
		}
	}

	private void MergeParamResults()
	{
		try
		{
			using (DataTable dataTable = ResultsDT.Copy())
			{
				dataTable.Columns.Remove("NumValue");
				DataColumn column = new DataColumn("NumValue", typeof(string));
				dataTable.Columns.Add(column);
				string columnName = "NumValue";
				for (int i = 0; i < ResultsDT.Rows.Count; i++)
				{
					dataTable.Rows[i][columnName] = ResultsDT.Rows[i][columnName].ToString();
				}
				ResultsDT = dataTable;
			}
			foreach (DataRow row in ResultsDT.Rows)
			{
				if (string.IsNullOrEmpty(row["NumValue"].ToString()) && !string.IsNullOrEmpty(row["CharValue"].ToString()))
				{
					row["NumValue"] = row["CharValue"].ToString();
				}
			}
		}
		catch (Exception ex)
		{
			NonCriticalErrorMessage.Append("MergeParamResults failed, " + ex.Message);
		}
	}

	private void GetLongWideView()
	{
		ParseLoopConditions("ScnValue");
		ReOrganizeColsIndex(wideView: false);
		if (DataLoggingConfig.ShowCharValue)
		{
			MergeParamResults();
		}
		RemoveColumn("UUT_SN");
		RemoveColumn("ScnValue");
		RemoveColumn("CharValue");
		RemoveColumn("SessionDataRID");
		RemoveColumn("TestResult");
		RemoveColumn("ParamResult");
		RemoveColumn("ArrayParamCharResult");
		RemoveColumn("ArrayLowerLimit");
		RemoveColumn("ArrayResult");
		RemoveColumn("ArrayUpperLimit");
		RemoveColumn("ArrayParamIndex");
		RemoveColumn("Array Param Name");
		SetColumnIndex("ParameterName", 0);
		SetColumnIndex("TestName", 0);
		SetColumnIndex("UOM", ResultsDT.Columns.Count - 1);
		SetColumnIndex("NumValue", ResultsDT.Columns.Count - 1);
		ResultsDT.Columns["NumValue"].ColumnName = serialNo;
	}

	private bool GetFileNameForSingleUnit(out string SheetName, out string ExcelWorkbookName)
	{
		ExcelWorkbookName = DataLoggingConfig.ExcelFileName;
		SheetName = "Default";
		try
		{
			string formattedTimeStamp = GetFormattedTimeStamp(DateTime.Now);
			if (DataLoggingConfig.FileOption == SerialConfig.FileOptions.NewFile)
			{
				string fileLocation = DataLoggingConfig.FileLocation;
				string path = serialNo + "_" + formattedTimeStamp + ".xlsx";
				Path.Combine(fileLocation, serialNo + "_" + formattedTimeStamp + ".xlsx");
				ExcelWorkbookName = Path.Combine(fileLocation, path);
				SheetName = serialNo + "_" + formattedTimeStamp;
			}
			else
			{
				ExcelWorkbookName = GetFileName(DataLoggingConfig.ExcelFileName);
				SheetName = serialNo + "_" + formattedTimeStamp;
			}
			if (SheetName.Length > 31)
			{
				SheetName = SheetName.Substring(0, 31);
			}
			return true;
		}
		catch
		{
			throw new Exception("\nError creating sheet name. ");
		}
	}

	private bool IsDataTheSame(ExcelRange usedRange)
	{
		try
		{
			List<string> dataColFromExcel = GetDataColFromExcel();
			List<string> dataColFromDT = GetDataColFromDT();
			if (!CompareLists(dataColFromExcel, dataColFromDT))
			{
				if (dataColFromDT.Count < dataColFromExcel.Count && DataLoggingConfig.AllUnitsFormatOption == SerialConfig.AllUnitsFormatOptions.WideFormat)
				{
					DataTable dataTable = ResultsDT.Copy();
					for (int i = 0; i < dataColFromExcel.Count; i++)
					{
						if (!ResultsDT.Columns.Contains(dataColFromExcel[i].ToString()))
						{
							DataColumn dataColumn = new DataColumn(dataColFromExcel[i].ToString());
							ResultsDT.Columns.Add(dataColumn);
							ResultsDT.Columns[dataColumn.ColumnName].SetOrdinal(i);
						}
						if (ResultsDT.Columns.Count > dataColFromExcel.Count)
						{
							ResultsDT = dataTable.Copy();
							return false;
						}
					}
					dataColFromDT = GetDataColFromDT();
					if (CompareLists(dataColFromExcel, dataColFromDT))
					{
						return true;
					}
					ResultsDT = dataTable.Copy();
					return false;
				}
				return false;
			}
			return true;
		}
		catch (Exception ex)
		{
			NonCriticalErrorMessage.Append("IsDataTheSame failed, " + ex.Message);
			return false;
		}
	}

	private List<string> GetDataColFromDT()
	{
		try
		{
			List<string> list = new List<string>();
			foreach (DataColumn column in ResultsDT.Columns)
			{
				list.Add(column.ColumnName);
			}
			return list;
		}
		catch (Exception ex)
		{
			NonCriticalErrorMessage.Append("GetDataFromDT failed, " + ex.Message);
		}
		return new List<string>();
	}

	private List<string> GetDataColFromExcel()
	{
		try
		{
			ExcelRange usedRange = ExcelManager.GetUsedRange();
			ExcelManager.FindFirstCellWithValue("UUT_SN", CellAddressType.A1, FindOption.Whole, out var celladdress, out var _);
			if (!string.IsNullOrEmpty(celladdress))
			{
				int rowIndex = Convert.ToInt16(celladdress.Substring(celladdress.LastIndexOf('$') + 1));
				ExcelCell startCell = new ExcelCell(rowIndex, 1);
				ExcelCell endCell = new ExcelCell(rowIndex, usedRange.EndCell.ColumnIndex);
				ExcelRange range = new ExcelRange(startCell, endCell);
				object[,] dataAsTwoDimensionalArray = ExcelManager.GetDataAsTwoDimensionalArray(range);
				List<string> list = new List<string>();
				object[,] array = dataAsTwoDimensionalArray;
				foreach (object obj in array)
				{
					list.Add(Convert.ToString(obj));
				}
				return list;
			}
		}
		catch (Exception ex)
		{
			NonCriticalErrorMessage.Append("GetDataColFromExcel failed, " + ex.Message);
		}
		return new List<string>();
	}

	private bool CompareLists(List<string> list1, List<string> list2)
	{
		if (list1.Count != list2.Count)
		{
			return false;
		}
		for (int i = 0; i < list1.Count; i++)
		{
			if (!list1[i].Equals(list2[i]))
			{
				return false;
			}
		}
		return true;
	}
}
