using System;
using System.Collections.Generic;
using System.Data;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Media;
using QC.QsprShared.Trace;
using QC.QsprShared.Utilities;
using QC.QsprTestObjects.Parameters;
using QC.QTMInterface;

namespace QC.QTMApplication;

public class InputParameterValueDataTemplateSelector : DataTemplateSelector
{
	private DataRowView currentDataRowView;

	private bool isReadOnly;

	public DataTemplate MultilineStringEditCellDataTemplate { get; set; }

	public DataTemplate InputParameterFileNameEditCellDataTemplate { get; set; }

	public DataTemplate InputParameterDataTableEditCellDataTemplate { get; set; }

	public DataTemplate InputArrayEditCellDataTemplate { get; set; }

	public DataTemplate DefaultCellEditTemplate { get; set; }

	public DataTemplate ErrorValidationTemplate { get; set; }

	public override DataTemplate SelectTemplate(object item, DependencyObject container)
	{
		if (item != null && item is DataRowView dataRowView)
		{
			currentDataRowView = dataRowView;
			if (!Convert.IsDBNull(dataRowView.Row["Parameter_Object"]))
			{
				ParameterCls parameterCls = dataRowView.Row["Parameter_Object"] as ParameterCls;
				isReadOnly = (bool)dataRowView.Row["IsParamReadOnly"];
				if (parameterCls != null)
				{
					if (IsArrayParameter(parameterCls))
					{
						return InputArrayEditCellDataTemplate;
					}
					if (parameterCls.IsParamDataTable())
					{
						return InputParameterDataTableEditCellDataTemplate;
					}
					if (parameterCls.NoOfElements == 1)
					{
						return CreateDynamicDataTemplateBasedOnDisplayHint(parameterCls);
					}
				}
			}
		}
		return null;
	}

	private DataTemplate CreateDynamicDataTemplateBasedOnDisplayHint(ParameterCls tParam)
	{
		DataTemplate dataTemplate = null;
		string[] hints = tParam.Constraints.Trim().Split(';');
		if ((tParam.DisplayHint & 3) == 3)
		{
			return DefaultCellEditTemplate;
		}
		if ((tParam.DisplayHint & 0x3000) == 12288)
		{
			return ApplyDisplayHint(tParam, GetConstraints(hints, "False;True"), tParam.IsNullable, enumType: true, tParam.DataType);
		}
		if ((tParam.DisplayHint & 2) == 2)
		{
			string defaultConstraints = "False;True";
			if ((tParam.DisplayHint & 0x1000) == 4096)
			{
				defaultConstraints = "No;Yes";
			}
			else if ((tParam.DisplayHint & 0x2000) == 8192)
			{
				defaultConstraints = "Off;On";
			}
			else if ((tParam.DisplayHint & 0x100) == 256)
			{
				defaultConstraints = "No;Yes";
			}
			return ApplyDisplayHint(tParam, GetConstraints(hints, defaultConstraints), tParam.IsNullable, enumType: true, tParam.DataType);
		}
		if ((tParam.DisplayHint & 1) == 1 || (tParam.DisplayHint & 4) == 4)
		{
			return InputParameterFileNameEditCellDataTemplate;
		}
		if ((tParam.DisplayHint & 0x1000) == 4096)
		{
			return ApplyDisplayHint(tParam, GetConstraints(hints, "No;Yes"), tParam.IsNullable, enumType: true, tParam.DataType);
		}
		if ((tParam.DisplayHint & 0x2000) == 8192)
		{
			return ApplyDisplayHint(tParam, GetConstraints(hints, "Off;On"), tParam.IsNullable, enumType: true, tParam.DataType);
		}
		if ((tParam.DisplayHint & 0x100) == 256)
		{
			return ApplyDisplayHint(tParam, tParam.Constraints.Trim(), tParam.IsNullable, enumType: false, tParam.DataType);
		}
		if ((tParam.DisplayHint & 8) == 8)
		{
			return ApplyDisplayHint(tParam, tParam.Constraints.Trim(), tParam.IsNullable, enumType: true, tParam.DataType);
		}
		_ = tParam.DisplayHint;
		if (0 == 0)
		{
			return ApplyDataTypeDisplayHint(tParam, "False;True", tParam.DataType, tParam.IsNullable);
		}
		return dataTemplate;
	}

	private DataTemplate ApplyDataTypeDisplayHint(ParameterCls tParam, string constraints, DataType dType, bool isNullable)
	{
		DataTemplate dataTemplate = null;
		try
		{
			switch (dType)
			{
			case DataType.Boolean:
				dataTemplate = ApplyDisplayHint(tParam, constraints, isNullable, enumType: false, dType);
				break;
			case DataType.String:
				dataTemplate = MultilineStringEditCellDataTemplate;
				break;
			default:
			{
				FrameworkElementFactory frameworkElementFactory = new FrameworkElementFactory(typeof(TextBox));
				Binding binding = new Binding("Value");
				binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
				binding.ValidationRules.Add(new ParameterValueRule
				{
					Parameter = tParam
				});
				frameworkElementFactory.SetBinding(TextBox.TextProperty, binding);
				Style style = new Style(typeof(TextBox));
				Binding binding2 = new Binding("HasGvGetValue");
				Setter item = new Setter(Control.BackgroundProperty, new SolidColorBrush(Colors.Yellow));
				Setter item2 = new Setter(FrameworkElement.ToolTipProperty, "This value will be overwritten by the global variable specified in the GV Get column");
				DataTrigger dataTrigger = new DataTrigger();
				binding2.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
				dataTrigger.Binding = binding2;
				dataTrigger.Value = true;
				dataTrigger.Setters.Add(item);
				dataTrigger.Setters.Add(item2);
				style.Triggers.Add(dataTrigger);
				if (currentDataRowView["HasDifferentValues"].ToString() == bool.TrueString)
				{
					frameworkElementFactory.SetValue(Control.BackgroundProperty, new SolidColorBrush(Colors.LightSteelBlue));
					frameworkElementFactory.SetValue(FrameworkElement.ToolTipProperty, currentDataRowView["DifferentValues"].ToString());
				}
				frameworkElementFactory.SetValue(TextBoxBase.IsReadOnlyProperty, isReadOnly);
				frameworkElementFactory.SetValue(FrameworkElement.StyleProperty, style);
				dataTemplate = new DataTemplate();
				dataTemplate.VisualTree = frameworkElementFactory;
				break;
			}
			}
		}
		catch
		{
		}
		return dataTemplate;
	}

	private bool IsArrayParameter(ParameterCls param)
	{
		if (!param.IsParamDataTable())
		{
			if (param.NoOfElements <= 1)
			{
				return param.IsDynamicArray;
			}
			return true;
		}
		return false;
	}

	private string GetConstraints(string[] hints, string defaultConstraints)
	{
		if (hints.Length > 1)
		{
			return hints[0].Trim() + ";" + hints[1].Trim();
		}
		return defaultConstraints;
	}

	private DataTemplate ApplyDisplayHint(ParameterCls tParam, string constraints, bool isNullable, bool enumType, DataType dType)
	{
		DataTemplate result = null;
		try
		{
			result = ((!isNullable) ? ShowDropDown(tParam, constraints.Trim(), enumType, dType) : ShowDropDown(tParam, constraints.Trim() + ";", enumType, dType));
		}
		catch (Exception ex)
		{
			TraceMessage.Write(ex.Source, "ApplyDisplayHint " + ex.Message, TraceMessageType.Exception);
		}
		return result;
	}

	private DataTemplate ShowDropDown(ParameterCls tParam, string constraints, bool enumType, DataType dType)
	{
		DataTemplate dataTemplate = null;
		string[] array = constraints.Trim().Split(';');
		_ = tParam.Value;
		if (array.Length > 0)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			if (enumType)
			{
				if (ParameterCollection.CreateNameValueList(constraints, out var names, out var values))
				{
					bool flag = QTMUtility.IsAllConstraintsHaveTwoParts(constraints);
					for (int i = 0; i < names.Count; i++)
					{
						int num = (int)values[i];
						string value = (flag ? $"{values[i].ToString()}  {names[i].ToString()}" : names[i].ToString());
						if (!dictionary.ContainsKey(num.ToString()))
						{
							dictionary.Add(num.ToString(), value);
						}
					}
				}
			}
			else
			{
				for (int j = 0; j < array.Length; j++)
				{
					if (!dictionary.ContainsKey(array[j].Trim()))
					{
						dictionary.Add(array[j].Trim(), array[j].Trim());
					}
				}
			}
			FrameworkElementFactory frameworkElementFactory = new FrameworkElementFactory(typeof(ComboBox));
			Binding binding = new Binding();
			binding.Source = dictionary;
			frameworkElementFactory.SetBinding(ItemsControl.ItemsSourceProperty, binding);
			frameworkElementFactory.SetValue(Selector.SelectedValuePathProperty, "Key");
			frameworkElementFactory.SetValue(ItemsControl.DisplayMemberPathProperty, "Value");
			Binding binding2 = new Binding("Value");
			binding2.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
			frameworkElementFactory.SetBinding(Selector.SelectedValueProperty, binding2);
			if (currentDataRowView["HasDifferentValues"].ToString() == bool.TrueString)
			{
				frameworkElementFactory.SetValue(Control.BackgroundProperty, new SolidColorBrush(Colors.LightSteelBlue));
				frameworkElementFactory.SetValue(FrameworkElement.ToolTipProperty, currentDataRowView["DifferentValues"].ToString());
			}
			frameworkElementFactory.SetValue(UIElement.IsEnabledProperty, !isReadOnly);
			dataTemplate = new DataTemplate();
			dataTemplate.VisualTree = frameworkElementFactory;
		}
		return dataTemplate;
	}
}
