Decompiled source of Fireman v0.1.0

plugins/Fireman.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using Fireman.Core;
using Fireman.Core.SortStrategies;
using Fireman.Interface;
using Fireman.Interface.GlobalControls;
using Fireman.Interface.Reusables;
using Fireman.Interface.Views;
using Fireman.Platform;
using Microsoft.CodeAnalysis;
using Notiffy.API;
using NukeLib.UI;
using NukeLib.Utils;
using TMPro;
using ThornClient.Core;
using ThornClient.Core.ConfigurableElements;
using ThornClient.Core.DataTypes;
using ThornClient.Managers;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Fireman")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3e0ba5db7e0e1f5717d9093a585399be03abd4c0")]
[assembly: AssemblyProduct("Fireman")]
[assembly: AssemblyTitle("Fireman")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Fireman
{
	[BepInPlugin("com.github.end-4.fireman", "Fireman", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		public static string workingPath = Assembly.GetExecutingAssembly().Location;

		public static string workingDir = Path.GetDirectoryName(workingPath);

		public const string PluginGUID = "com.github.end-4.fireman";

		public const string PluginName = "Fireman";

		public const string PluginVersion = "0.1.0";

		public const string BundleKey = "fireman.main";

		private static readonly string BundlePath = Path.Combine(workingDir, "assets", "fireman.bundle");

		public static string PluginIconPath => Path.Combine(workingDir, "icon.png");

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			AssetManager.LoadBundle("fireman.main", BundlePath);
		}
	}
}
namespace Fireman.Platform
{
	public static class FileIcons
	{
		public const string BundleKey = "fireman.icons";

		private static readonly string BundlePath;

		private static readonly Dictionary<string, string> FolderMap;

		private static readonly Dictionary<string[], string> FileExtMap;

		static FileIcons()
		{
			BundlePath = Path.Combine(Plugin.workingDir, "assets", "fireman_fileicons.bundle");
			FolderMap = new Dictionary<string, string>
			{
				{
					Paths.Game,
					"folder_game"
				},
				{
					Paths.BepInEx,
					"folder_bepinex"
				},
				{
					Paths.Cybergrind,
					"folder_cybergrind"
				},
				{
					Paths.Home,
					"folder_home"
				},
				{
					Paths.Downloads,
					"folder_downloads"
				},
				{
					Paths.Documents,
					"folder_documents"
				},
				{
					Paths.Images,
					"folder_images"
				},
				{
					Paths.Music,
					"folder_music"
				},
				{
					Paths.Videos,
					"folder_videos"
				},
				{
					Paths.AngryLevels,
					"folder_angry"
				},
				{
					Paths.ThornConfig,
					"folder_thorn"
				}
			};
			FileExtMap = new Dictionary<string[], string>
			{
				{
					new string[8] { ".txt", ".docx", ".doc", ".pdf", ".rtf", ".odt", ".tex", ".log" },
					"file_text"
				},
				{
					new string[13]
					{
						".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".bmp", ".tiff", ".tif", ".ico",
						".heic", ".psd", ".jxl"
					},
					"file_image"
				},
				{
					new string[6] { ".mp3", ".wav", ".aac", ".flac", ".ogg", ".m4a" },
					"file_music"
				},
				{
					new string[8] { ".mp4", ".mov", ".avi", ".mkv", ".wmv", ".webm", ".m4v", ".mpeg" },
					"file_video"
				},
				{
					new string[7] { ".zip", ".rar", ".7z", ".tar", ".gz", ".bz2", ".xz" },
					"file_zip"
				},
				{
					new string[11]
					{
						".exe", ".msi", ".apk", ".app", ".dmg", ".ps1", ".sh", ".bash", ".zsh", ".fish",
						"makefile"
					},
					"file_executable"
				},
				{
					new string[1] { ".dll" },
					"file_lib"
				},
				{
					new string[4] { ".json", ".cfg", ".ini", ".toml" },
					"file_config"
				},
				{
					new string[1] { ".cgp" },
					"file_cgp"
				},
				{
					new string[1] { ".cgvsb" },
					"file_skybox"
				},
				{
					new string[1] { ".angry" },
					"file_angry"
				}
			};
			AssetManager.LoadBundle("fireman.icons", BundlePath);
		}

		public static Sprite? GetFileIcon(FileSystemInfo fileInfo)
		{
			string text = "file";
			if (fileInfo is DirectoryInfo)
			{
				text = "folder";
				if (FolderMap.TryGetValue(fileInfo.FullName, out string value))
				{
					text = value;
				}
			}
			else
			{
				text = "file";
				foreach (KeyValuePair<string[], string> item in FileExtMap)
				{
					if (item.Key.Any((string ext) => fileInfo.Name.EndsWith(ext)))
					{
						text = item.Value;
						break;
					}
				}
			}
			return AssetManager.Get<Sprite>("fireman.icons", text);
		}

		public static Sprite? GetSymbolicFolderIcon(DirectoryInfo dirInfo)
		{
			string text = "";
			if (dirInfo.Parent == null)
			{
				text = "hard_disk_symbolic";
			}
			else if (dirInfo.FullName == Paths.Game)
			{
				text = "game_symbolic";
			}
			else if (dirInfo.FullName == Paths.BepInEx)
			{
				text = "bepinex_symbolic";
			}
			else if (dirInfo.FullName == Paths.Cybergrind)
			{
				text = "cybergrind_symbolic";
			}
			else if (dirInfo.FullName == Paths.Home)
			{
				text = "home_symbolic";
			}
			else if (dirInfo.FullName == Paths.Downloads)
			{
				text = "downloads_symbolic";
			}
			else if (dirInfo.FullName == Paths.Documents)
			{
				text = "documents_symbolic";
			}
			else if (dirInfo.FullName == Paths.Images)
			{
				text = "images_symbolic";
			}
			else if (dirInfo.FullName == Paths.Music)
			{
				text = "music_symbolic";
			}
			else if (dirInfo.FullName == Paths.Videos)
			{
				text = "videos_symbolic";
			}
			else if (dirInfo.FullName == Paths.AngryLevels)
			{
				text = "angry_symbolic";
			}
			else if (dirInfo.FullName == Paths.ThornConfig)
			{
				text = "thorn_symbolic";
			}
			if (text != "")
			{
				return AssetManager.Get<Sprite>("fireman.icons", text);
			}
			return null;
		}
	}
	public static class Paths
	{
		public static readonly DirectoryInfo GameInfo = new DirectoryInfo(Paths.GameRootPath);

		public static readonly DirectoryInfo BepInExInfo = new DirectoryInfo(Paths.BepInExRootPath);

		public static readonly DirectoryInfo CybergrindInfo = new DirectoryInfo(Path.Combine(GameInfo.FullName, "Cybergrind"));

		public static readonly DirectoryInfo HomeInfo = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));

		public static readonly DirectoryInfo DownloadsInfo = new DirectoryInfo(Path.Combine(HomeInfo.FullName, "Downloads"));

		public static readonly DirectoryInfo DocumentsInfo = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Personal));

		public static readonly DirectoryInfo ImagesInfo = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures));

		public static readonly DirectoryInfo MusicInfo = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.MyMusic));

		public static readonly DirectoryInfo VideosInfo = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.MyVideos));

		public static readonly DirectoryInfo AngryLevelsInfo = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AngryLevelLoader"));

		public static readonly DirectoryInfo ThornConfigInfo = new DirectoryInfo(Path.Combine(BepInExInfo.FullName, "config", "ThornClient"));

		public static string Game => GameInfo.FullName;

		public static string BepInEx => BepInExInfo.FullName;

		public static string Cybergrind => CybergrindInfo.FullName;

		public static string Home => HomeInfo.FullName;

		public static string Downloads => DownloadsInfo.FullName;

		public static string Documents => DocumentsInfo.FullName;

		public static string Images => ImagesInfo.FullName;

		public static string Music => MusicInfo.FullName;

		public static string Videos => VideosInfo.FullName;

		public static string AngryLevels => AngryLevelsInfo.FullName;

		public static string ThornConfig => ThornConfigInfo.FullName;
	}
}
namespace Fireman.Interface
{
	public class Config : Module
	{
		public static Setting<Keybind> ToggleFileManager;

		public static Setting<Keybind> NewTabBind;

		public static Setting<Keybind> CloseTabBind;

		public static Setting<Keybind> BackBind;

		public static Setting<Keybind> BackBindAlt;

		public static Setting<Keybind> ForwardBind;

		public static Setting<Keybind> ForwardBindAlt;

		public static Setting<Keybind> ParentDirBind;

		public static Setting<Keybind> LeftTabBind;

		public static Setting<Keybind> LeftTabBindAlt;

		public static Setting<Keybind> RightTabBind;

		public static Setting<Keybind> RightTabBindAlt;

		public static Setting<Keybind> CopyBind;

		public static Setting<Keybind> CopyBindAlt;

		public static Setting<Keybind> CutBind;

		public static Setting<Keybind> CutBindAlt;

		public static Setting<Keybind> PasteBind;

		public static Setting<Keybind> PasteBindAlt;

		public static Setting<Keybind> PermaDeleteBind;

		public static Setting<Keybind> PermaDeleteBindAlt;

		public static Setting<Keybind> FocusAddressBarBind;

		public static Setting<Keybind> FocusAddressBarBindAlt;

		public static Setting<bool> SortFoldersBeforeFiles;

		public static Setting<Keybind> DebugPicker;

		public static Setting<Keybind> DebugPickerMulti;

		public static Setting<Keybind> DebugPickerFolders;

		public static Setting<Keybind> DebugPickerFoldersMulti;

		public static Setting<string> LastVersion;

		private static FileManager? _fm;

		public override Sprite Icon => FileAssetUtils.LoadNewSprite(Path.Combine(Plugin.workingDir, "icon_clickgui.png"), 100f, (SpriteMeshType)1);

		public Config()
			: base("fireman.config", "Fireman", "File manager for ULTRAKILL", (ModuleCategory)3, (KeyCode)0, (KeyCode)0, false, false)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Expected O, but got Unknown
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Expected O, but got Unknown
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Expected O, but got Unknown
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Expected O, but got Unknown
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Expected O, but got Unknown
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Expected O, but got Unknown
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Expected O, but got Unknown
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Expected O, but got Unknown
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Expected O, but got Unknown
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Expected O, but got Unknown
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Expected O, but got Unknown
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Expected O, but got Unknown
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Expected O, but got Unknown
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Expected O, but got Unknown
			//IL_0410: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Expected O, but got Unknown
			//IL_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Expected O, but got Unknown
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Expected O, but got Unknown
			ToggleFileManager = ((Configurable)this).CreateSetting<Keybind>("toggleManager", "Toggle file manager", "Keybind to toggle the file manager overlay", new Keybind((KeyCode)101, (KeyCode)308), (SettingGroup)null);
			ToggleFileManager.OnPress += ToggleOverlay;
			SettingGroup val = ((Configurable)this).CreateGroup("moreBinds", "More keybinds", "Other keybinds", (SettingGroup)null);
			NewTabBind = ((Configurable)this).CreateSetting<Keybind>("newTab", "New tab", "Keybind to open a new tab", new Keybind((KeyCode)116, (KeyCode)306), val);
			CloseTabBind = ((Configurable)this).CreateSetting<Keybind>("closeTab", "Close tab", "Keybind to close current tab", new Keybind((KeyCode)119, (KeyCode)306), val);
			BackBind = ((Configurable)this).CreateSetting<Keybind>("back", "Back", "Keybind to navigate back in history", new Keybind((KeyCode)276, (KeyCode)308), val);
			BackBindAlt = ((Configurable)this).CreateSetting<Keybind>("backAlt", "Back (alternative)", "Keybind to navigate back in history", new Keybind((KeyCode)326, (KeyCode)0), val);
			ForwardBind = ((Configurable)this).CreateSetting<Keybind>("forward", "Forward", "Keybind to navigate forward in history", new Keybind((KeyCode)275, (KeyCode)308), val);
			ForwardBindAlt = ((Configurable)this).CreateSetting<Keybind>("forwardAlt", "Forward (alternative)", "Keybind to navigate forward in history", new Keybind((KeyCode)327, (KeyCode)0), val);
			ParentDirBind = ((Configurable)this).CreateSetting<Keybind>("parentDir", "To parent directory", "Keybind to navigate to parent directory", new Keybind((KeyCode)273, (KeyCode)308), val);
			LeftTabBind = ((Configurable)this).CreateSetting<Keybind>("leftTab", "Left tab", "Keybind to switch to the tab on the left", new Keybind((KeyCode)280, (KeyCode)306), val);
			LeftTabBindAlt = ((Configurable)this).CreateSetting<Keybind>("leftTabAlt", "Left tab (alternative)", "Keybind to switch to the tab on the left", new Keybind((KeyCode)0, (KeyCode)0), val);
			RightTabBind = ((Configurable)this).CreateSetting<Keybind>("rightTab", "Right tab", "Keybind to switch to the tab on the right", new Keybind((KeyCode)281, (KeyCode)306), val);
			RightTabBindAlt = ((Configurable)this).CreateSetting<Keybind>("rightTabAlt", "Right tab (alternative)", "Keybind to switch to the tab on the right", new Keybind((KeyCode)9, (KeyCode)306), val);
			CopyBind = ((Configurable)this).CreateSetting<Keybind>("copy", "Copy", "Keybind to copy items", new Keybind((KeyCode)99, (KeyCode)306), val);
			CopyBindAlt = ((Configurable)this).CreateSetting<Keybind>("copyAlt", "Copy (alternative)", "Keybind to copy items", new Keybind((KeyCode)99, (KeyCode)305), val);
			CutBind = ((Configurable)this).CreateSetting<Keybind>("cut", "Cut", "Keybind to cut items", new Keybind((KeyCode)120, (KeyCode)306), val);
			CutBindAlt = ((Configurable)this).CreateSetting<Keybind>("cutAlt", "Cut (alternative)", "Keybind to cut items", new Keybind((KeyCode)120, (KeyCode)305), val);
			PasteBind = ((Configurable)this).CreateSetting<Keybind>("paste", "Paste", "Keybind to paste items", new Keybind((KeyCode)118, (KeyCode)306), val);
			PasteBindAlt = ((Configurable)this).CreateSetting<Keybind>("pasteAlt", "Paste (alternative)", "Keybind to paste items", new Keybind((KeyCode)118, (KeyCode)305), val);
			PermaDeleteBind = ((Configurable)this).CreateSetting<Keybind>("permaDelete", "Delete permanently", "Keybind to permanently delete items", new Keybind((KeyCode)127, (KeyCode)304), val);
			PermaDeleteBindAlt = ((Configurable)this).CreateSetting<Keybind>("permaDeleteAlt", "Delete permanently (alternative)", "Keybind to permanently delete items", new Keybind((KeyCode)127, (KeyCode)303), val);
			FocusAddressBarBind = ((Configurable)this).CreateSetting<Keybind>("focusAddressBar", "Focus address bar", "Keybind to focus the address bar", new Keybind((KeyCode)108, (KeyCode)306), val);
			FocusAddressBarBindAlt = ((Configurable)this).CreateSetting<Keybind>("focusAddressBarAlt", "Focus address bar (alternative)", "Keybind to focus the address bar", new Keybind((KeyCode)108, (KeyCode)305), val);
			SortFoldersBeforeFiles = ((Configurable)this).CreateSetting<bool>("sortFoldersBeforeFiles", "Sort folders before files", "Folders on top, then goes files", true, (SettingGroup)null);
			SettingGroup val2 = ((Configurable)this).CreateGroup("debug", "Debug", "Debug options", (SettingGroup)null);
			DebugPicker = ((Configurable)this).CreateSetting<Keybind>("debugPicker", "File picker", "Activates a file picker", new Keybind((KeyCode)0, (KeyCode)0), val2);
			DebugPickerMulti = ((Configurable)this).CreateSetting<Keybind>("debugPickerMulti", "File picker (multi)", "Activates a multi-select picker", new Keybind((KeyCode)0, (KeyCode)0), val2);
			DebugPickerFolders = ((Configurable)this).CreateSetting<Keybind>("debugPickerFolders", "Folder picker", "Activates a folder picker", new Keybind((KeyCode)0, (KeyCode)0), val2);
			DebugPickerFoldersMulti = ((Configurable)this).CreateSetting<Keybind>("debugPickerFoldersMulti", "Folder picker (multi)", "Activates a multi-select folder picker", new Keybind((KeyCode)0, (KeyCode)0), val2);
			LastVersion = ((Configurable)this).CreateSetting<string>("lastVersion", "Last version", "Last loaded version", "0.0.0", val2);
			DebugPicker.OnPress += delegate
			{
				DebugPick(multi: false, folders: false);
			};
			DebugPickerMulti.OnPress += delegate
			{
				DebugPick(multi: true, folders: false);
			};
			DebugPickerFolders.OnPress += delegate
			{
				DebugPick(multi: false, folders: true);
			};
			DebugPickerFoldersMulti.OnPress += delegate
			{
				DebugPick(multi: true, folders: true);
			};
			SceneUtils.SafeSceneLoadedNoParam += SendStartupNotifications;
		}

		private void DebugPick(bool multi, bool folders)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			bool allowMultiSelection = multi;
			FileManager fileManager = FileManager.CreatePicker(null, folders, allowMultiSelection);
			GameObject gameObject = ((Component)fileManager).gameObject;
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject val = ((IEnumerable<GameObject>)((Scene)(ref activeScene)).GetRootGameObjects()).FirstOrDefault((Func<GameObject, bool>)((GameObject obj) => ((Object)obj).name == "Canvas"));
			if (!((Object)(object)val == (Object)null) && !((Object)(object)gameObject == (Object)null))
			{
				gameObject.transform.SetParent(val.transform, false);
				fileManager.ItemsPicked += delegate(string[] pathArr)
				{
					NotificationSystem.NotifySend("Fireman::<color=#a5f2e2>Debug</color>", "PATHS PICKED\n" + DebugUtils.Stringify<string>(pathArr, ", ", "[", "]"), (Sprite)null, "", (Urgency)1, "NotifySend", 0u, (Dictionary<string, string>)null, -1);
				};
			}
		}

		private void ToggleOverlay()
		{
			if (SceneUtils.IsSafe())
			{
				InitializeIfNeeded();
				FileManager? fm = _fm;
				GameObject val = ((fm != null) ? ((Component)fm).gameObject : null);
				if ((Object)(object)val != (Object)null)
				{
					val.SetActive(!val.activeSelf);
				}
				if (val != null)
				{
					val.transform.SetAsLastSibling();
				}
			}
		}

		private static void InitializeIfNeeded()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_fm != (Object)null))
			{
				Scene activeScene = SceneManager.GetActiveScene();
				GameObject val = ((IEnumerable<GameObject>)((Scene)(ref activeScene)).GetRootGameObjects()).FirstOrDefault((Func<GameObject, bool>)((GameObject obj) => ((Object)obj).name == "Canvas"));
				if (!((Object)(object)val == (Object)null))
				{
					_fm = FileManager.CreateManager();
					((Component)_fm).transform.SetParent(val.transform, false);
					((Object)_fm).hideFlags = (HideFlags)61;
					((Component)_fm).gameObject.SetActive(false);
				}
			}
		}

		private void SendStartupNotifications()
		{
			if (LastVersion.Value == "0.0.0")
			{
				NotificationSystem.NotifySend("Fireman::<color=#e09330>Hello</color>", "Press " + ToggleFileManager.Value.ToString(true) + " to toggle the file manager", (Sprite)null, Plugin.PluginIconPath, (Urgency)1, "NotifySend", 0u, (Dictionary<string, string>)null, -1);
			}
			LastVersion.Value = "0.1.0";
		}
	}
	public class FileManager : MonoBehaviour
	{
		private static readonly string DefaultPath = Paths.GameInfo.FullName;

		private Window WindowInstance;

		private bool _pickerMode;

		private bool _allowMultiSelection = true;

		private bool _isSelectionFolder;

		public IReadOnlyList<Tab> Tabs => WindowInstance.Tabs;

		public Tab CurrentTab => WindowInstance.CurrentTab;

		public string CurrentPath
		{
			get
			{
				return WindowInstance.CurrentPath;
			}
			set
			{
				WindowInstance.CurrentPath = value;
			}
		}

		public event Action<string[]>? ItemsPicked;

		private void Start()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			WindowInstance = new Window(DefaultPath, _pickerMode, _allowMultiSelection, _isSelectionFolder);
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Titlebar");
			if (obj != null)
			{
				obj.AddComponent<TitlebarDragHandler>();
			}
			GameObject obj2 = UIUtils.FindRecursive(((Component)this).gameObject, "Titlebar/Close");
			if (obj2 != null)
			{
				((UnityEvent)obj2.GetComponent<Button>().onClick).AddListener(new UnityAction(Close));
			}
			GameObject obj3 = UIUtils.FindRecursive(((Component)this).gameObject, "Titlebar/TabScrollView/Viewport/Row");
			TabRowController tabRowController = ((obj3 != null) ? obj3.AddComponent<TabRowController>() : null);
			if ((Object)(object)tabRowController != (Object)null)
			{
				tabRowController.TargetWindow = WindowInstance;
			}
			ResizeController obj4 = ((Component)this).gameObject.AddComponent<ResizeController>();
			obj4.minWidth = 300f;
			obj4.minHeight = 200f;
			GameObject obj5 = UIUtils.FindRecursive(((Component)this).gameObject, "Content/TopBar");
			GameObject obj6 = ((obj5 != null) ? UIUtils.FindRecursive(obj5, "Navi/Back") : null);
			BackButtonController backButtonController = ((obj6 != null) ? obj6.AddComponent<BackButtonController>() : null);
			if ((Object)(object)backButtonController != (Object)null)
			{
				backButtonController.TargetWindow = WindowInstance;
			}
			GameObject obj7 = ((obj5 != null) ? UIUtils.FindRecursive(obj5, "Navi/Forward") : null);
			ForwardButtonController forwardButtonController = ((obj7 != null) ? obj7.AddComponent<ForwardButtonController>() : null);
			if ((Object)(object)forwardButtonController != (Object)null)
			{
				forwardButtonController.TargetWindow = WindowInstance;
			}
			GameObject obj8 = ((obj5 != null) ? UIUtils.FindRecursive(obj5, "Navi/Up") : null);
			UpButtonController upButtonController = ((obj8 != null) ? obj8.AddComponent<UpButtonController>() : null);
			if ((Object)(object)upButtonController != (Object)null)
			{
				upButtonController.TargetWindow = WindowInstance;
			}
			GameObject obj9 = ((obj5 != null) ? UIUtils.FindRecursive(obj5, "Address") : null);
			AddressController addressController = ((obj9 != null) ? obj9.AddComponent<AddressController>() : null);
			if ((Object)(object)addressController != (Object)null)
			{
				addressController.TargetWindow = WindowInstance;
			}
			object obj10;
			if (obj5 == null)
			{
				obj10 = null;
			}
			else
			{
				GameObject obj11 = UIUtils.FindRecursive(obj5, "Settings");
				obj10 = ((obj11 != null) ? obj11.GetComponent<Button>() : null);
			}
			if (obj10 != null)
			{
				((Component)obj10).gameObject.SetActive(false);
			}
			GameObject gameObject = ((Component)this).gameObject;
			GameObject obj12 = ((gameObject != null) ? UIUtils.FindRecursive(gameObject, "Content/Body/Bookmarks/Container/ScrollView/Viewport/Content") : null);
			BookmarksController bookmarksController = ((obj12 != null) ? obj12.AddComponent<BookmarksController>() : null);
			if ((Object)(object)bookmarksController != (Object)null)
			{
				bookmarksController.TargetWindow = WindowInstance;
			}
			GameObject gameObject2 = ((Component)this).gameObject;
			GameObject obj13 = ((gameObject2 != null) ? UIUtils.FindRecursive(gameObject2, "Content/Body/Files/Container") : null);
			GameObject obj14 = ((obj13 != null) ? UIUtils.FindRecursive(obj13, "ScrollView/Viewport/Content") : null);
			GameObject obj15 = ((obj14 != null) ? UIUtils.FindRecursive(obj14, "GridView") : null);
			GridViewPopulator gridViewPopulator = ((obj15 != null) ? obj15.AddComponent<GridViewPopulator>() : null);
			if ((Object)(object)gridViewPopulator != (Object)null)
			{
				gridViewPopulator.TargetWindow = WindowInstance;
			}
			GameObject obj16 = ((obj13 != null) ? UIUtils.FindRecursive(obj13, "Placeholders") : null);
			MainPanelPlaceholderController mainPanelPlaceholderController = ((obj16 != null) ? obj16.AddComponent<MainPanelPlaceholderController>() : null);
			if ((Object)(object)mainPanelPlaceholderController != (Object)null)
			{
				mainPanelPlaceholderController.TargetWindow = WindowInstance;
			}
			GameObject obj17 = ((obj13 != null) ? UIUtils.FindRecursive(obj13, "Status") : null);
			StatusBarController statusBarController = ((obj17 != null) ? obj17.AddComponent<StatusBarController>() : null);
			if ((Object)(object)statusBarController != (Object)null)
			{
				statusBarController.TargetWindow = WindowInstance;
			}
			GameObject obj18 = ((obj13 != null) ? UIUtils.FindRecursive(obj13, "Actions") : null);
			ActionsBarController actionsBarController = ((obj18 != null) ? obj18.AddComponent<ActionsBarController>() : null);
			if ((Object)(object)actionsBarController != (Object)null)
			{
				actionsBarController.TargetWindow = WindowInstance;
				actionsBarController.TargetFileManager = this;
			}
			GameObjectExtensions.GetOrAddComponent<FileManagerKeybindHandler>(((Component)this).gameObject).TargetWindow = WindowInstance;
			WindowInstance.TabsChanged += CloseIfEmpty;
			WindowInstance.ItemsPicked += PickAndDestroy;
		}

		private void OnDestroy()
		{
			WindowInstance.ItemsPicked -= PickAndDestroy;
			WindowInstance.TabsChanged -= CloseIfEmpty;
		}

		private void PickAndDestroy(string[] paths)
		{
			if (_pickerMode)
			{
				this.ItemsPicked?.Invoke(paths);
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private void CloseIfEmpty()
		{
			if (WindowInstance.Count == 0)
			{
				Close();
			}
		}

		public void Close()
		{
			if ((Object)(object)((Component)this).gameObject != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private static FileManager NewInstance(string? initialPath, bool pickerMode, bool allowMultiSelection, bool isSelectionFolder = false)
		{
			GameObject obj = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>("fireman.main", "Window"));
			FileManager fileManager = ((obj != null) ? obj.AddComponent<FileManager>() : null);
			if ((Object)(object)fileManager == (Object)null)
			{
				return null;
			}
			fileManager._pickerMode = pickerMode;
			fileManager._allowMultiSelection = allowMultiSelection;
			fileManager._isSelectionFolder = isSelectionFolder;
			if (initialPath != null)
			{
				fileManager.CurrentPath = initialPath;
			}
			return fileManager;
		}

		public static FileManager CreateManager(string? initialPath = null)
		{
			return NewInstance(initialPath, pickerMode: false, allowMultiSelection: true);
		}

		public static FileManager CreatePicker(string? initialPath = null, bool isSelectionFolder = false, bool allowMultiSelection = false)
		{
			return NewInstance(initialPath, pickerMode: true, allowMultiSelection, isSelectionFolder);
		}
	}
}
namespace Fireman.Interface.Views
{
	public abstract class FileItemController : MonoBehaviour, ISelectHandler, IEventSystemHandler
	{
		public FileSystemInfo? FileInfo;

		public Window? TargetWindow;

		protected ButtonActiveStateIndicator? ActiveIndicator;

		protected ClickHandler? ClickHandler;

		public int Index { get; set; }

		protected virtual void Start()
		{
			ActiveIndicator = GameObjectExtensions.GetOrAddComponent<ButtonActiveStateIndicator>(((Component)this).gameObject);
			ClickHandler = GameObjectExtensions.GetOrAddComponent<ClickHandler>(((Component)this).gameObject);
			ClickHandler.OnPress += HandlePress;
			if (TargetWindow != null)
			{
				ClickHandler.OnDoubleClick += TargetWindow.ActivateSelection;
				TargetWindow.CurrentTab.Selection.SelectionChanged += UpdateSelectionVisual;
			}
			UpdateSelectionVisual();
		}

		protected virtual void OnDestroy()
		{
			if (TargetWindow != null)
			{
				TargetWindow.CurrentTab.Selection.SelectionChanged -= UpdateSelectionVisual;
			}
		}

		protected virtual void UpdateSelectionVisual()
		{
			if (!((Object)(object)ActiveIndicator == (Object)null) && TargetWindow != null && FileInfo != null)
			{
				ActiveIndicator.Active = TargetWindow.CurrentTab.Selection.IsSelected(FileInfo.FullName);
			}
		}

		private void HandlePress()
		{
			if (TargetWindow == null || FileInfo == null)
			{
				return;
			}
			FileSelectionModel selection = TargetWindow.CurrentTab.Selection;
			bool flag = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303);
			if ((Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) && TargetWindow.AllowMultiSelection)
			{
				selection.Toggle(FileInfo.FullName, Index);
			}
			else if (flag && TargetWindow.AllowMultiSelection)
			{
				List<string> allPaths = (from info in TargetWindow.GetCurrentDirItems()
					select info.FullName).ToList();
				int fromIndex = ((selection.AnchorIndex >= 0) ? selection.AnchorIndex : Index);
				selection.SelectRange(allPaths, fromIndex, Index);
			}
			else
			{
				selection.SelectOnly(FileInfo.FullName, Index);
			}
		}

		public virtual void SetSelected(bool isSelected)
		{
			if ((Object)(object)ActiveIndicator != (Object)null)
			{
				ActiveIndicator.Active = isSelected;
			}
		}

		public virtual void OnSelect(BaseEventData eventData)
		{
			EnsureVisibleInScrollView();
			if (Input.GetMouseButton(0) || Input.GetMouseButton(1) || TargetWindow == null || FileInfo == null)
			{
				return;
			}
			FileSelectionModel selection = TargetWindow.CurrentTab.Selection;
			if ((Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) && TargetWindow.AllowMultiSelection)
			{
				List<string> allPaths = (from info in TargetWindow.GetCurrentDirItems()
					select info.FullName).ToList();
				int fromIndex = ((selection.AnchorIndex >= 0) ? selection.AnchorIndex : Index);
				selection.SelectRange(allPaths, fromIndex, Index);
			}
			else
			{
				selection.SelectOnly(FileInfo.FullName, Index);
			}
		}

		protected void EnsureVisibleInScrollView()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			ScrollRect componentInParent = ((Component)this).GetComponentInParent<ScrollRect>();
			if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.viewport == (Object)null))
			{
				RectTransform val = (RectTransform)((Component)this).transform;
				RectTransform viewport = componentInParent.viewport;
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				Vector3[] array2 = (Vector3[])(object)new Vector3[4];
				val.GetWorldCorners(array);
				viewport.GetWorldCorners(array2);
				if (array[1].y > array2[1].y)
				{
					float num = array[1].y - array2[1].y;
					RectTransform content = componentInParent.content;
					content.anchoredPosition -= new Vector2(0f, num);
				}
				else if (array[0].y < array2[0].y)
				{
					float num2 = array2[0].y - array[0].y;
					RectTransform content2 = componentInParent.content;
					content2.anchoredPosition += new Vector2(0f, num2);
				}
			}
		}

		public abstract void UpdateItemInfo();
	}
	public readonly record struct PointerClickInfo
	{
		public readonly bool IsCtrl;

		public readonly bool IsShift;

		public PointerClickInfo(bool IsCtrl, bool IsShift)
		{
			this.IsCtrl = IsCtrl;
			this.IsShift = IsShift;
		}

		[CompilerGenerated]
		public void Deconstruct(out bool IsCtrl, out bool IsShift)
		{
			IsCtrl = this.IsCtrl;
			IsShift = this.IsShift;
		}
	}
	public class GridItemController : FileItemController
	{
		private Image? _icon;

		private TextMeshProUGUI? _name;

		private Button? _btn;

		private CanvasGroup? _group;

		protected override void Start()
		{
			base.Start();
			_btn = ((Component)this).GetComponent<Button>();
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Icon");
			_icon = ((obj != null) ? obj.GetComponent<Image>() : null);
			GameObject obj2 = UIUtils.FindRecursive(((Component)this).gameObject, "Name");
			_name = ((obj2 != null) ? obj2.GetComponent<TextMeshProUGUI>() : null);
			_group = ((Component)this).gameObject.GetComponent<CanvasGroup>();
			FileOperationsManager.CopyBufferChanged += UpdateOpacity;
			FileOperationsManager.CurrentActionChanged += UpdateOpacity;
			UpdateItemInfo();
		}

		protected override void OnDestroy()
		{
			FileOperationsManager.CopyBufferChanged -= UpdateOpacity;
			FileOperationsManager.CurrentActionChanged -= UpdateOpacity;
			base.OnDestroy();
		}

		private void ActivateItem()
		{
			if (FileInfo is DirectoryInfo directoryInfo && TargetWindow != null)
			{
				TargetWindow.CurrentPath = directoryInfo.FullName;
			}
		}

		public override void UpdateItemInfo()
		{
			if (FileInfo != null)
			{
				if ((Object)(object)_icon != (Object)null)
				{
					_icon.sprite = FileIcons.GetFileIcon(FileInfo);
				}
				if ((Object)(object)_name != (Object)null)
				{
					((TMP_Text)_name).text = TextUtils.SanitizeForDisplay(FileInfo.Name);
				}
			}
		}

		private void UpdateOpacity()
		{
			if (!((Object)(object)_group == (Object)null))
			{
				bool flag = FileOperationsManager.CurrentAction == CopyAction.Cut && FileOperationsManager.CopyBufferPaths.Any((string path) => path == FileInfo?.FullName);
				_group.alpha = (flag ? 0.5f : 1f);
			}
		}
	}
	public class GridViewPopulator : ViewPopulator
	{
		protected override GameObject CreateItem(FileSystemInfo fileInfo, int index)
		{
			GameObject val = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>("fireman.main", "GridFileItem"));
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GridItemController gridItemController = val.AddComponent<GridItemController>();
			gridItemController.FileInfo = fileInfo;
			gridItemController.TargetWindow = TargetWindow;
			gridItemController.Index = index;
			return val;
		}
	}
	public abstract class ViewPopulator : MonoBehaviour
	{
		public Window? TargetWindow;

		private FileSystemWatcher? _watcher;

		private readonly ConcurrentQueue<FileSystemEventArgs> _fileEventQueue = new ConcurrentQueue<FileSystemEventArgs>();

		protected virtual void Start()
		{
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged += OnPathChanged;
				SetupWatcher();
				Repopulate();
			}
		}

		protected virtual void OnDestroy()
		{
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged -= OnPathChanged;
			}
			DisposeWatcher();
		}

		private void OnPathChanged()
		{
			SetupWatcher();
			Repopulate();
		}

		private void SetupWatcher()
		{
			DisposeWatcher();
			if (TargetWindow?.CurrentPath == null || !Directory.Exists(TargetWindow.CurrentPath))
			{
				return;
			}
			try
			{
				_watcher = new FileSystemWatcher(TargetWindow.CurrentPath)
				{
					NotifyFilter = (NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.Size | NotifyFilters.LastWrite),
					Filter = "*.*",
					EnableRaisingEvents = true
				};
				_watcher.Created += OnFileSystemChanged;
				_watcher.Deleted += OnFileSystemChanged;
				_watcher.Renamed += OnFileSystemChanged;
				_watcher.Changed += OnFileSystemChanged;
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("Failed to initialize FileSystemWatcher for " + TargetWindow.CurrentPath + ": " + ex.Message));
			}
		}

		private void DisposeWatcher()
		{
			if (_watcher != null)
			{
				_watcher.EnableRaisingEvents = false;
				_watcher.Created -= OnFileSystemChanged;
				_watcher.Deleted -= OnFileSystemChanged;
				_watcher.Renamed -= OnFileSystemChanged;
				_watcher.Changed -= OnFileSystemChanged;
				_watcher.Dispose();
				_watcher = null;
				_fileEventQueue.Clear();
			}
		}

		private void OnFileSystemChanged(object sender, FileSystemEventArgs e)
		{
			_fileEventQueue.Enqueue(e);
		}

		protected void Repopulate()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (TargetWindow == null)
			{
				return;
			}
			foreach (Transform item in ((Component)this).transform)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			FileSystemInfo[] currentDirItems = TargetWindow.GetCurrentDirItems();
			for (int i = 0; i < currentDirItems.Length; i++)
			{
				FileSystemInfo fileInfo = currentDirItems[i];
				CreateItem(fileInfo, i).transform.SetParent(((Component)this).transform, false);
			}
		}

		protected abstract GameObject CreateItem(FileSystemInfo fileInfo, int index);

		protected virtual void Update()
		{
			while (true)
			{
				if (!_fileEventQueue.TryDequeue(out FileSystemEventArgs fileEvent))
				{
					break;
				}
				switch (fileEvent.ChangeType)
				{
				case WatcherChangeTypes.Deleted:
				{
					FileItemController fileItemController2 = ((Component)((Component)this).transform).GetComponentsInChildren<FileItemController>().FirstOrDefault((FileItemController comp) => comp.FileInfo?.FullName == fileEvent.FullPath);
					if ((Object)(object)fileItemController2 != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)fileItemController2).gameObject);
					}
					RefreshIndices();
					break;
				}
				case WatcherChangeTypes.Created:
				{
					string fullPath2 = fileEvent.FullPath;
					FileSystemInfo fileInfo2 = (File.Exists(fullPath2) ? ((FileSystemInfo)new FileInfo(fullPath2)) : ((FileSystemInfo)new DirectoryInfo(fullPath2)));
					CreateItem(fileInfo2, ((Component)this).transform.childCount).transform.SetParent(((Component)this).transform, false);
					break;
				}
				case WatcherChangeTypes.Renamed:
					if (fileEvent is RenamedEventArgs e)
					{
						string oldPath = e.OldFullPath;
						string fullPath = e.FullPath;
						FileItemController fileItemController = ((Component)((Component)this).transform).GetComponentsInChildren<FileItemController>().FirstOrDefault((FileItemController comp) => comp.FileInfo?.FullName == oldPath);
						if ((Object)(object)fileItemController != (Object)null)
						{
							FileSystemInfo fileInfo = (File.Exists(fullPath) ? ((FileSystemInfo)new FileInfo(fullPath)) : ((FileSystemInfo)new DirectoryInfo(fullPath)));
							fileItemController.FileInfo = fileInfo;
							fileItemController.UpdateItemInfo();
						}
					}
					else
					{
						Repopulate();
					}
					break;
				default:
					Repopulate();
					break;
				}
			}
			if (TargetWindow == null)
			{
				return;
			}
			EventSystem current = EventSystem.current;
			GameObject val = ((current != null) ? current.currentSelectedGameObject : null);
			if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<TMP_InputField>() != (Object)null)
			{
				return;
			}
			if ((Input.GetKeyDown((KeyCode)273) || Input.GetKeyDown((KeyCode)274) || Input.GetKeyDown((KeyCode)276) || Input.GetKeyDown((KeyCode)275)) && ((Object)(object)val == (Object)null || (Object)(object)val.GetComponent<FileItemController>() == (Object)null))
			{
				FileItemController componentInChildren = ((Component)this).GetComponentInChildren<FileItemController>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					Selectable component = ((Component)componentInChildren).GetComponent<Selectable>();
					if (component != null)
					{
						component.Select();
					}
				}
			}
			else
			{
				if (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271))
				{
					TargetWindow.ActivateSelection();
				}
				if (Input.GetKeyDown((KeyCode)27))
				{
					TargetWindow.CurrentTab.Selection.Clear();
				}
			}
		}

		private void RefreshIndices()
		{
			FileItemController[] componentsInChildren = ((Component)this).GetComponentsInChildren<FileItemController>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].Index = i;
			}
		}
	}
}
namespace Fireman.Interface.Reusables
{
	public class ButtonActiveStateIndicator : MonoBehaviour
	{
		[CompilerGenerated]
		private bool <Active>k__BackingField;

		public Color? SelectedColor;

		public Color? NormalColor;

		private Button _btn;

		public bool Active
		{
			[CompilerGenerated]
			get
			{
				return <Active>k__BackingField;
			}
			set
			{
				if (<Active>k__BackingField != value)
				{
					<Active>k__BackingField = value;
					UpdateState();
				}
			}
		}

		private void OnEnable()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			_btn = ((Component)this).GetComponent<Button>();
			ColorBlock colors;
			if (!SelectedColor.HasValue)
			{
				colors = ((Selectable)_btn).colors;
				SelectedColor = ((ColorBlock)(ref colors)).selectedColor;
			}
			if (!NormalColor.HasValue)
			{
				colors = ((Selectable)_btn).colors;
				NormalColor = ((ColorBlock)(ref colors)).normalColor;
			}
		}

		protected void UpdateState()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			ColorBlock colors = ((Selectable)_btn).colors;
			Color normalColor = (Color)((!Active) ? (((??)NormalColor) ?? ((ColorBlock)(ref colors)).normalColor) : (((??)SelectedColor) ?? ((ColorBlock)(ref colors)).selectedColor));
			((ColorBlock)(ref colors)).normalColor = normalColor;
			((Selectable)_btn).colors = colors;
		}
	}
}
namespace Fireman.Interface.GlobalControls
{
	public class ActionsBarController : MonoBehaviour
	{
		public FileManager? TargetFileManager;

		public Window? TargetWindow;

		public Button? _cancel;

		public ClickHandler? _confirm;

		private void Start()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			if (TargetWindow == null)
			{
				return;
			}
			if (!TargetWindow.PickerMode)
			{
				((Component)this).gameObject.SetActive(false);
				return;
			}
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Cancel");
			_cancel = ((obj != null) ? obj.GetComponent<Button>() : null);
			GameObject obj2 = UIUtils.FindRecursive(((Component)this).gameObject, "Select");
			_confirm = ((obj2 != null) ? GameObjectExtensions.GetOrAddComponent<ClickHandler>(obj2) : null);
			Button? cancel = _cancel;
			if (cancel != null)
			{
				((UnityEvent)cancel.onClick).AddListener((UnityAction)delegate
				{
					FileManager? targetFileManager = TargetFileManager;
					Object.Destroy((Object)(object)((targetFileManager != null) ? ((Component)targetFileManager).gameObject : null));
				});
			}
			ClickHandler? confirm = _confirm;
			if (confirm != null)
			{
				confirm.OnPress += delegate
				{
					TargetWindow?.PickSelection();
				};
			}
			((Component)this).gameObject.SetActive(true);
		}
	}
	public class AddressBreadcrumbRowController : MonoBehaviour
	{
		public Window? TargetWindow;

		private string? lastPath;

		private void Start()
		{
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged += UpdateDisplay;
			}
			UpdateDisplay();
		}

		private void OnDestroy()
		{
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged -= UpdateDisplay;
			}
		}

		private void UpdateDisplay()
		{
			if (!(TargetWindow?.CurrentPath == lastPath))
			{
				lastPath = TargetWindow?.CurrentPath;
				Repopulate();
			}
		}

		private void Repopulate()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (TargetWindow == null)
			{
				return;
			}
			foreach (Transform item in ((Component)this).transform)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			DirectoryInfo[] array = FileUtils.GetPathItems(new DirectoryInfo(TargetWindow.CurrentPath)).ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				DirectoryInfo dirInfo = array[i];
				AddCrumb(dirInfo, i == 0, i == array.Length - 1);
			}
		}

		private void AddCrumb(DirectoryInfo dirInfo, bool first, bool last)
		{
			GameObject val = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>("fireman.main", "BreadcrumbPiece"), ((Component)this).transform);
			if (!((Object)(object)val == (Object)null))
			{
				BreadcrumbPieceController breadcrumbPieceController = val.AddComponent<BreadcrumbPieceController>();
				breadcrumbPieceController.Directory = dirInfo;
				breadcrumbPieceController.First = first;
				breadcrumbPieceController.Last = last;
				breadcrumbPieceController.TargetWindow = TargetWindow;
			}
		}
	}
	public class AddressController : MonoBehaviour
	{
		public Window? TargetWindow;

		private GameObject? _input;

		private GameObject? _breadcrumbRow;

		private TMP_InputField? _inputComp;

		private void Start()
		{
			GameObject gameObject = ((Component)this).gameObject;
			_input = ((gameObject != null) ? UIUtils.FindRecursive(gameObject, "Input") : null);
			GameObject? input = _input;
			_inputComp = ((input != null) ? input.GetComponent<TMP_InputField>() : null);
			if ((Object)(object)_inputComp != (Object)null)
			{
				((UnityEvent<string>)(object)_inputComp.onDeselect).AddListener((UnityAction<string>)UnfocusInput);
				((UnityEvent<string>)(object)_inputComp.onEndEdit).AddListener((UnityAction<string>)UnfocusInput);
			}
			GameObject? input2 = _input;
			AddressInputController addressInputController = ((input2 != null) ? input2.AddComponent<AddressInputController>() : null);
			if ((Object)(object)addressInputController != (Object)null)
			{
				addressInputController.TargetWindow = TargetWindow;
			}
			GameObject gameObject2 = ((Component)this).gameObject;
			_breadcrumbRow = ((gameObject2 != null) ? UIUtils.FindRecursive(gameObject2, "BreadcrumbScrollView/Viewport/Row") : null);
			GameObject? breadcrumbRow = _breadcrumbRow;
			AddressBreadcrumbRowController addressBreadcrumbRowController = ((breadcrumbRow != null) ? breadcrumbRow.AddComponent<AddressBreadcrumbRowController>() : null);
			if ((Object)(object)addressBreadcrumbRowController != (Object)null)
			{
				addressBreadcrumbRowController.TargetWindow = TargetWindow;
			}
			GameObject gameObject3 = ((Component)this).gameObject;
			GameObject obj = ((gameObject3 != null) ? UIUtils.FindRecursive(gameObject3, "BreadcrumbScrollView/InputActivatorButton") : null);
			ClickHandler val = ((obj != null) ? GameObjectExtensions.GetOrAddComponent<ClickHandler>(obj) : null);
			if ((Object)(object)val != (Object)null)
			{
				val.OnPress += FocusInput;
			}
		}

		public void FocusInput()
		{
			GameObject? breadcrumbRow = _breadcrumbRow;
			if (breadcrumbRow != null)
			{
				breadcrumbRow.SetActive(false);
			}
			GameObject? input = _input;
			if (input != null)
			{
				input.SetActive(true);
			}
			EventSystem.current.SetSelectedGameObject(_input, (BaseEventData)null);
			TMP_InputField? inputComp = _inputComp;
			if (inputComp != null)
			{
				inputComp.ActivateInputField();
			}
		}

		private void UnfocusInput(string _)
		{
			GameObject? input = _input;
			if (input != null)
			{
				input.SetActive(false);
			}
			GameObject? breadcrumbRow = _breadcrumbRow;
			if (breadcrumbRow != null)
			{
				breadcrumbRow.SetActive(true);
			}
		}
	}
	public class AddressInputController : MonoBehaviour
	{
		public Window? TargetWindow;

		private TMP_InputField? _input;

		private void OnEnable()
		{
			_input = ((Component)this).GetComponent<TMP_InputField>();
			((UnityEvent<string>)(object)_input.onEndEdit).AddListener((UnityAction<string>)TrySetPath);
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged += UpdateDisplay;
			}
			UpdateDisplay();
		}

		private void OnDisable()
		{
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged -= UpdateDisplay;
			}
		}

		private void TrySetPath(string value)
		{
			if (Validations.Accessible(value) && TargetWindow != null)
			{
				TargetWindow.CurrentPath = value;
			}
			else
			{
				UpdateDisplay();
			}
		}

		private void UpdateDisplay()
		{
			if (TargetWindow != null && !((Object)(object)_input == (Object)null))
			{
				string currentPath = TargetWindow.CurrentPath;
				_input.SetTextWithoutNotify(currentPath);
			}
		}
	}
	public class BackButtonController : MonoBehaviour
	{
		public Window? TargetWindow;

		private Image? _icon;

		private Button? _button;

		private void Start()
		{
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Icon");
			_icon = ((obj != null) ? obj.GetComponent<Image>() : null);
			_button = ((Component)this).gameObject.GetComponent<Button>();
			GameObjectExtensions.GetOrAddComponent<ClickHandler>(((Component)this).gameObject).OnPress += delegate
			{
				TargetWindow?.GoBack();
			};
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged += UpdateDisplay;
			}
			UpdateDisplay();
		}

		private void OnDestroy()
		{
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged -= UpdateDisplay;
			}
		}

		private void UpdateDisplay()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (TargetWindow != null)
			{
				string text = (TargetWindow.CanGoBack ? "direction_left" : "direction_left_inactive");
				Sprite sprite = AssetManager.Get<Sprite>("fireman.main", text);
				if ((Object)(object)_icon != (Object)null)
				{
					_icon.sprite = sprite;
					((Graphic)_icon).color = (TargetWindow.CanGoBack ? Color.white : ColorUtils.Transparentize(Color.white, 0.5f));
				}
				if ((Object)(object)_button != (Object)null)
				{
					((Selectable)_button).interactable = TargetWindow.CanGoBack;
				}
			}
		}
	}
	public class BookmarkItemController : MonoBehaviour
	{
		public DirectoryInfo? Path;

		public Window? TargetWindow;

		private static Dictionary<string, string> NiceBookmarkNames = new Dictionary<string, string>
		{
			[Paths.Home] = "Home",
			[Paths.AngryLevels] = "Angry levels",
			[Paths.ThornConfig] = "Thorn config"
		};

		private ButtonActiveStateIndicator? _btnVisualState;

		private void Start()
		{
			if (Path != null && TargetWindow != null)
			{
				GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Icon");
				Image val = ((obj != null) ? obj.GetComponent<Image>() : null);
				GameObject obj2 = UIUtils.FindRecursive(((Component)this).gameObject, "Name");
				TextMeshProUGUI val2 = ((obj2 != null) ? obj2.GetComponent<TextMeshProUGUI>() : null);
				_btnVisualState = GameObjectExtensions.GetOrAddComponent<ButtonActiveStateIndicator>(((Component)this).gameObject);
				Sprite fileIcon = FileIcons.GetFileIcon(Path);
				if ((Object)(object)val != (Object)null)
				{
					val.sprite = fileIcon;
				}
				if ((Object)(object)val2 != (Object)null)
				{
					((TMP_Text)val2).text = GetBookmarkName(Path);
				}
				GameObjectExtensions.GetOrAddComponent<ClickHandler>(((Component)this).gameObject).OnPress += delegate
				{
					TargetWindow.CurrentPath = Path.FullName;
				};
				TargetWindow.CurrentPathChanged += UpdateDisplay;
				UpdateDisplay();
			}
		}

		private void OnDestroy()
		{
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged -= UpdateDisplay;
			}
		}

		private string GetBookmarkName(DirectoryInfo path)
		{
			if (NiceBookmarkNames.TryGetValue(path.FullName, out string value))
			{
				return value;
			}
			return path.Name;
		}

		private void UpdateDisplay()
		{
			if (!((Object)(object)_btnVisualState == (Object)null) && TargetWindow != null && Path != null)
			{
				_btnVisualState.Active = TargetWindow.CurrentTab.CurrentPath == Path.FullName;
			}
		}
	}
	public class BookmarksController : MonoBehaviour
	{
		public Window? TargetWindow;

		private const string Separator = "__SEPARATOR";

		private static string[] ItemPaths
		{
			get
			{
				List<string> list = new List<string>();
				list.Add(Paths.Game);
				list.Add(Paths.BepInEx);
				list.Add(Paths.Cybergrind);
				list.AddRange((!Chainloader.PluginInfos.ContainsKey("com.eternalUnion.angryLevelLoader")) ? new string[0] : new string[1] { Paths.AngryLevels });
				list.AddRange((!Chainloader.PluginInfos.ContainsKey("com.github.end-4.thornClient")) ? new string[0] : new string[1] { Paths.ThornConfig });
				list.Add("__SEPARATOR");
				list.Add(Paths.Home);
				list.Add(Paths.Downloads);
				list.Add(Paths.Documents);
				list.Add(Paths.Images);
				list.Add(Paths.Music);
				list.Add(Paths.Videos);
				return list.ToArray();
			}
		}

		private void Start()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			foreach (Transform item in ((Component)this).transform)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			string[] itemPaths = ItemPaths;
			foreach (string text in itemPaths)
			{
				if (text == "__SEPARATOR")
				{
					CreateSeparator();
				}
				else
				{
					CreateButton(text);
				}
			}
		}

		private void CreateSeparator()
		{
			Object.Instantiate<GameObject>(AssetManager.Get<GameObject>("fireman.main", "BookmarkSeparator"), ((Component)this).transform);
		}

		private void CreateButton(string path)
		{
			GameObject val = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>("fireman.main", "BookmarkItem"), ((Component)this).transform);
			if (!((Object)(object)val == (Object)null))
			{
				BookmarkItemController bookmarkItemController = val.AddComponent<BookmarkItemController>();
				bookmarkItemController.Path = new DirectoryInfo(path);
				bookmarkItemController.TargetWindow = TargetWindow;
			}
		}
	}
	public class BreadcrumbPieceController : MonoBehaviour
	{
		public Window? TargetWindow;

		public DirectoryInfo? Directory;

		public bool First = true;

		public bool Last = true;

		private Image? _bg;

		private Image? _icon;

		private TextMeshProUGUI? _text;

		private Button? _btn;

		private void Start()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			_bg = ((Component)this).GetComponent<Image>();
			_btn = ((Component)this).GetComponent<Button>();
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Icon");
			_icon = ((obj != null) ? obj.GetComponent<Image>() : null);
			GameObject obj2 = UIUtils.FindRecursive(((Component)this).gameObject, "Name");
			_text = ((obj2 != null) ? obj2.GetComponent<TextMeshProUGUI>() : null);
			((UnityEvent)_btn.onClick).AddListener(new UnityAction(GoTo));
			UpdatePieceShape();
			UpdateInfo();
		}

		private void GoTo()
		{
			if (TargetWindow != null && Directory != null)
			{
				TargetWindow.CurrentPath = Directory.FullName;
			}
		}

		private void UpdatePieceShape()
		{
			if (!((Object)(object)_bg == (Object)null))
			{
				bool first = First;
				bool last = Last;
				string text = (first ? ((!last) ? "Round_FillLargeLeft" : "Round_FillLarge") : ((!last) ? "FillLarge" : "Round_FillLargeRight"));
				string text2 = text;
				Sprite sprite = AssetManager.Get<Sprite>("fireman.main", text2);
				_bg.sprite = sprite;
			}
		}

		private void UpdateInfo()
		{
			if (Directory != null && !((Object)(object)_icon == (Object)null) && !((Object)(object)_text == (Object)null))
			{
				((TMP_Text)_text).text = Directory.Name;
				Sprite symbolicFolderIcon = FileIcons.GetSymbolicFolderIcon(Directory);
				if ((Object)(object)symbolicFolderIcon != (Object)null)
				{
					_icon.sprite = symbolicFolderIcon;
					((Component)_icon).gameObject.SetActive(true);
				}
				else
				{
					((Component)_icon).gameObject.SetActive(false);
				}
			}
		}
	}
	public class FileManagerKeybindHandler : MonoBehaviour
	{
		public Window? TargetWindow;

		private AddressController? _addressController;

		private void Start()
		{
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Content/TopBar/Address");
			_addressController = ((obj != null) ? obj.GetComponent<AddressController>() : null);
		}

		private void OnEnable()
		{
			Config.NewTabBind.OnPress += NewTab;
			Config.CloseTabBind.OnPress += CloseTab;
			Config.BackBind.OnPress += GoBack;
			Config.BackBindAlt.OnPress += GoBack;
			Config.ForwardBind.OnPress += GoForward;
			Config.ForwardBindAlt.OnPress += GoForward;
			Config.ParentDirBind.OnPress += GoUp;
			Config.LeftTabBind.OnPress += LeftTab;
			Config.LeftTabBindAlt.OnPress += LeftTab;
			Config.RightTabBind.OnPress += RightTab;
			Config.RightTabBindAlt.OnPress += RightTab;
			Config.CopyBind.OnPress += Copy;
			Config.CopyBindAlt.OnPress += Copy;
			Config.CutBind.OnPress += Cut;
			Config.CutBindAlt.OnPress += Cut;
			Config.PasteBind.OnPress += Paste;
			Config.PasteBindAlt.OnPress += Paste;
			Config.PermaDeleteBind.OnPress += PermaDelete;
			Config.PermaDeleteBindAlt.OnPress += PermaDelete;
			Config.FocusAddressBarBind.OnPress += FocusAddressBar;
			Config.FocusAddressBarBindAlt.OnPress += FocusAddressBar;
		}

		private void OnDisable()
		{
			Config.NewTabBind.OnPress -= NewTab;
			Config.CloseTabBind.OnPress -= CloseTab;
			Config.BackBind.OnPress -= GoBack;
			Config.BackBindAlt.OnPress -= GoBack;
			Config.ForwardBind.OnPress -= GoForward;
			Config.ForwardBindAlt.OnPress -= GoForward;
			Config.ParentDirBind.OnPress -= GoUp;
			Config.LeftTabBind.OnPress -= LeftTab;
			Config.LeftTabBindAlt.OnPress -= LeftTab;
			Config.RightTabBind.OnPress -= RightTab;
			Config.RightTabBindAlt.OnPress -= RightTab;
			Config.CopyBind.OnPress -= Copy;
			Config.CopyBindAlt.OnPress -= Copy;
			Config.CutBind.OnPress -= Cut;
			Config.CutBindAlt.OnPress -= Cut;
			Config.PasteBind.OnPress -= Paste;
			Config.PasteBindAlt.OnPress -= Paste;
			Config.PermaDeleteBind.OnPress -= PermaDelete;
			Config.PermaDeleteBindAlt.OnPress -= PermaDelete;
			Config.FocusAddressBarBind.OnPress -= FocusAddressBar;
			Config.FocusAddressBarBindAlt.OnPress -= FocusAddressBar;
		}

		private void NewTab()
		{
			if (((Component)this).gameObject.activeInHierarchy)
			{
				TargetWindow?.NewTab();
			}
		}

		private void CloseTab()
		{
			if (((Component)this).gameObject.activeInHierarchy)
			{
				TargetWindow?.CloseTab();
			}
		}

		private void GoForward()
		{
			if (((Component)this).gameObject.activeInHierarchy)
			{
				TargetWindow?.GoForward();
			}
		}

		private void GoBack()
		{
			if (((Component)this).gameObject.activeInHierarchy)
			{
				TargetWindow?.GoBack();
			}
		}

		private void GoUp()
		{
			if (((Component)this).gameObject.activeInHierarchy)
			{
				TargetWindow?.GoUp();
			}
		}

		private void LeftTab()
		{
			if (((Component)this).gameObject.activeInHierarchy && TargetWindow != null)
			{
				int currentTabIndex = TargetWindow.CurrentTabIndex;
				int count = TargetWindow.Count;
				TargetWindow.CurrentTabIndex = (currentTabIndex + count - 1) % count;
			}
		}

		private void RightTab()
		{
			if (((Component)this).gameObject.activeInHierarchy && TargetWindow != null)
			{
				int currentTabIndex = TargetWindow.CurrentTabIndex;
				TargetWindow.CurrentTabIndex = (currentTabIndex + 1) % TargetWindow.Count;
			}
		}

		private void Copy()
		{
			if (((Component)this).gameObject.activeInHierarchy && TargetWindow != null)
			{
				FileOperationsManager.Copy(TargetWindow.CurrentTab.Selection);
			}
		}

		private void Cut()
		{
			if (((Component)this).gameObject.activeInHierarchy && TargetWindow != null)
			{
				FileOperationsManager.Cut(TargetWindow.CurrentTab.Selection);
			}
		}

		private void Paste()
		{
			if (((Component)this).gameObject.activeInHierarchy && TargetWindow != null)
			{
				FileOperationsManager.Paste(TargetWindow.CurrentPath);
			}
		}

		private void PermaDelete()
		{
			if (((Component)this).gameObject.activeInHierarchy && TargetWindow != null)
			{
				FileOperationsManager.PermaDelete(TargetWindow.CurrentTab.Selection);
			}
		}

		private void FocusAddressBar()
		{
			if (((Component)this).gameObject.activeInHierarchy && !((Object)(object)_addressController == (Object)null))
			{
				_addressController.FocusInput();
			}
		}
	}
	public class ForwardButtonController : MonoBehaviour
	{
		public Window? TargetWindow;

		private Image? _icon;

		private Button? _button;

		private void Start()
		{
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Icon");
			_icon = ((obj != null) ? obj.GetComponent<Image>() : null);
			_button = ((Component)this).gameObject.GetComponent<Button>();
			GameObjectExtensions.GetOrAddComponent<ClickHandler>(((Component)this).gameObject).OnPress += delegate
			{
				TargetWindow?.GoForward();
			};
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged += UpdateDisplay;
			}
			UpdateDisplay();
		}

		private void OnDestroy()
		{
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged -= UpdateDisplay;
			}
		}

		private void UpdateDisplay()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (TargetWindow != null)
			{
				string text = (TargetWindow.CanGoForward ? "direction_right" : "direction_right_inactive");
				Sprite sprite = AssetManager.Get<Sprite>("fireman.main", text);
				if ((Object)(object)_icon != (Object)null)
				{
					_icon.sprite = sprite;
					((Graphic)_icon).color = (TargetWindow.CanGoForward ? Color.white : ColorUtils.Transparentize(Color.white, 0.5f));
				}
				if ((Object)(object)_button != (Object)null)
				{
					((Selectable)_button).interactable = TargetWindow.CanGoForward;
				}
			}
		}
	}
	public class MainPanelPlaceholderController : MonoBehaviour
	{
		public Window? TargetWindow;

		private GameObject? _empty;

		private void Start()
		{
			if (TargetWindow != null)
			{
				_empty = UIUtils.FindRecursive(((Component)this).gameObject, "Empty");
				TargetWindow.CurrentPathChanged += UpdatePlaceholder;
				UpdatePlaceholder();
			}
		}

		private void UpdatePlaceholder()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (TargetWindow != null)
			{
				int num = TargetWindow.GetCurrentDirItemsUnsorted().Length;
				GameObject? empty = _empty;
				if (empty != null)
				{
					SlideFadeToggleEffectExtensions.SetActiveAnimated(empty, num == 0, new Vector2(0f, -10f), 30f);
				}
			}
		}
	}
	public class StatusBarController : MonoBehaviour
	{
		public Window? TargetWindow;

		private TextMeshProUGUI? _text;

		private void Start()
		{
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Text");
			_text = ((obj != null) ? obj.GetComponent<TextMeshProUGUI>() : null);
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged += UpdateDisplay;
			}
			FileOperationsManager.CopyBufferChanged += UpdateDisplay;
			FileOperationsManager.CurrentActionChanged += UpdateDisplay;
			UpdateDisplay();
		}

		private void OnDestroy()
		{
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged -= UpdateDisplay;
			}
			FileOperationsManager.CopyBufferChanged -= UpdateDisplay;
			FileOperationsManager.CurrentActionChanged -= UpdateDisplay;
		}

		private void UpdateDisplay()
		{
			if (TargetWindow == null)
			{
				return;
			}
			string countString = GetCountString((FileOperationsManager.CurrentAction == CopyAction.None) ? TargetWindow.GetCurrentDirItemsUnsorted() : FileOperationsManager.CopyBufferPaths.Select((string path) => (!Directory.Exists(path)) ? ((FileSystemInfo)new FileInfo(path)) : ((FileSystemInfo)new DirectoryInfo(path))).ToArray());
			if ((Object)(object)_text != (Object)null)
			{
				switch (FileOperationsManager.CurrentAction)
				{
				case CopyAction.None:
					((TMP_Text)_text).text = countString;
					break;
				case CopyAction.Copy:
					((TMP_Text)_text).text = "Copy buffer: " + countString;
					break;
				case CopyAction.Cut:
					((TMP_Text)_text).text = "Cut buffer: " + countString;
					break;
				}
			}
			UIUtils.UnfuckLayoutHack(((Component)this).gameObject);
		}

		private static string GetCountString(FileSystemInfo[] items)
		{
			int num = items.Count((FileSystemInfo i) => i is DirectoryInfo);
			int num2 = items.Count((FileSystemInfo i) => i is FileInfo);
			string text = "";
			if (num > 0)
			{
				text += $"[{num}]";
			}
			if (num2 > 0)
			{
				text = text + ((text.Length > 0) ? " + " : "") + $"{num2}";
			}
			return text + ((text.Length == 0) ? "Nothing" : " items");
		}
	}
	public class TabButtonController : MonoBehaviour
	{
		public Tab? TargetTab;

		public Window? TargetWindow;

		private Button? _btn;

		private Image? _icon;

		private TextMeshProUGUI? _name;

		private Button? _close;

		private ButtonActiveStateIndicator? _btnVisualState;

		private void Start()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			_btn = ((Component)this).gameObject.GetComponent<Button>();
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Icon");
			_icon = ((obj != null) ? obj.GetComponent<Image>() : null);
			GameObject obj2 = UIUtils.FindRecursive(((Component)this).gameObject, "Name");
			_name = ((obj2 != null) ? obj2.GetComponent<TextMeshProUGUI>() : null);
			GameObject obj3 = UIUtils.FindRecursive(((Component)this).gameObject, "Close");
			_close = ((obj3 != null) ? obj3.GetComponent<Button>() : null);
			_btnVisualState = GameObjectExtensions.GetOrAddComponent<ButtonActiveStateIndicator>(((Component)this).gameObject);
			Button? btn = _btn;
			if (btn != null)
			{
				((UnityEvent)btn.onClick).AddListener((UnityAction)delegate
				{
					if (TargetWindow != null && TargetTab != null)
					{
						TargetWindow.CurrentTab = TargetTab;
					}
				});
			}
			Button? close = _close;
			if (close != null)
			{
				((UnityEvent)close.onClick).AddListener(new UnityAction(CloseTab));
			}
			GameObjectExtensions.GetOrAddComponent<ClickHandler>(((Component)this).gameObject).OnMiddlePress += CloseTab;
			Button? close2 = _close;
			if (close2 != null)
			{
				GameObjectExtensions.GetOrAddComponent<ClickHandler>(((Component)close2).gameObject).OnMiddlePress += CloseTab;
			}
			if (TargetTab != null)
			{
				TargetTab.CurrentPathChanged += UpdateCurrentDir;
			}
			if (TargetWindow != null)
			{
				TargetWindow.CurrentTabChanged += UpdateActive;
			}
			UpdateCurrentDir();
			UpdateActive();
		}

		private void CloseTab()
		{
			if (TargetWindow != null && TargetTab != null)
			{
				TargetWindow.CloseTab(TargetTab);
			}
		}

		private void OnDestroy()
		{
			if (TargetTab != null)
			{
				TargetTab.CurrentPathChanged -= UpdateCurrentDir;
			}
			if (TargetWindow != null)
			{
				TargetWindow.CurrentTabChanged -= UpdateActive;
			}
		}

		private void UpdateCurrentDir()
		{
			if (!((Object)(object)_name == (Object)null) && !((Object)(object)_icon == (Object)null) && TargetTab != null)
			{
				DirectoryInfo directoryInfo = new DirectoryInfo(TargetTab.CurrentPath);
				string name = directoryInfo.Name;
				Sprite fileIcon = FileIcons.GetFileIcon(directoryInfo);
				if (((TMP_Text)_name).text != name)
				{
					((TMP_Text)_name).text = name;
				}
				if ((Object)(object)_icon.sprite != (Object)(object)fileIcon)
				{
					_icon.sprite = fileIcon;
				}
				UIUtils.UnfuckLayoutHack(((Component)this).gameObject);
			}
		}

		private void UpdateActive()
		{
			if (!((Object)(object)_btnVisualState == (Object)null))
			{
				_btnVisualState.Active = TargetWindow?.CurrentTab == TargetTab;
				UIUtils.UnfuckLayoutHack(((Component)this).gameObject);
			}
		}
	}
	public class TabRowController : MonoBehaviour
	{
		public Window? TargetWindow;

		private GameObject? _newButton;

		private unsafe void Start()
		{
			if (TargetWindow != null)
			{
				TargetWindow.TabAdded += AddTab;
				TargetWindow.TabRemoved += RemoveTab;
				TargetWindow.CurrentPathChanged += new Action(((Component)this).gameObject, (nint)(delegate*<GameObject, void>)(&UIUtils.UnfuckLayoutHack));
			}
			Repopulate();
		}

		private unsafe void OnDestroy()
		{
			if (TargetWindow != null)
			{
				TargetWindow.TabAdded -= AddTab;
				TargetWindow.TabRemoved -= RemoveTab;
				TargetWindow.CurrentPathChanged -= new Action(((Component)this).gameObject, (nint)(delegate*<GameObject, void>)(&UIUtils.UnfuckLayoutHack));
			}
		}

		private void AddTab(Tab tab)
		{
			GameObject val = Object.Instantiate<GameObject>(AssetManager.Get<GameObject>("fireman.main", "WindowTab"), ((Component)this).transform);
			if (!((Object)(object)val == (Object)null))
			{
				TabButtonController tabButtonController = val.AddComponent<TabButtonController>();
				tabButtonController.TargetTab = tab;
				tabButtonController.TargetWindow = TargetWindow;
				GameObject? newButton = _newButton;
				if (newButton != null)
				{
					newButton.transform.SetAsLastSibling();
				}
			}
		}

		private void RemoveTab(Tab tab)
		{
			(from controller in ((Component)this).gameObject.GetComponentsInChildren<TabButtonController>()
				where controller.TargetTab == tab
				select controller).ToList().ForEach(delegate(TabButtonController controller)
			{
				Object.Destroy((Object)(object)((Component)controller).gameObject);
			});
		}

		private void Repopulate()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (TargetWindow == null)
			{
				return;
			}
			foreach (Transform item in ((Component)this).transform)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			foreach (Tab tab in TargetWindow.Tabs)
			{
				AddTab(tab);
			}
			EnsureNewButton();
			UIUtils.UnfuckLayoutHack(((Component)this).gameObject);
			ExecutionUtils.RunNextFrame((Action)delegate
			{
				if ((Object)(object)((Component)this).gameObject != (Object)null)
				{
					UIUtils.UnfuckLayoutHack(((Component)this).gameObject);
				}
			});
		}

		private void EnsureNewButton()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			GameObject val = AssetManager.Get<GameObject>("fireman.main", "NewTab");
			if ((Object)(object)_newButton == (Object)null)
			{
				_newButton = Object.Instantiate<GameObject>(val, ((Component)this).transform);
				((UnityEvent)GameObjectExtensions.GetOrAddComponent<Button>(_newButton).onClick).AddListener(new UnityAction(AddTab));
			}
			GameObject? newButton = _newButton;
			if (newButton != null)
			{
				newButton.transform.SetAsLastSibling();
			}
		}

		private void AddTab()
		{
			TargetWindow?.NewTab();
		}
	}
	public class UpButtonController : MonoBehaviour
	{
		public Window? TargetWindow;

		private Image? _icon;

		private Button? _button;

		private void Start()
		{
			GameObject obj = UIUtils.FindRecursive(((Component)this).gameObject, "Icon");
			_icon = ((obj != null) ? obj.GetComponent<Image>() : null);
			_button = ((Component)this).gameObject.GetComponent<Button>();
			GameObjectExtensions.GetOrAddComponent<ClickHandler>(((Component)this).gameObject).OnPress += delegate
			{
				TargetWindow?.GoUp();
			};
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged += UpdateDisplay;
			}
			UpdateDisplay();
		}

		private void OnDestroy()
		{
			if (TargetWindow != null)
			{
				TargetWindow.CurrentPathChanged -= UpdateDisplay;
			}
		}

		private void UpdateDisplay()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (TargetWindow != null)
			{
				bool canGoUp = TargetWindow.CanGoUp;
				if ((Object)(object)_icon != (Object)null)
				{
					((Graphic)_icon).color = (canGoUp ? Color.white : ColorUtils.Transparentize(Color.white, 0.5f));
				}
				if ((Object)(object)_button != (Object)null)
				{
					((Selectable)_button).interactable = canGoUp;
				}
			}
		}
	}
}
namespace Fireman.Core
{
	public static class FileOperationsManager
	{
		public static CopyAction _currentAction = CopyAction.None;

		private static readonly HashSet<string> _copyBufferPaths = new HashSet<string>(StringComparer.Ordinal);

		public static CopyAction CurrentAction
		{
			get
			{
				return _currentAction;
			}
			private set
			{
				_currentAction = value;
				FileOperationsManager.CurrentActionChanged?.Invoke();
			}
		}

		public static IReadOnlyCollection<string> CopyBufferPaths
		{
			get
			{
				return _copyBufferPaths;
			}
			private set
			{
				_copyBufferPaths.Clear();
				_copyBufferPaths.UnionWith(value);
				FileOperationsManager.CopyBufferChanged?.Invoke();
			}
		}

		public static event Action? CopyBufferChanged;

		public static event Action? CurrentActionChanged;

		public static void Copy(FileSelectionModel selection)
		{
			Grab(selection, CopyAction.Copy);
		}

		public static void Cut(FileSelectionModel selection)
		{
			Grab(selection, CopyAction.Cut);
		}

		public static void Paste(string destination)
		{
			if (CopyBufferPaths.Count == 0)
			{
				return;
			}
			DirectoryInfo directoryInfo = new DirectoryInfo(destination);
			if (CurrentAction == CopyAction.Copy)
			{
				foreach (string copyBufferPath in _copyBufferPaths)
				{
					string text = Path.Combine(directoryInfo.FullName, Path.GetFileName(copyBufferPath));
					if (copyBufferPath == text)
					{
						text = Path.Combine(directoryInfo.FullName, Path.GetFileNameWithoutExtension(copyBufferPath) + " copy" + Path.GetExtension(copyBufferPath));
					}
					File.Copy(copyBufferPath, text, overwrite: true);
				}
				return;
			}
			if (CurrentAction != CopyAction.Cut)
			{
				return;
			}
			foreach (string copyBufferPath2 in _copyBufferPaths)
			{
				string text2 = Path.Combine(directoryInfo.FullName, Path.GetFileName(copyBufferPath2));
				if (!(copyBufferPath2 == text2))
				{
					File.Move(copyBufferPath2, text2);
				}
			}
			_copyBufferPaths.Clear();
			CurrentAction = CopyAction.None;
		}

		public static void PermaDelete(FileSelectionModel selection)
		{
			if (selection?.SelectedPaths == null || selection.SelectedPaths.Count == 0)
			{
				return;
			}
			foreach (string selectedPath in selection.SelectedPaths)
			{
				try
				{
					if (File.Exists(selectedPath))
					{
						File.Delete(selectedPath);
					}
					else if (Directory.Exists(selectedPath))
					{
						Directory.Delete(selectedPath, recursive: true);
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("Failed to delete " + selectedPath + ": " + ex));
				}
			}
		}

		private static void Grab(FileSelectionModel selection, CopyAction action)
		{
			CopyBufferPaths = selection.SelectedPaths;
			GUIUtility.systemCopyBuffer = string.Join("\n", selection.SelectedPaths);
			CurrentAction = action;
		}
	}
	public enum CopyAction
	{
		Copy,
		Cut,
		None
	}
	public class NavigationHistory
	{
		private readonly List<string> _dirList = new List<string>();

		private int _currentIndex;

		public string CurrentPath
		{
			get
			{
				if (_currentIndex < 0 || _currentIndex >= _dirList.Count)
				{
					return null;
				}
				return _dirList[_currentIndex];
			}
		}

		public bool CanGoBack => _currentIndex > 0;

		public bool CanGoForward => _currentIndex < _dirList.Count - 1;

		public NavigationHistory(string initialPath)
		{
			if (string.IsNullOrEmpty(initialPath))
			{
				throw new ArgumentNullException("initialPath");
			}
			_dirList.Add(initialPath);
			_currentIndex = 0;
		}

		public NavigationHistory(NavigationHistory other)
		{
			if (other == null)
			{
				throw new ArgumentNullException("other");
			}
			_dirList = new List<string>(other._dirList);
			_currentIndex = other._currentIndex;
		}

		public bool NavigateTo(string newPath)
		{
			if (string.IsNullOrEmpty(newPath))
			{
				return false;
			}
			string text = Validations.ResolvePath(newPath);
			if (CurrentPath.Equals(text, StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			if (!Validations.Accessible(text))
			{
				return false;
			}
			if (_currentIndex < _dirList.Count - 1)
			{
				_dirList.RemoveRange(_currentIndex + 1, _dirList.Count - (_currentIndex + 1));
			}
			_dirList.Add(text);
			_currentIndex++;
			return true;
		}

		public string GoBack()
		{
			if (CanGoBack)
			{
				_currentIndex--;
			}
			return CurrentPath;
		}

		public string GoForward()
		{
			if (CanGoForward)
			{
				_currentIndex++;
			}
			return CurrentPath;
		}
	}
	public class FileSelectionModel
	{
		private readonly HashSet<string> _selectedPaths = new HashSet<string>(StringComparer.Ordinal);

		public IReadOnlyCollection<string> SelectedPaths => _selectedPaths;

		public int Count => _selectedPaths.Count;

		public int FocusedIndex { get; set; } = -1;

		public int AnchorIndex { get; set; } = -1;

		public event Action? SelectionChanged;

		public bool IsSelected(string path)
		{
			return _selectedPaths.Contains(path);
		}

		public FileSelectionModel()
		{
		}

		public FileSelectionModel(FileSelectionModel source)
		{
			_selectedPaths = new HashSet<string>(source._selectedPaths, StringComparer.Ordinal);
			FocusedIndex = source.FocusedIndex;
			AnchorIndex = source.AnchorIndex;
		}

		public void SelectOnly(string path, int index)
		{
			_selectedPaths.Clear();
			_selectedPaths.Add(path);
			FocusedIndex = index;
			AnchorIndex = index;
			this.SelectionChanged?.Invoke();
		}

		public void Toggle(string path, int index)
		{
			if (!_selectedPaths.Remove(path))
			{
				_selectedPaths.Add(path);
			}
			FocusedIndex = index;
			AnchorIndex = index;
			this.SelectionChanged?.Invoke();
		}

		public void SelectRange(IList<string> allPaths, int fromIndex, int toIndex)
		{
			int num = Math.Min(fromIndex, toIndex);
			int num2 = Math.Max(fromIndex, toIndex);
			_selectedPaths.Clear();
			for (int i = num; i <= num2; i++)
			{
				_selectedPaths.Add(allPaths[i]);
			}
			FocusedIndex = toIndex;
			this.SelectionChanged?.Invoke();
		}

		public void SelectAll(IEnumerable<string> paths)
		{
			_selectedPaths.Clear();
			foreach (string path in paths)
			{
				_selectedPaths.Add(path);
			}
			this.SelectionChanged?.Invoke();
		}

		public void Clear()
		{
			if (_selectedPaths.Count != 0 || FocusedIndex != -1)
			{
				_selectedPaths.Clear();
				FocusedIndex = -1;
				AnchorIndex = -1;
				this.SelectionChanged?.Invoke();
			}
		}
	}
	public class SortContext
	{
		public bool Reverse;

		public bool FoldersFirst;

		public SortContext(bool reverse = false)
		{
			Reverse = reverse;
			FoldersFirst = Config.SortFoldersBeforeFiles.Value;
		}
	}
	public abstract class SortStrategy
	{
		public abstract FileSystemInfo[] SortItems(FileSystemInfo[] items, SortContext context);

		protected static int CompareWithContext(FileSystemInfo x, FileSystemInfo y, SortContext context, Func<FileSystemInfo, FileSystemInfo, int> primaryComparison)
		{
			if (context.FoldersFirst)
			{
				bool flag = x is DirectoryInfo;
				bool flag2 = y is DirectoryInfo;
				if (flag && !flag2)
				{
					return -1;
				}
				if (!flag && flag2)
				{
					return 1;
				}
			}
			int num = primaryComparison(x, y);
			if (!context.Reverse)
			{
				return num;
			}
			return -num;
		}
	}
	public class Tab
	{
		private NavigationHistory _history;

		private SortStrategy _sortStrategy = new NameSortStrategy();

		private FileSelectionModel _selectionModel;

		public FileSelectionModel Selection => _selectionModel;

		public SortStrategy SortingStrategy
		{
			get
			{
				return _sortStrategy;
			}
			set
			{
				_sortStrategy = value;
			}
		}

		public string CurrentPath
		{
			get
			{
				return _history.CurrentPath;
			}
			set
			{
				string currentPath = _history.CurrentPath;
				if (_history.NavigateTo(value))
				{
					UpdateSelection(_history.CurrentPath, currentPath);
					this.CurrentPathChanged?.Invoke();
				}
			}
		}

		public bool CanGoBack => _history.CanGoBack;

		public bool CanGoForward => _history.CanGoForward;

		public event Action? CurrentPathChanged;

		public FileSystemInfo[] GetSortedItems(FileSystemInfo[] items)
		{
			return _sortStrategy.SortItems(items, new SortContext());
		}

		public string GoBack()
		{
			string result = _history.GoBack();
			Action? action = this.CurrentPathChanged;
			if (action != null)
			{
				action();
				return result;
			}
			return result;
		}

		public string GoForward()
		{
			string result = _history.GoForward();
			Action? action = this.CurrentPathChanged;
			if (action != null)
			{
				action();
				return result;
			}
			return result;
		}

		public Tab(string initialPath)
		{
			_history = new NavigationHistory(initialPath);
			_selectionModel = new FileSelectionModel();
		}

		public Tab(Tab source)
		{
			_history = source._history;
			_selectionModel = new FileSelectionModel(source.Selection);
		}

		private void UpdateSelection(string newPath, string oldPath)
		{
			DirectoryInfo directoryInfo = new DirectoryInfo(newPath);
			DirectoryInfo directoryInfo2 = new DirectoryInfo(oldPath);
			List<string> list = (from i in GetSortedItems(directoryInfo.GetFileSystemInfos())
				select i.FullName).ToList();
			if (list.Count != 0)
			{
				if (directoryInfo.FullName == (directoryInfo2.Parent?.FullName ?? ""))
				{
					int index = list.IndexOf(directoryInfo2.FullName);
					Selection.SelectOnly(directoryInfo2.FullName, index);
				}
				else if (list.Count > 0)
				{
					Selection.SelectOnly(list[0], 0);
				}
			}
		}
	}
	public static class TextUtils
	{
		private const char ReplacementChar = '\ufffd';

		public static string SanitizeForDisplay(string? input)
		{
			if (string.IsNullOrEmpty(input))
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder(input.Length);
			foreach (char c in input)
			{
				bool flag;
				switch (c)
				{
				case '‐':
				case '‑':
				case '‒':
				case '–':
				case '—':
				case '―':
				case '−':
					flag = true;
					break;
				default:
					flag = false;
					break;
				}
				if (flag)
				{
					stringBuilder.Append('-');
					continue;
				}
				UnicodeCategory unicodeCategory = char.GetUnicodeCategory(c);
				if (unicodeCategory != UnicodeCategory.Control && unicodeCategory != UnicodeCategory.OtherNotAssigned)
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.ToString();
		}
	}
	public static class Validations
	{
		public static bool Accessible(string path)
		{
			if (string.IsNullOrWhiteSpace(path))
			{
				return false;
			}
			try
			{
				string path2 = ResolvePath(path);
				if (File.Exists(path2))
				{
					using (File.Open(path2, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
					{
						return true;
					}
				}
				if (Directory.Exists(path2))
				{
					Directory.EnumerateFileSystemEntries(path2).FirstOrDefault();
					return true;
				}
				return false;
			}
			catch (UnauthorizedAccessException)
			{
				return false;
			}
			catch (IOException)
			{
				return false;
			}
			catch (Exception)
			{
				return false;
			}
		}

		public static string ResolvePath(string path)
		{
			if (string.IsNullOrWhiteSpace(path))
			{
				throw new ArgumentException("Path cannot be null or empty.", "path");
			}
			if (path.StartsWith("file://", StringComparison.OrdinalIgnoreCase) && Uri.TryCreate(path, UriKind.Absolute, out Uri result))
			{
				path = result.LocalPath;
			}
			if (path.StartsWith("~"))
			{
				string home = Paths.Home;
				if (path.Length == 1)
				{
					path = home;
				}
				else if (path[1] == '/' || path[1] == '\\')
				{
					path = Path.Combine(home, path.Substring(2));
				}
			}
			return Path.GetFullPath(path);
		}
	}
	public class Window
	{
		private List<Tab> _tabs;

		private int _currTabIndex;

		public IReadOnlyList<Tab> Tabs => _tabs;

		public int Count => Tabs.Count;

		public bool AllowMultiSelection { get; set; }

		public bool PickerMode { get; private set; }

		public bool IsSelectionFolder { get; private set; }

		public Tab CurrentTab
		{
			get
			{
				return _tabs[_currTabIndex];
			}
			set
			{
				_currTabIndex = _tabs.IndexOf(value);
				this.CurrentTabChanged?.Invoke();
				this.CurrentPathChanged?.Invoke();
			}
		}

		public int CurrentTabIndex
		{
			get
			{
				return _currTabIndex;
			}
			set
			{
				_currTabIndex = value;
				this.CurrentTabChanged?.Invoke();
				this.CurrentPathChanged?.Invoke();
			}
		}

		public string CurrentPath
		{
			get
			{
				return CurrentTab.CurrentPath;
			}
			set
			{
				CurrentTab.CurrentPath = value;
				this.CurrentPathChanged?.Invoke();
			}
		}

		public SortStrategy SortingStrategy
		{
			get
			{
				return CurrentTab.SortingStrategy;
			}
			set
			{
				CurrentTab.SortingStrategy = value;
			}
		}

		public bool CanGoBack => CurrentTab.CanGoBack;

		public bool CanGoForward => CurrentTab.CanGoForward;

		public bool CanGoUp => new DirectoryInfo(CurrentPath).Parent != null;

		public event Action? TabsChanged;

		public event Action? CurrentTabChanged;

		public event Action<Tab>? TabAdded;

		public event Action<Tab>? TabRemoved;

		public event Action? CurrentPathChanged;

		public event Action<string[]>? ItemsPicked;

		public FileSystemInfo[] GetCurrentDirItems()
		{
			FileSystemInfo[] currentDirItemsUnsorted = GetCurrentDirItemsUnsorted();
			return CurrentTab.GetSortedItems(currentDirItemsUnsorted);
		}

		public FileSystemInfo[] GetCurrentDirItemsUnsorted()
		{
			return new DirectoryInfo(CurrentPath).GetFileSystemInfos();
		}

		public string GoBack()
		{
			CurrentTab.GoBack();
			this.CurrentPathChanged?.Invoke();
			return CurrentPath;
		}

		public string GoForward()
		{
			CurrentTab.GoForward();
			this.CurrentPathChanged?.Invoke();
			return CurrentPath;
		}

		public string GoUp()
		{
			DirectoryInfo parent = new DirectoryInfo(CurrentPath).Parent;
			if (parent != null)
			{
				CurrentPath = parent.FullName;
			}
			return CurrentPath;
		}

		public Window(string initialPath, bool picker = false, bool allowMultiSelection = false, bool isSelectionFolder = false)
		{
			PickerMode = picker;
			AllowMultiSelection = allowMultiSelection;
			IsSelectionFolder = isSelectionFolder;
			Tab tab = new Tab(initialPath);
			_tabs = new List<Tab>(1) { tab };
			CurrentTabChanged += delegate
			{
				this.CurrentPathChanged?.Invoke();
			};
			this.TabsChanged?.Invoke();
			this.TabAdded?.Invoke(tab);
		}

		public Window(Window source)
		{
			PickerMode = source.PickerMode;
			AllowMultiSelection = source.AllowMultiSelection;
			_tabs = source._tabs.Select((Tab tab) => new Tab(tab)).ToList();
			CurrentTabChanged += delegate
			{
				this.CurrentPathChanged?.Invoke();
			};
			foreach (Tab tab in _tabs)
			{
				this.TabAdded?.Invoke(tab);
			}
			this.TabsChanged?.Invoke();
		}

		public Tab NewTab(string initialPath, bool switchTo = true)
		{
			Tab tab = new Tab(initialPath);
			_tabs.Add(tab);
			this.TabAdded?.Invoke(tab);
			this.TabsChanged?.Invoke();
			if (switchTo)
			{
				CurrentTab = tab;
				this.CurrentTabChanged?.Invoke();
			}
			return tab;
		}

		public Tab NewTab()
		{
			return NewTab(CurrentPath);
		}

		public void CloseTab(Tab tab)
		{
			_tabs.Remove(tab);
			if (Count > 0)
			{
				_currTabIndex = Math.Clamp(_currTabIndex, 0, _tabs.Count - 1);
				this.CurrentTabChanged?.Invoke();
			}
			this.TabRemoved?.Invoke(tab);
			this.TabsChanged?.Invoke();
		}

		public void CloseTab()
		{
			CloseTab(CurrentTab);
		}

		public void ActivateSelection()
		{
			FileSelectionModel selection = CurrentTab.Selection;
			if (selection.Count == 1)
			{
				string text = selection.SelectedPaths.First();
				if (Directory.Exists(text))
				{
					CurrentPath = text;
				}
				else if (PickerMode && !IsSelectionFolder)
				{
					PickSelection();
				}
				return;
			}
			bool flag = selection.SelectedPaths.Any(File.Exists);
			bool flag2 = selection.SelectedPaths.Any(Directory.Exists);
			bool flag3 = flag2 && !flag;
			bool flag4 = flag && !flag2;
			if (flag3)
			{
				foreach (string selectedPath in selection.SelectedPaths)
				{
					if (Directory.Exists(selectedPath))
					{
						NewTab(selectedPath);
					}
				}
				return;
			}
			if ((!PickerMode || AllowMultiSelection) && PickerMode && flag4 && !IsSelectionFolder)
			{
				PickSelection();
			}
		}

		public bool CanPickSelection()
		{
			IReadOnlyCollection<string> selectedPaths = CurrentTab.Selection.SelectedPaths;
			bool flag = selectedPaths.Any(File.Exists);
			bool flag2 = selectedPaths.Any(Directory.Exists);
			bool flag3 = flag2 && !flag;
			bool flag4 = flag && !flag2;
			if (!flag4 && !flag3)
			{
				return false;
			}
			if (selectedPaths.Count == 0)
			{
				return false;
			}
			if (selectedPaths.Count > 1 && !AllowMultiSelection)
			{
				return false;
			}
			if (flag4 && IsSelectionFolder)
			{
				return false;
			}
			if (flag3 && !IsSelectionFolder)
			{
				return false;
			}
			return true;
		}

		public void PickSelection()
		{
			if (CanPickSelection())
			{
				IReadOnlyCollection<string> readOnlyCollection = CurrentTab.Selection.SelectedPaths;
				if (readOnlyCollection.Count == 0)
				{
					readOnlyCollection = new <>z__ReadOnlySingleElementList<string>(CurrentPath);
				}
				this.ItemsPicked?.Invoke(readOnlyCollection.ToArray());
			}
		}
	}
}
namespace Fireman.Core.SortStrategies
{
	public class ExtensionSortStrategy : SortStrategy
	{
		public override FileSystemInfo[] SortItems(FileSystemInfo[] items, SortContext context)
		{
			Array.Sort(items, (FileSystemInfo x, FileSystemInfo y) => SortStrategy.CompareWithContext(x, y, context, delegate(FileSystemInfo a, FileSystemInfo b)
			{
				string? extension = Path.GetExtension(a.Name);
				string extension2 = Path.GetExtension(b.Name);
				int num = string.Compare(extension, extension2, StringComparison.OrdinalIgnoreCase);
				return (num != 0) ? num : string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase);
			}));
			return items;
		}
	}
	public class NameSortStrategy : SortStrategy
	{
		public override FileSystemInfo[] SortItems(FileSystemInfo[] items, SortContext context)
		{
			Array.Sort(items, (FileSystemInfo x, FileSystemInfo y) => SortStrategy.CompareWithContext(x, y, context, (FileSystemInfo a, FileSystemInfo b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase)));
			return items;
		}
	}
}