using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Xml.Serialization;
using QC.QsprTestObjects.Tests.Base;
using QC.QTMInterface;

namespace QC.QsprTestObjects.Registry;

[Serializable]
public abstract class QTMTarget : INotifyPropertyChanged
{
	public const string THISPC = "This PC";

	protected string targetName;

	protected Hashtable hashContainers = new Hashtable();

	protected ObservableCollection<QTMTestContainer> arrayContainers = new ObservableCollection<QTMTestContainer>();

	protected bool expanded = true;

	private bool isSelected;

	[XmlIgnore]
	private string key;

	[XmlIgnore]
	public QTMRegistry theRegistry;

	public string Name
	{
		get
		{
			return targetName;
		}
		set
		{
			targetName = value;
		}
	}

	[XmlIgnore]
	public bool IsSelected
	{
		get
		{
			return isSelected;
		}
		set
		{
			isSelected = value;
			RaiseOnPropertyChanged("IsSelected");
		}
	}

	[XmlIgnore]
	public Hashtable HashContainers
	{
		get
		{
			return hashContainers;
		}
		set
		{
			hashContainers = value;
		}
	}

	[XmlElement(Type = typeof(QTMTestContainer))]
	public ObservableCollection<QTMTestContainer> TestContainers
	{
		get
		{
			return arrayContainers;
		}
		set
		{
			arrayContainers = value;
		}
	}

	[XmlIgnore]
	public virtual bool Connected
	{
		get
		{
			return true;
		}
		set
		{
		}
	}

	public bool Expanded
	{
		get
		{
			return expanded;
		}
		set
		{
			expanded = value;
			RaiseOnPropertyChanged("Expanded");
		}
	}

	public string Key
	{
		get
		{
			return key;
		}
		set
		{
			key = value;
		}
	}

	[XmlIgnore]
	public MessageDelegate QTMMessageDelegate => theRegistry.scheduler.msgDelegate;

	public abstract QTMTargetType TargetType { get; }

	[field: XmlIgnore]
	public event PropertyChangedEventHandler PropertyChanged;

	public QTMTarget()
	{
	}

	public QTMTarget(string name)
	{
		targetName = name;
	}

	public bool AddTestContainer(string containerName, QC.QsprTestObjects.Tests.Base.QTMTestTypes containerType)
	{
		if (!hashContainers.Contains(containerName))
		{
			QTMTestContainer testContainer = new QTMTestContainer(containerName, containerType, Name, TargetType);
			AddContainer(testContainer);
			return true;
		}
		return false;
	}

	public void AddContainer(QTMTestContainer testContainer)
	{
		hashContainers.Add(testContainer.OriginalName.Trim(), testContainer);
		arrayContainers.Add(testContainer);
		testContainer.theRegistry = theRegistry;
	}

	public bool DeleteTestContainer(string containerName)
	{
		if (hashContainers.Contains(containerName))
		{
			QTMTestContainer testContainer = (QTMTestContainer)hashContainers[containerName];
			DeleteContainer(testContainer, containerName);
			return true;
		}
		return false;
	}

	protected void DeleteContainer(QTMTestContainer testContainer, string containerName)
	{
		hashContainers.Remove(containerName);
		arrayContainers.Remove(testContainer);
	}

	public QTMTestContainer GetContainer(string containerName)
	{
		try
		{
			if (hashContainers.Contains(containerName))
			{
				return (QTMTestContainer)hashContainers[containerName];
			}
		}
		catch
		{
		}
		return null;
	}

	public bool RenameContainer(string oldFullPath, string newFullPath)
	{
		try
		{
			QTMTestContainer container = GetContainer(oldFullPath);
			if (container != null)
			{
				DeleteContainer(container, container.Name);
				container.Name = newFullPath;
				container.IsDllPathUpdated = false;
				container.UpdatedDllPathName = "";
				foreach (QTMTest value in container.HashTests.Values)
				{
					value.ContainerName = newFullPath;
				}
				AddContainer(container);
				return true;
			}
		}
		catch
		{
		}
		return false;
	}

	public void UpdateContainerWithNewPath(string oldPath, string updatedDllPath, QTMTestContainer testContainer)
	{
		if (hashContainers.ContainsKey(oldPath))
		{
			hashContainers.Remove(oldPath);
			hashContainers.Add(updatedDllPath, testContainer);
		}
	}

	public void CreateHashtable()
	{
		hashContainers = new Hashtable();
		foreach (QTMTestContainer arrayContainer in arrayContainers)
		{
			arrayContainer.theRegistry = theRegistry;
			hashContainers[arrayContainer.Name] = arrayContainer;
			arrayContainer.CreateHashtable();
		}
	}

	public abstract void RunTest(BaseTest sender, string containerName, ref object objParams, ref object objProperties);

	public abstract void GetResultsParamInfo(BaseTest sender, ref object obj);

	public abstract bool LoadContainer(QTMTestContainer testContainer, ref string listOfTests);

	public abstract void UnloadContainer(QC.QsprTestObjects.Tests.Base.QTMTestTypes sender, string name);

	public abstract void GetAllParamInfo(BaseTest sender, string realName, string containerName, ref object obj);

	public abstract void StopTest(BaseTest sender);

	public abstract void OnTestMessage(TestMsgType msgType, string testFullPath, TestResult result);

	public abstract void SetGlobalVariable(string Name, string Value);

	public abstract void SetGlobalVariable(string Name, int Value);

	public abstract void SetGlobalVariable(string Name, object Value);

	public abstract bool MenuMessages(string message);

	public virtual bool Connect()
	{
		return true;
	}

	public virtual bool AddDll(out string[] dllName)
	{
		dllName = null;
		return false;
	}

	public virtual bool AddScript(out string[] scripts)
	{
		scripts = null;
		return false;
	}

	public virtual bool GetContainerNames(QC.QsprTestObjects.Tests.Base.QTMTestTypes testType, out string[] containerNames)
	{
		containerNames = null;
		return false;
	}

	public virtual void CloseKernels()
	{
	}

	protected void RaiseOnPropertyChanged(string propertyName)
	{
		if (this.PropertyChanged != null)
		{
			this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
		}
	}
}
