using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using QC.QsprTestObjects.Tests.Base;

namespace QC.QTMApplication;

public class TestTreeSelectionManager
{
	protected BaseTest lastSelectedTest;

	private TreeTraversalDirection lastTreeTraversalDirection;

	public RootTest Root { get; protected set; }

	public ObservableCollection<BaseTest> SelectedTests { get; protected set; }

	public TreeView TreeView { get; protected set; }

	public BaseTest LastSelectedTest => lastSelectedTest;

	public TreeTraversalDirection LastTreeTraversalDirection
	{
		get
		{
			return lastTreeTraversalDirection;
		}
		set
		{
			lastTreeTraversalDirection = value;
		}
	}

	public event RoutedPropertyChangedEventHandler<BaseTest> FirstSelectedTestChanged;

	public TestTreeSelectionManager(RootTest root, TreeView treeView)
	{
		Root = root;
		TreeView = treeView;
		SelectedTests = new ObservableCollection<BaseTest>();
		SelectedTests.CollectionChanged += SelectedTests_CollectionChanged;
		LastTreeTraversalDirection = TreeTraversalDirection.None;
	}

	private void SelectedTests_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
	{
		if (e.Action == NotifyCollectionChangedAction.Add)
		{
			foreach (BaseTest newItem in e.NewItems)
			{
				newItem.Properties.IsSelected = true;
				lastSelectedTest = newItem;
			}
			return;
		}
		if (e.Action == NotifyCollectionChangedAction.Remove)
		{
			foreach (BaseTest oldItem in e.OldItems)
			{
				oldItem.Properties.IsSelected = false;
				lastSelectedTest = SelectedTests.LastOrDefault();
			}
			return;
		}
		if (e.Action != NotifyCollectionChangedAction.Replace)
		{
			return;
		}
		foreach (BaseTest newItem2 in e.NewItems)
		{
			newItem2.Properties.IsSelected = true;
			lastSelectedTest = newItem2;
		}
		foreach (BaseTest oldItem2 in e.OldItems)
		{
			oldItem2.Properties.IsSelected = false;
		}
	}

	public void ClearSelections()
	{
		List<BaseTest> list = SelectedTests.ToList();
		foreach (BaseTest item in list)
		{
			SelectedTests.Remove(item);
		}
		lastSelectedTest = null;
	}

	public void SelectTest(BaseTest baseTest, bool shiftPressed = false, bool ctrlPressed = false)
	{
		TreeViewItem treeViewItem = (TreeViewItem)TreeView.ItemContainerGenerator.ContainerFromItem(baseTest);
		if (treeViewItem != null)
		{
			Keyboard.Focus(treeViewItem);
		}
		TreeTraversalDirection relativeDirection = GetRelativeDirection(lastSelectedTest, baseTest);
		if (shiftPressed && SelectedTests.Count > 0)
		{
			if (lastSelectedTest != baseTest)
			{
				switch (relativeDirection)
				{
				case TreeTraversalDirection.Down:
				{
					BaseTest baseTest3 = ((LastTreeTraversalDirection != TreeTraversalDirection.Up) ? TestTreeBrowser.GetNextTest(LastSelectedTest) : LastSelectedTest);
					while (baseTest3 != null && baseTest3 != baseTest)
					{
						if (SelectedTests.Contains(baseTest3))
						{
							if (SelectedTests.Count > 1)
							{
								SelectedTests.Remove(baseTest3);
							}
						}
						else
						{
							SelectedTests.Add(baseTest3);
						}
						baseTest3 = TestTreeBrowser.GetNextTest(baseTest3);
					}
					if (baseTest3 != null && !SelectedTests.Contains(baseTest3))
					{
						SelectedTests.Add(baseTest3);
					}
					break;
				}
				case TreeTraversalDirection.Up:
				{
					BaseTest baseTest2 = ((LastTreeTraversalDirection != TreeTraversalDirection.Down) ? TestTreeBrowser.GetPreviousTest(LastSelectedTest) : LastSelectedTest);
					while (baseTest2 != null && baseTest2 != baseTest)
					{
						if (SelectedTests.Contains(baseTest2))
						{
							if (SelectedTests.Count > 1)
							{
								SelectedTests.Remove(baseTest2);
							}
						}
						else
						{
							SelectedTests.Add(baseTest2);
						}
						baseTest2 = TestTreeBrowser.GetPreviousTest(baseTest2);
					}
					if (baseTest2 != null && !SelectedTests.Contains(baseTest2))
					{
						SelectedTests.Add(baseTest2);
					}
					break;
				}
				}
			}
			else
			{
				SelectTest(baseTest);
			}
		}
		else if (ctrlPressed && SelectedTests.Count > 0)
		{
			if (SelectedTests.Contains(baseTest))
			{
				SelectedTests.Remove(baseTest);
			}
			else
			{
				SelectedTests.Add(baseTest);
			}
		}
		else
		{
			if (SelectedTests.Count == 1 && SelectedTests.Contains(baseTest))
			{
				return;
			}
			if (SelectedTests.Count <= 1 || !SelectedTests.Contains(baseTest))
			{
				BaseTest oldValue = SelectedTests.FirstOrDefault();
				List<BaseTest> list = SelectedTests.ToList();
				foreach (BaseTest item in list)
				{
					SelectedTests.Remove(item);
				}
				SelectedTests.Add(baseTest);
				if (this.FirstSelectedTestChanged != null)
				{
					this.FirstSelectedTestChanged(this, new RoutedPropertyChangedEventArgs<BaseTest>(oldValue, baseTest));
				}
			}
		}
		LastTreeTraversalDirection = relativeDirection;
	}

	public TreeTraversalDirection GetRelativeDirection(BaseTest startTest, BaseTest endTest)
	{
		TreeTraversalDirection result = TreeTraversalDirection.None;
		if (startTest != endTest)
		{
			if (startTest is RootTest)
			{
				result = TreeTraversalDirection.Down;
			}
			else if (endTest is RootTest)
			{
				result = TreeTraversalDirection.Up;
			}
			else if (startTest != null && endTest != null)
			{
				string uniqueTestPath = startTest.UniqueTestPath;
				string[] array = uniqueTestPath.Split(new string[1] { "|" }, StringSplitOptions.None);
				string uniqueTestPath2 = endTest.UniqueTestPath;
				string[] array2 = uniqueTestPath2.Split(new string[1] { "|" }, StringSplitOptions.None);
				if (uniqueTestPath.Length > uniqueTestPath2.Length && uniqueTestPath.Contains(uniqueTestPath2))
				{
					result = TreeTraversalDirection.Up;
				}
				else if (uniqueTestPath.Length < uniqueTestPath2.Length && uniqueTestPath2.Contains(uniqueTestPath))
				{
					result = TreeTraversalDirection.Down;
				}
				else
				{
					int num = ((array.Length <= array2.Length) ? array.Length : array2.Length);
					for (int i = 0; i < num; i++)
					{
						if (!(array[i] != array2[i]))
						{
							continue;
						}
						int result2 = -1;
						bool flag = int.TryParse(array[i], out result2);
						int result3 = -1;
						bool flag2 = int.TryParse(array2[i], out result3);
						if (flag == flag2)
						{
							if (flag)
							{
								if (result2 > result3)
								{
									result = TreeTraversalDirection.Up;
								}
								else if (result2 < result3)
								{
									result = TreeTraversalDirection.Down;
								}
							}
							else
							{
								flag = int.TryParse(array[i + 1], out result2);
								flag2 = int.TryParse(array2[i + 1], out result3);
								if (flag == flag2 && flag)
								{
									if (result2 > result3)
									{
										result = TreeTraversalDirection.Up;
									}
									else if (result2 < result3)
									{
										result = TreeTraversalDirection.Down;
									}
								}
							}
						}
						i = num;
					}
				}
			}
		}
		return result;
	}
}
