Decompiled source of VanillaInventoryPlus v1.0.1

BepInEx\plugins\VanillaInventoryPlus\VanillaInventoryPlus.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
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("VanillaInventoryPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ee94069e7ecc47ad74ebfc893ac760ee7342f633")]
[assembly: AssemblyProduct("VanillaInventoryPlus")]
[assembly: AssemblyTitle("VanillaInventoryPlus")]
[assembly: AssemblyVersion("1.0.0.0")]
internal sealed class ConfigurationManagerAttributes
{
	public int? Order;
}
namespace VanillaInventoryPlus;

internal static class NearbyStashButton
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static UnityAction <>9__1_0;

		internal void <Create>b__1_0()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				NearbyStashManager.Run(localPlayer);
			}
		}
	}

	private static Sprite _icon;

	internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize)
	{
		//IL_0060: 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)
		//IL_006b: Expected O, but got Unknown
		if ((Object)(object)_icon == (Object)null)
		{
			_icon = SpriteLoader.Load("stash_nearby.png");
		}
		ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_StashNearby", _icon, buttonWidth, buttonHeight, iconSize);
		((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners();
		ButtonClickedEvent onClick = toolbarButtonView.Button.onClick;
		object obj = <>c.<>9__1_0;
		if (obj == null)
		{
			UnityAction val = delegate
			{
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null))
				{
					NearbyStashManager.Run(localPlayer);
				}
			};
			<>c.<>9__1_0 = val;
			obj = (object)val;
		}
		((UnityEvent)onClick).AddListener((UnityAction)obj);
		TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_stash_nearby", "$vit_stash_nearby_desc", GetHotkeyText);
	}

	private unsafe static string GetHotkeyText()
	{
		//IL_0021: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		if (ModConfig.NearbyStashEnableHotkey == null || !ModConfig.NearbyStashEnableHotkey.Value || ModConfig.NearbyStashHotkey == null)
		{
			return null;
		}
		KeyboardShortcut value = ModConfig.NearbyStashHotkey.Value;
		if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
		{
			return null;
		}
		return ((object)(*(KeyboardShortcut*)(&value))/*cast due to .constrained prefix*/).ToString();
	}
}
internal static class PlayerSortNameButton
{
	private static Sprite _icon;

	internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		if ((Object)(object)_icon == (Object)null)
		{
			_icon = SpriteLoader.Load("sort_name.png");
		}
		ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_PlayerSortName", _icon, buttonWidth, buttonHeight, iconSize);
		((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners();
		((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick));
		TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_name", "$vit_sort_name_desc");
	}

	private static void OnClick()
	{
		InventoryGui instance = InventoryGui.instance;
		if (!((Object)(object)instance == (Object)null))
		{
			bool nextDirection = PlayerSortState.GetNextDirection(ContainerSortMode.Name, defaultAscending: true);
			PlayerInventorySorter.Sort(instance, ContainerSortMode.Name, nextDirection);
			PlayerSortState.Set(ContainerSortMode.Name, nextDirection);
		}
	}
}
internal static class PlayerSortTypeButton
{
	private static Sprite _icon;

	internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		if ((Object)(object)_icon == (Object)null)
		{
			_icon = SpriteLoader.Load("sort_type_thin.png");
		}
		ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_PlayerSortType", _icon, buttonWidth, buttonHeight, iconSize);
		((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners();
		((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick));
		TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_type", "$vit_sort_type_desc");
	}

	private static void OnClick()
	{
		InventoryGui instance = InventoryGui.instance;
		if (!((Object)(object)instance == (Object)null))
		{
			bool nextDirection = PlayerSortState.GetNextDirection(ContainerSortMode.Type, defaultAscending: true);
			PlayerInventorySorter.Sort(instance, ContainerSortMode.Type, nextDirection);
			PlayerSortState.Set(ContainerSortMode.Type, nextDirection);
		}
	}
}
internal static class PlayerSortWeightButton
{
	private static Sprite _icon;

	internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		if ((Object)(object)_icon == (Object)null)
		{
			_icon = SpriteLoader.Load("sort_weight.png");
		}
		ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_PlayerSortWeight", _icon, buttonWidth, buttonHeight, iconSize);
		((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners();
		((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick));
		TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_weight", "$vit_sort_weight_desc");
	}

	private static void OnClick()
	{
		InventoryGui instance = InventoryGui.instance;
		if (!((Object)(object)instance == (Object)null))
		{
			bool nextDirection = PlayerSortState.GetNextDirection(ContainerSortMode.Weight, defaultAscending: false);
			PlayerInventorySorter.Sort(instance, ContainerSortMode.Weight, nextDirection);
			PlayerSortState.Set(ContainerSortMode.Weight, nextDirection);
		}
	}
}
internal static class SortNameButton
{
	private static Sprite _icon;

	internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		if ((Object)(object)_icon == (Object)null)
		{
			_icon = SpriteLoader.Load("sort_name.png");
		}
		ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_SortName", _icon, buttonWidth, buttonHeight, iconSize);
		((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners();
		((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick));
		TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_name", "$vit_sort_name_desc");
	}

	private static void OnClick()
	{
		InventoryGui instance = InventoryGui.instance;
		if (!((Object)(object)instance == (Object)null))
		{
			bool nextDirection = SortState.GetNextDirection(ContainerSortMode.Name, defaultAscending: true);
			InventorySorter.SortOpenContainer(instance, ContainerSortMode.Name, nextDirection);
			SortState.Set(ContainerSortMode.Name, nextDirection);
		}
	}
}
internal static class SortTypeButton
{
	private static Sprite _icon;

	private static Sprite _thinIcon;

	internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize, bool useThinIcon)
	{
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Expected O, but got Unknown
		if ((Object)(object)_icon == (Object)null)
		{
			_icon = SpriteLoader.Load("sort_type.png");
		}
		if (useThinIcon && (Object)(object)_thinIcon == (Object)null)
		{
			_thinIcon = SpriteLoader.Load("sort_type_thin.png");
		}
		Sprite icon = ((useThinIcon && (Object)(object)_thinIcon != (Object)null) ? _thinIcon : _icon);
		ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_SortType", icon, buttonWidth, buttonHeight, iconSize);
		((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners();
		((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick));
		TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_type", "$vit_sort_type_desc");
	}

	private static void OnClick()
	{
		InventoryGui instance = InventoryGui.instance;
		if (!((Object)(object)instance == (Object)null))
		{
			bool nextDirection = SortState.GetNextDirection(ContainerSortMode.Type, defaultAscending: true);
			InventorySorter.SortOpenContainer(instance, ContainerSortMode.Type, nextDirection);
			SortState.Set(ContainerSortMode.Type, nextDirection);
		}
	}
}
internal static class SortWeightButton
{
	private static Sprite _icon;

	internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		if ((Object)(object)_icon == (Object)null)
		{
			_icon = SpriteLoader.Load("sort_weight.png");
		}
		ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_SortWeight", _icon, buttonWidth, buttonHeight, iconSize);
		((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners();
		((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick));
		TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_weight", "$vit_sort_weight_desc");
	}

	private static void OnClick()
	{
		InventoryGui instance = InventoryGui.instance;
		if (!((Object)(object)instance == (Object)null))
		{
			bool nextDirection = SortState.GetNextDirection(ContainerSortMode.Weight, defaultAscending: false);
			InventorySorter.SortOpenContainer(instance, ContainerSortMode.Weight, nextDirection);
			SortState.Set(ContainerSortMode.Weight, nextDirection);
		}
	}
}
internal static class StackAllButton
{
	private static Sprite _icon;

	private static Sprite _thinIcon;

	internal static void Create(Transform source, Transform parent, float buttonWidth, float buttonHeight, float iconSize, bool useThinIcon)
	{
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Expected O, but got Unknown
		if ((Object)(object)source == (Object)null || (Object)(object)parent == (Object)null)
		{
			return;
		}
		Button vanillaButton = ((Component)source).GetComponent<Button>();
		if (!((Object)(object)vanillaButton == (Object)null))
		{
			if ((Object)(object)_icon == (Object)null)
			{
				_icon = SpriteLoader.Load("stack.png");
			}
			if (useThinIcon && (Object)(object)_thinIcon == (Object)null)
			{
				_thinIcon = SpriteLoader.Load("stack_thin.png");
			}
			Sprite icon = ((useThinIcon && (Object)(object)_thinIcon != (Object)null) ? _thinIcon : _icon);
			ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(((Component)source).gameObject, parent, "VIT_StackAll", icon, buttonWidth, buttonHeight, iconSize);
			((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners();
			((UnityEvent)toolbarButtonView.Button.onClick).AddListener((UnityAction)delegate
			{
				((UnityEvent)vanillaButton.onClick).Invoke();
				CompactCurrentContainer();
				SortState.Clear();
			});
			TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_stack_all", "$vit_stack_all_desc");
			((Component)source).gameObject.SetActive(false);
		}
	}

	private static void CompactCurrentContainer()
	{
		InventoryGui instance = InventoryGui.instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		Container value = Traverse.Create((object)instance).Field<Container>("m_currentContainer").Value;
		if ((Object)(object)value == (Object)null)
		{
			return;
		}
		Inventory inventory = value.GetInventory();
		if (inventory == null)
		{
			return;
		}
		List<ItemData> list = new List<ItemData>(inventory.GetAllItems());
		bool flag = false;
		for (int i = 0; i < list.Count; i++)
		{
			ItemData val = list[i];
			if (val == null || val.m_shared == null)
			{
				continue;
			}
			int maxStackSize = val.m_shared.m_maxStackSize;
			if (maxStackSize <= 1 || val.m_stack >= maxStackSize)
			{
				continue;
			}
			for (int j = i + 1; j < list.Count; j++)
			{
				ItemData val2 = list[j];
				if (val2 == null || val2.m_shared == null || !CanStackTogether(val, val2))
				{
					continue;
				}
				int num = maxStackSize - val.m_stack;
				if (num <= 0)
				{
					break;
				}
				int num2 = Mathf.Min(num, val2.m_stack);
				if (num2 > 0)
				{
					val.m_stack += num2;
					val2.m_stack -= num2;
					flag = true;
					if (val2.m_stack <= 0)
					{
						inventory.RemoveItem(val2);
						list[j] = null;
					}
				}
			}
		}
		if (flag)
		{
			Traverse.Create((object)inventory).Method("Changed", new object[2] { true, false }).GetValue();
			Traverse.Create((object)value).Method("Save", Array.Empty<object>()).GetValue();
			Traverse.Create((object)instance).Method("UpdateContainer", Array.Empty<object>()).GetValue();
		}
	}

	private static bool CanStackTogether(ItemData first, ItemData second)
	{
		if (first == null || second == null || first.m_shared == null || second.m_shared == null)
		{
			return false;
		}
		if (first.m_shared.m_maxStackSize <= 1 || second.m_shared.m_maxStackSize <= 1)
		{
			return false;
		}
		if (first.m_shared.m_name == second.m_shared.m_name && first.m_quality == second.m_quality)
		{
			return first.m_variant == second.m_variant;
		}
		return false;
	}
}
internal static class TakeAllButton
{
	private static Sprite _icon;

	private const float BottomMargin = 12f;

	private const float IconPadding = 4f;

	internal static void Create(Transform originalTakeAll)
	{
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Expected O, but got Unknown
		if ((Object)(object)originalTakeAll == (Object)null)
		{
			return;
		}
		RectTransform component = ((Component)originalTakeAll).GetComponent<RectTransform>();
		Button vanillaButton = ((Component)originalTakeAll).GetComponent<Button>();
		if ((Object)(object)component == (Object)null || (Object)(object)vanillaButton == (Object)null)
		{
			return;
		}
		if ((Object)(object)_icon == (Object)null)
		{
			_icon = SpriteLoader.Load("take_all.png");
		}
		float width = GetWidth(component, 100f);
		float height = GetHeight(component, 30f);
		GameObject val = Object.Instantiate<GameObject>(((Component)originalTakeAll).gameObject, originalTakeAll.parent);
		((Object)val).name = "VIT_TakeAll";
		RectTransform component2 = val.GetComponent<RectTransform>();
		Button component3 = val.GetComponent<Button>();
		if ((Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null)
		{
			Object.Destroy((Object)(object)val);
			return;
		}
		component2.sizeDelta = new Vector2(width, height);
		LayoutElement component4 = val.GetComponent<LayoutElement>();
		if ((Object)(object)component4 != (Object)null)
		{
			component4.minWidth = width;
			component4.preferredWidth = width;
			component4.minHeight = height;
			component4.preferredHeight = height;
			component4.flexibleWidth = 0f;
			component4.flexibleHeight = 0f;
		}
		component2.anchorMin = new Vector2(0.5f, 0f);
		component2.anchorMax = new Vector2(0.5f, 0f);
		component2.pivot = new Vector2(0.5f, 1f);
		component2.anchoredPosition = new Vector2(0f, -12f);
		ApplyDisplayMode(val, width, height);
		((UnityEventBase)component3.onClick).RemoveAllListeners();
		((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
		{
			if ((Object)(object)vanillaButton != (Object)null)
			{
				((UnityEvent)vanillaButton.onClick).Invoke();
			}
			SortState.Clear();
		});
		TooltipUtility.Add(val, "$vit_take_all", "$vit_take_all_desc");
		val.transform.SetAsLastSibling();
		val.SetActive(true);
		((Component)originalTakeAll).gameObject.SetActive(false);
	}

	private static void ApplyDisplayMode(GameObject buttonObject, float buttonWidth, float buttonHeight)
	{
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		TakeAllDisplayMode value = ModConfig.TakeAllMode.Value;
		TMP_Text[] componentsInChildren = buttonObject.GetComponentsInChildren<TMP_Text>(true);
		TMP_Text[] array;
		if (value == TakeAllDisplayMode.Text)
		{
			array = componentsInChildren;
			for (int i = 0; i < array.Length; i++)
			{
				((Component)array[i]).gameObject.SetActive(true);
			}
			return;
		}
		array = componentsInChildren;
		for (int i = 0; i < array.Length; i++)
		{
			((Component)array[i]).gameObject.SetActive(false);
		}
		GameObject val = new GameObject("Icon", new Type[2]
		{
			typeof(RectTransform),
			typeof(Image)
		});
		val.transform.SetParent(buttonObject.transform, false);
		RectTransform component = val.GetComponent<RectTransform>();
		component.anchorMin = new Vector2(0.5f, 0.5f);
		component.anchorMax = new Vector2(0.5f, 0.5f);
		component.pivot = new Vector2(0.5f, 0.5f);
		component.anchoredPosition = Vector2.zero;
		float num = Mathf.Max(8f, buttonHeight - 4f);
		component.sizeDelta = new Vector2(num, num);
		Image component2 = val.GetComponent<Image>();
		component2.sprite = _icon;
		component2.preserveAspect = true;
		((Graphic)component2).raycastTarget = false;
		((Graphic)component2).color = ((ModConfig.IconColor != null) ? ModConfig.IconColor.Value : Color.white);
	}

	private static float GetWidth(RectTransform rect, float fallback)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)rect != (Object)null)
		{
			Rect rect2 = rect.rect;
			if (((Rect)(ref rect2)).width > 1f)
			{
				rect2 = rect.rect;
				return ((Rect)(ref rect2)).width;
			}
		}
		if ((Object)(object)rect != (Object)null && rect.sizeDelta.x > 1f)
		{
			return rect.sizeDelta.x;
		}
		return fallback;
	}

	private static float GetHeight(RectTransform rect, float fallback)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)rect != (Object)null)
		{
			Rect rect2 = rect.rect;
			if (((Rect)(ref rect2)).height > 1f)
			{
				rect2 = rect.rect;
				return ((Rect)(ref rect2)).height;
			}
		}
		if ((Object)(object)rect != (Object)null && rect.sizeDelta.y > 1f)
		{
			return rect.sizeDelta.y;
		}
		return fallback;
	}
}
internal static class ExtraSlotsCompatibility
{
	private const string ExtraSlotsGuid = "shudnal.ExtraSlots";

	private const string ExtraSlotsApiTypeName = "ExtraSlots.API";

	internal static bool TryGetRegularInventoryHeight(Inventory inventory, out int height)
	{
		height = 0;
		if (inventory == null)
		{
			return false;
		}
		int height2 = inventory.GetHeight();
		if (height2 <= 0)
		{
			return false;
		}
		if (!Chainloader.PluginInfos.TryGetValue("shudnal.ExtraSlots", out var value))
		{
			height = height2;
			return true;
		}
		if (value == null || (Object)(object)value.Instance == (Object)null)
		{
			LogCompatibilityFailure("plugin instance is unavailable");
			return false;
		}
		try
		{
			Type type = ((object)value.Instance).GetType().Assembly.GetType("ExtraSlots.API", throwOnError: false);
			if (type == null)
			{
				LogCompatibilityFailure("ExtraSlots.API was not found");
				return false;
			}
			MethodInfo method = type.GetMethod("GetInventoryHeightPlayer", BindingFlags.Static | BindingFlags.Public);
			if (method == null)
			{
				LogCompatibilityFailure("GetInventoryHeightPlayer() was not found");
				return false;
			}
			if (!(method.Invoke(null, null) is int num))
			{
				LogCompatibilityFailure("GetInventoryHeightPlayer() returned an unexpected value");
				return false;
			}
			if (num <= 0 || num > height2)
			{
				LogCompatibilityFailure("invalid player inventory height: " + num + " / full height: " + height2);
				return false;
			}
			height = num;
			return true;
		}
		catch (Exception ex)
		{
			LogCompatibilityFailure(ex.GetType().Name + ": " + ex.Message);
			return false;
		}
	}

	private static void LogCompatibilityFailure(string reason)
	{
		Plugin.Log.LogWarning((object)("Extra Slots compatibility: " + reason + ". Player inventory operation was skipped to protect extra-slot items."));
	}
}
[HarmonyPatch(typeof(InventoryGui), "Awake")]
internal static class InventoryGuiPatch
{
	[HarmonyPostfix]
	[HarmonyPriority(200)]
	private static void Postfix(InventoryGui __instance)
	{
		InventoryUiBuilder.Build(__instance);
	}
}
internal enum ContainerSortMode
{
	Name,
	Weight,
	Type
}
internal static class InventorySorter
{
	internal static void SortOpenContainer(InventoryGui gui, ContainerSortMode mode, bool ascending)
	{
		//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)gui == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Cannot sort: InventoryGui is null.");
				return;
			}
			Container value = Traverse.Create((object)gui).Field<Container>("m_currentContainer").Value;
			if ((Object)(object)value == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Cannot sort: no container is open.");
				return;
			}
			Inventory inventory = value.GetInventory();
			if (inventory == null)
			{
				Plugin.Log.LogWarning((object)"Cannot sort: container inventory is null.");
				return;
			}
			IEnumerable<ItemData> source = from item in inventory.GetAllItems()
				where item != null && item.m_shared != null
				select item;
			List<ItemData> list = mode switch
			{
				ContainerSortMode.Weight => (!ascending) ? source.OrderByDescending((ItemData item) => item.GetWeight(-1)).ThenBy<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ToList() : source.OrderBy((ItemData item) => item.GetWeight(-1)).ThenBy<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ToList(), 
				ContainerSortMode.Type => (!ascending) ? source.OrderByDescending<ItemData, string>(GetItemTypeName, StringComparer.OrdinalIgnoreCase).ThenBy<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ToList() : source.OrderBy<ItemData, string>(GetItemTypeName, StringComparer.OrdinalIgnoreCase).ThenBy<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ToList(), 
				_ => (!ascending) ? source.OrderByDescending<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ThenBy((ItemData item) => item.m_quality).ThenBy((ItemData item) => item.m_variant)
					.ToList() : source.OrderBy<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ThenBy((ItemData item) => item.m_quality).ThenBy((ItemData item) => item.m_variant)
					.ToList(), 
			};
			int width = inventory.GetWidth();
			if (width <= 0)
			{
				Plugin.Log.LogWarning((object)"Cannot sort: invalid inventory width.");
				return;
			}
			for (int num = 0; num < list.Count; num++)
			{
				int num2 = num % width;
				int num3 = num / width;
				list[num].m_gridPos = new Vector2i(num2, num3);
			}
			Traverse.Create((object)inventory).Method("Changed", new object[2] { true, false }).GetValue();
			Traverse.Create((object)value).Method("Save", Array.Empty<object>()).GetValue();
			Traverse.Create((object)gui).Method("UpdateContainer", new object[1] { Player.m_localPlayer }).GetValue();
			Plugin.Log.LogInfo((object)("Container sorted: " + mode.ToString() + " / " + (ascending ? "ascending" : "descending") + " / " + list.Count + " items."));
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)"Error while sorting container:");
			Plugin.Log.LogError((object)ex);
		}
	}

	private static string GetLocalizedName(ItemData item)
	{
		if (item == null || item.m_shared == null)
		{
			return "";
		}
		if (Localization.instance == null)
		{
			return item.m_shared.m_name ?? "";
		}
		return Localization.instance.Localize(item.m_shared.m_name);
	}

	private static string GetItemTypeName(ItemData item)
	{
		if (item == null || item.m_shared == null)
		{
			return "";
		}
		return ((object)Unsafe.As<ItemType, ItemType>(ref item.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString();
	}
}
internal static class InventoryUiBuilder
{
	private static bool _refreshPending;

	internal static void Build(InventoryGui gui)
	{
		if ((Object)(object)gui == (Object)null)
		{
			return;
		}
		Transform val = ((Component)gui).transform.Find("root/Player/Container");
		Transform val2 = ((Component)gui).transform.Find("root/Player");
		if ((Object)(object)val == (Object)null)
		{
			Plugin.Log.LogWarning((object)"Container UI was not found.");
			return;
		}
		Transform val3 = val.Find("StackAll");
		Transform val4 = val.Find("TakeAll");
		if ((Object)(object)val3 == (Object)null)
		{
			Plugin.Log.LogWarning((object)"Vanilla StackAll was not found.");
			return;
		}
		((Component)val3).gameObject.SetActive(true);
		if ((Object)(object)val4 != (Object)null)
		{
			((Component)val4).gameObject.SetActive(true);
		}
		float buttonHeight = GetButtonHeight(((Component)val3).GetComponent<RectTransform>(), 30f);
		float num = Mathf.Max(22f, buttonHeight - 4f);
		bool flag = ToolbarLayout.IsCompactHorizontalMode();
		float buttonWidth = buttonHeight;
		float num2 = (flag ? (buttonHeight * 0.65f) : buttonHeight);
		float iconSize = (flag ? Mathf.Max(9f, num2 - 2f) : num);
		int num3 = 0;
		if (ModConfig.ShowSortNameButton.Value)
		{
			num3++;
		}
		if (ModConfig.ShowSortWeightButton.Value)
		{
			num3++;
		}
		if (ModConfig.ShowSortTypeButton.Value)
		{
			num3++;
		}
		if (ModConfig.ShowStackAllButton.Value)
		{
			num3++;
		}
		if (num3 > 0)
		{
			Transform transform = ToolbarLayout.Create(val, num3, buttonWidth, num2).transform;
			if (ModConfig.ShowSortNameButton.Value)
			{
				SortNameButton.Create(((Component)val3).gameObject, transform, buttonWidth, num2, iconSize);
			}
			if (ModConfig.ShowSortWeightButton.Value)
			{
				SortWeightButton.Create(((Component)val3).gameObject, transform, buttonWidth, num2, iconSize);
			}
			if (ModConfig.ShowSortTypeButton.Value)
			{
				SortTypeButton.Create(((Component)val3).gameObject, transform, buttonWidth, num2, iconSize, flag);
			}
			if (ModConfig.ShowStackAllButton.Value)
			{
				StackAllButton.Create(val3, transform, buttonWidth, num2, iconSize, flag);
			}
		}
		if (ModConfig.ShowTakeAllButton.Value && (Object)(object)val4 != (Object)null)
		{
			TakeAllButton.Create(val4);
		}
		if ((Object)(object)val2 != (Object)null)
		{
			PlayerSortToolbarBuilder.Build(((Component)val3).gameObject, val2, buttonHeight);
		}
		ApplyVanillaButtonVisibility(val3, val4);
	}

	internal static void RequestRefresh()
	{
		InventoryGui instance = InventoryGui.instance;
		if (!((Object)(object)instance == (Object)null) && !_refreshPending)
		{
			_refreshPending = true;
			((MonoBehaviour)instance).StartCoroutine(RefreshNextFrame(instance));
		}
	}

	private static IEnumerator RefreshNextFrame(InventoryGui gui)
	{
		Cleanup(gui);
		yield return null;
		_refreshPending = false;
		if (!((Object)(object)gui == (Object)null))
		{
			Build(gui);
		}
	}

	private static void Cleanup(InventoryGui gui)
	{
		if ((Object)(object)gui == (Object)null)
		{
			return;
		}
		Transform val = ((Component)gui).transform.Find("root/Player/Container");
		Transform val2 = ((Component)gui).transform.Find("root/Player");
		if ((Object)(object)val != (Object)null)
		{
			Transform stackAll = val.Find("StackAll");
			Transform takeAll = val.Find("TakeAll");
			ApplyVanillaButtonVisibility(stackAll, takeAll);
			Transform val3 = val.Find("VIT_ContainerToolbar");
			if ((Object)(object)val3 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val3).gameObject);
			}
			Transform val4 = val.Find("VIT_TakeAll");
			if ((Object)(object)val4 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val4).gameObject);
			}
		}
		if ((Object)(object)val2 != (Object)null)
		{
			Transform val5 = val2.Find("VIT_PlayerSortToolbar");
			if ((Object)(object)val5 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val5).gameObject);
			}
		}
		TooltipManager.Hide();
	}

	private static void ApplyVanillaButtonVisibility(Transform stackAll, Transform takeAll)
	{
		bool flag = ModConfig.HideVanillaStackAllButton != null && ModConfig.HideVanillaStackAllButton.Value;
		bool flag2 = ModConfig.HideVanillaTakeAllButton != null && ModConfig.HideVanillaTakeAllButton.Value;
		if ((Object)(object)stackAll != (Object)null)
		{
			bool flag3 = ModConfig.ShowStackAllButton != null && ModConfig.ShowStackAllButton.Value;
			bool active = !flag && !flag3;
			((Component)stackAll).gameObject.SetActive(active);
		}
		if ((Object)(object)takeAll != (Object)null)
		{
			bool flag4 = ModConfig.ShowTakeAllButton != null && ModConfig.ShowTakeAllButton.Value;
			bool active2 = !flag2 && !flag4;
			((Component)takeAll).gameObject.SetActive(active2);
		}
	}

	private static float GetButtonHeight(RectTransform rect, float fallback)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)rect != (Object)null)
		{
			Rect rect2 = rect.rect;
			if (((Rect)(ref rect2)).height > 1f)
			{
				rect2 = rect.rect;
				return ((Rect)(ref rect2)).height;
			}
		}
		if ((Object)(object)rect != (Object)null && rect.sizeDelta.y > 1f)
		{
			return rect.sizeDelta.y;
		}
		return fallback;
	}
}
internal static class LocalizationManager
{
	private static readonly Dictionary<string, Dictionary<string, string>> _translations = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

	private static bool _loaded;

	internal static string Translate(string localizationKey)
	{
		EnsureLoaded();
		if (string.IsNullOrWhiteSpace(localizationKey))
		{
			return "";
		}
		string text = localizationKey.Trim();
		if (text.StartsWith("$"))
		{
			text = text.Substring(1);
		}
		if (!_translations.TryGetValue(text, out var value))
		{
			return localizationKey;
		}
		string currentLanguage = GetCurrentLanguage();
		if (value.TryGetValue(currentLanguage, out var value2) && !string.IsNullOrWhiteSpace(value2))
		{
			return value2;
		}
		if (value.TryGetValue("English", out var value3) && !string.IsNullOrWhiteSpace(value3))
		{
			return value3;
		}
		return localizationKey;
	}

	private static void EnsureLoaded()
	{
		if (_loaded)
		{
			return;
		}
		_loaded = true;
		using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("VanillaInventoryPlus.Resources.localization.tsv"))
		{
			if (stream == null)
			{
				Plugin.Log.LogError((object)"Localization resource not found: VanillaInventoryPlus.Resources.localization.tsv");
				return;
			}
			using StreamReader streamReader = new StreamReader(stream);
			string text = streamReader.ReadLine();
			if (string.IsNullOrWhiteSpace(text))
			{
				Plugin.Log.LogError((object)"Localization file is empty.");
				return;
			}
			string[] array = text.Split('\t');
			if (array.Length < 2)
			{
				Plugin.Log.LogError((object)"Localization TSV has invalid header.");
				return;
			}
			array[0] = array[0].Trim().Trim('\ufeff');
			string text2;
			while ((text2 = streamReader.ReadLine()) != null)
			{
				if (string.IsNullOrWhiteSpace(text2) || text2.TrimStart().StartsWith("#"))
				{
					continue;
				}
				string[] array2 = text2.Split('\t');
				if (array2.Length == 0)
				{
					continue;
				}
				string text3 = array2[0].Trim();
				if (string.IsNullOrWhiteSpace(text3))
				{
					continue;
				}
				if (text3.StartsWith("$"))
				{
					text3 = text3.Substring(1);
				}
				Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
				for (int i = 1; i < array.Length; i++)
				{
					string text4 = array[i].Trim();
					if (!string.IsNullOrWhiteSpace(text4))
					{
						string value = ((i < array2.Length) ? array2[i].Trim() : "");
						dictionary[text4] = value;
					}
				}
				_translations[text3] = dictionary;
			}
		}
		Plugin.Log.LogInfo((object)("Localization file loaded. " + _translations.Count + " keys."));
	}

	private static string GetCurrentLanguage()
	{
		try
		{
			if (Localization.instance == null)
			{
				return "English";
			}
			string value = Traverse.Create((object)Localization.instance).Method("GetSelectedLanguage", Array.Empty<object>()).GetValue<string>();
			if (string.IsNullOrWhiteSpace(value))
			{
				return "English";
			}
			return value;
		}
		catch
		{
			return "English";
		}
	}
}
internal enum ToolbarSide
{
	RightTop,
	LeftTop,
	LeftDown,
	DownLeft,
	DownRight
}
internal enum PlayerToolbarSide
{
	DownLeft,
	DownRight
}
internal enum TakeAllDisplayMode
{
	Icon,
	Text
}
internal static class ModConfig
{
	internal static ConfigEntry<Color> IconColor;

	internal static ConfigEntry<bool> HideVanillaStackAllButton;

	internal static ConfigEntry<bool> HideVanillaTakeAllButton;

	internal static ConfigEntry<bool> ShowSortNameButton;

	internal static ConfigEntry<bool> ShowSortWeightButton;

	internal static ConfigEntry<bool> ShowSortTypeButton;

	internal static ConfigEntry<bool> ShowStackAllButton;

	internal static ConfigEntry<bool> ShowTakeAllButton;

	internal static ConfigEntry<bool> ShowPlayerSortNameButton;

	internal static ConfigEntry<bool> ShowPlayerSortWeightButton;

	internal static ConfigEntry<bool> ShowPlayerSortTypeButton;

	internal static ConfigEntry<bool> ShowNearbyStashButton;

	internal static ConfigEntry<PlayerToolbarSide> PlayerInventoryToolbarSide;

	internal static ConfigEntry<TakeAllDisplayMode> TakeAllMode;

	internal static ConfigEntry<ToolbarSide> ContainerToolbarSide;

	internal static ConfigEntry<bool> ContainerToolbarSmallHorizontalButtons;

	internal static ConfigEntry<float> ContainerToolbarSpacing;

	internal static ConfigEntry<float> ContainerToolbarOffsetX;

	internal static ConfigEntry<float> ContainerToolbarOffsetY;

	internal static ConfigEntry<float> NearbyStashRadius;

	internal static ConfigEntry<bool> NearbyStashPlayerBuiltOnly;

	internal static ConfigEntry<bool> NearbyStashProtectHotbar;

	internal static ConfigEntry<bool> NearbyStashEnableHotkey;

	internal static ConfigEntry<KeyboardShortcut> NearbyStashHotkey;

	internal static void Bind(ConfigFile config)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Expected O, but got Unknown
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Expected O, but got Unknown
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Expected O, but got Unknown
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Expected O, but got Unknown
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Expected O, but got Unknown
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Expected O, but got Unknown
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Expected O, but got Unknown
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Expected O, but got Unknown
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: Expected O, but got Unknown
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Expected O, but got Unknown
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Expected O, but got Unknown
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e5: Expected O, but got Unknown
		//IL_0317: Unknown result type (might be due to invalid IL or missing references)
		//IL_0321: Expected O, but got Unknown
		//IL_0365: Unknown result type (might be due to invalid IL or missing references)
		//IL_036f: Expected O, but got Unknown
		//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bd: Expected O, but got Unknown
		//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fd: Expected O, but got Unknown
		//IL_042f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0439: Expected O, but got Unknown
		//IL_046b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0475: Expected O, but got Unknown
		//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b1: Expected O, but got Unknown
		//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0501: Expected O, but got Unknown
		//IL_0533: Unknown result type (might be due to invalid IL or missing references)
		//IL_053d: Expected O, but got Unknown
		//IL_056f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0579: Expected O, but got Unknown
		//IL_05bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_05c7: Expected O, but got Unknown
		//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0603: Expected O, but got Unknown
		IconColor = config.Bind<Color>("Appearance", "IconColor", Color32.op_Implicit(new Color32(byte.MaxValue, (byte)161, (byte)61, byte.MaxValue)), new ConfigDescription("Color tint for all custom icons.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 10
			}
		}));
		HideVanillaStackAllButton = config.Bind<bool>("Buttons", "HideVanillaStackAll", false, new ConfigDescription("Hide the original vanilla Stack All button.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 70
			}
		}));
		HideVanillaTakeAllButton = config.Bind<bool>("Buttons", "HideVanillaTakeAll", false, new ConfigDescription("Hide the original vanilla Take All button.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 60
			}
		}));
		ShowStackAllButton = config.Bind<bool>("Buttons", "ShowCustomStackAll", true, new ConfigDescription("Replace the vanilla Stack All button with the custom toolbar button.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 50
			}
		}));
		ShowTakeAllButton = config.Bind<bool>("Buttons", "ShowCustomTakeAll", true, new ConfigDescription("Replace the vanilla Take All button with the custom button.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 40
			}
		}));
		ShowSortNameButton = config.Bind<bool>("Buttons", "ShowSortName", true, new ConfigDescription("Show the Sort by Name button in the container toolbar.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 30
			}
		}));
		ShowSortTypeButton = config.Bind<bool>("Buttons", "ShowSortType", true, new ConfigDescription("Show the Sort by Type button in the container toolbar.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 20
			}
		}));
		ShowSortWeightButton = config.Bind<bool>("Buttons", "ShowSortWeight", true, new ConfigDescription("Show the Sort by Weight button in the container toolbar.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 10
			}
		}));
		ShowPlayerSortNameButton = config.Bind<bool>("Player Inventory Buttons", "ShowSortName", true, new ConfigDescription("Show the Sort by Name button in the player inventory.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 50
			}
		}));
		ShowPlayerSortWeightButton = config.Bind<bool>("Player Inventory Buttons", "ShowSortWeight", true, new ConfigDescription("Show the Sort by Weight button in the player inventory.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 40
			}
		}));
		ShowPlayerSortTypeButton = config.Bind<bool>("Player Inventory Buttons", "ShowSortType", true, new ConfigDescription("Show the Sort by Type button in the player inventory.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 30
			}
		}));
		ShowNearbyStashButton = config.Bind<bool>("Player Inventory Buttons", "ShowNearbyStash", true, new ConfigDescription("Show the Nearby Stash button in the player inventory.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 20
			}
		}));
		PlayerInventoryToolbarSide = config.Bind<PlayerToolbarSide>("Player Inventory Buttons", "Side", PlayerToolbarSide.DownRight, new ConfigDescription("Position of the player inventory toolbar.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 10
			}
		}));
		ContainerToolbarOffsetX = config.Bind<float>("Container Inventory Toolbar", "OffsetX", 0f, new ConfigDescription("Additional horizontal toolbar offset in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-80f, 80f), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 50
			}
		}));
		ContainerToolbarOffsetY = config.Bind<float>("Container Inventory Toolbar", "OffsetY", 0f, new ConfigDescription("Additional vertical toolbar offset in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-80f, 80f), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 40
			}
		}));
		ContainerToolbarSpacing = config.Bind<float>("Container Inventory Toolbar", "Spacing", 2f, new ConfigDescription("Distance between enabled toolbar buttons.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 30
			}
		}));
		ContainerToolbarSmallHorizontalButtons = config.Bind<bool>("Container Inventory Toolbar", "SmallHorizontalButtons", true, new ConfigDescription("Use compact rectangular buttons for DownLeft and DownRight positions only.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 20
			}
		}));
		ContainerToolbarSide = config.Bind<ToolbarSide>("Container Inventory Toolbar", "Side", ToolbarSide.DownRight, new ConfigDescription("Position of the container toolbar.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 10
			}
		}));
		NearbyStashEnableHotkey = config.Bind<bool>("Nearby Stash", "EnableHotkey", true, new ConfigDescription("Enable the hotkey for stashing matching items to nearby chests.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 50
			}
		}));
		NearbyStashHotkey = config.Bind<KeyboardShortcut>("Nearby Stash", "Hotkey", new KeyboardShortcut((KeyCode)115, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new ConfigDescription("Hotkey for stashing matching items to nearby chests.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 40
			}
		}));
		NearbyStashPlayerBuiltOnly = config.Bind<bool>("Nearby Stash", "PlayerBuiltOnly", true, new ConfigDescription("Only use chests placed by players.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 30
			}
		}));
		NearbyStashProtectHotbar = config.Bind<bool>("Nearby Stash", "ProtectHotbar", false, new ConfigDescription("When enabled, do not move items from the first inventory row.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 20
			}
		}));
		NearbyStashRadius = config.Bind<float>("Nearby Stash", "Radius", 10f, new ConfigDescription("Search radius for nearby chests in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 10
			}
		}));
		TakeAllMode = config.Bind<TakeAllDisplayMode>("Take All", "DisplayMode", TakeAllDisplayMode.Icon, new ConfigDescription("Display the custom Take All button as an icon or as vanilla text.", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 10
			}
		}));
		RegisterUiRefreshEvents();
	}

	private static void RegisterUiRefreshEvents()
	{
		IconColor.SettingChanged += OnUiSettingChanged;
		HideVanillaStackAllButton.SettingChanged += OnUiSettingChanged;
		HideVanillaTakeAllButton.SettingChanged += OnUiSettingChanged;
		ShowSortNameButton.SettingChanged += OnUiSettingChanged;
		ShowSortWeightButton.SettingChanged += OnUiSettingChanged;
		ShowSortTypeButton.SettingChanged += OnUiSettingChanged;
		ShowStackAllButton.SettingChanged += OnUiSettingChanged;
		ShowTakeAllButton.SettingChanged += OnUiSettingChanged;
		ShowPlayerSortNameButton.SettingChanged += OnUiSettingChanged;
		ShowPlayerSortWeightButton.SettingChanged += OnUiSettingChanged;
		ShowPlayerSortTypeButton.SettingChanged += OnUiSettingChanged;
		ShowNearbyStashButton.SettingChanged += OnUiSettingChanged;
		PlayerInventoryToolbarSide.SettingChanged += OnUiSettingChanged;
		ContainerToolbarSide.SettingChanged += OnUiSettingChanged;
		ContainerToolbarSpacing.SettingChanged += OnUiSettingChanged;
		ContainerToolbarSmallHorizontalButtons.SettingChanged += OnUiSettingChanged;
		ContainerToolbarOffsetX.SettingChanged += OnUiSettingChanged;
		ContainerToolbarOffsetY.SettingChanged += OnUiSettingChanged;
		TakeAllMode.SettingChanged += OnUiSettingChanged;
	}

	private static void OnUiSettingChanged(object sender, EventArgs args)
	{
		InventoryUiBuilder.RequestRefresh();
	}
}
internal static class NearbyStashManager
{
	private static Container _currentContainer;

	private static bool _running;

	private static bool _receivedResponse;

	private static int _movedItems;

	private const float ResponseTimeout = 2f;

	internal static void Run(Player player)
	{
		if (!((Object)(object)player == (Object)null) && !_running)
		{
			float radius = Mathf.Max(0.5f, ModConfig.NearbyStashRadius.Value);
			List<Container> list = FindNearbyContainers(player, radius);
			if (list.Count == 0)
			{
				ShowMessage(player, "$vit_stash_no_chests");
			}
			else
			{
				((MonoBehaviour)player).StartCoroutine(ProcessContainers(player, list));
			}
		}
	}

	private static List<Container> FindNearbyContainers(Player player, float radius)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		Vector3 playerPosition = ((Component)player).transform.position;
		Container[] array = Object.FindObjectsByType<Container>((FindObjectsInactive)0, (FindObjectsSortMode)0);
		List<Container> list = new List<Container>();
		Container[] array2 = array;
		foreach (Container val in array2)
		{
			if (IsValidContainer(val, player, playerPosition, radius))
			{
				list.Add(val);
			}
		}
		return list.OrderBy((Container container) => Vector3.SqrMagnitude(((Component)container).transform.position - playerPosition)).ToList();
	}

	private static bool IsValidContainer(Container container, Player player, Vector3 playerPosition, float radius)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)container == (Object)null || (Object)(object)((Component)container).transform == (Object)null)
		{
			return false;
		}
		if (Vector3.SqrMagnitude(((Component)container).transform.position - playerPosition) > radius * radius)
		{
			return false;
		}
		if (container.GetInventory() == null)
		{
			return false;
		}
		ZNetView nView = GetNView(container);
		if ((Object)(object)nView == (Object)null || !nView.IsValid())
		{
			return false;
		}
		if ((Object)(object)container.m_wagon != (Object)null)
		{
			return false;
		}
		if ((Object)(object)((Component)container).GetComponentInParent<Ship>() != (Object)null)
		{
			return false;
		}
		Piece componentInParent = ((Component)container).GetComponentInParent<Piece>();
		if ((Object)(object)componentInParent == (Object)null)
		{
			return false;
		}
		if (ModConfig.NearbyStashPlayerBuiltOnly.Value && !componentInParent.IsPlacedByPlayer())
		{
			return false;
		}
		if (container.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false))
		{
			return false;
		}
		try
		{
			if (!Traverse.Create((object)container).Method("CheckAccess", new object[1] { player.GetPlayerID() }).GetValue<bool>())
			{
				return false;
			}
		}
		catch
		{
			return false;
		}
		return true;
	}

	private static IEnumerator ProcessContainers(Player player, List<Container> containers)
	{
		_running = true;
		_movedItems = 0;
		foreach (Container container in containers)
		{
			if (!((Object)(object)container == (Object)null) && HasAnythingToStack(container, player))
			{
				_currentContainer = container;
				_receivedResponse = false;
				Plugin.Log.LogInfo((object)("Nearby stash: requesting " + ((Object)container).name));
				container.StackAll();
				float timer = 0f;
				while (!_receivedResponse && timer < 2f)
				{
					timer += Time.unscaledDeltaTime;
					yield return null;
				}
				if (!_receivedResponse)
				{
					Plugin.Log.LogWarning((object)("Nearby stash timeout: " + ((Object)container).name));
				}
				yield return null;
			}
		}
		_currentContainer = null;
		_running = false;
		if (_movedItems > 0)
		{
			string text = string.Format(LocalizationManager.Translate("$vit_stash_moved"), _movedItems);
			ShowRawMessage(player, text);
		}
		else
		{
			ShowMessage(player, "$vit_stash_nothing");
		}
	}

	private static bool HasAnythingToStack(Container container, Player player)
	{
		if ((Object)(object)container == (Object)null || (Object)(object)player == (Object)null)
		{
			return false;
		}
		Inventory inventory = container.GetInventory();
		if (inventory == null)
		{
			return false;
		}
		if (!TryGetPlayerInventoryArea(player, out var inventory2, out var width, out var regularHeight))
		{
			return false;
		}
		foreach (ItemData allItem in inventory2.GetAllItems())
		{
			if (CanMoveItem(allItem, player, width, regularHeight) && inventory.ContainsItemByName(allItem.m_shared.m_name))
			{
				return true;
			}
		}
		return false;
	}

	private static bool CanMoveItem(ItemData item, Player player, int inventoryWidth, int regularHeight)
	{
		if (item == null || item.m_shared == null)
		{
			return false;
		}
		int x = item.m_gridPos.x;
		int y = item.m_gridPos.y;
		if (x < 0 || x >= inventoryWidth || y < 0 || y >= regularHeight)
		{
			return false;
		}
		if ((Object)(object)player != (Object)null && ((Humanoid)player).IsItemEquiped(item))
		{
			return false;
		}
		if (ModConfig.NearbyStashProtectHotbar.Value && y == 0)
		{
			return false;
		}
		return true;
	}

	private static bool TryGetPlayerInventoryArea(Player player, out Inventory inventory, out int width, out int regularHeight)
	{
		inventory = null;
		width = 0;
		regularHeight = 0;
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		inventory = ((Humanoid)player).GetInventory();
		if (inventory == null)
		{
			return false;
		}
		width = inventory.GetWidth();
		if (width <= 0)
		{
			return false;
		}
		if (!ExtraSlotsCompatibility.TryGetRegularInventoryHeight(inventory, out regularHeight))
		{
			return false;
		}
		if (regularHeight <= 0)
		{
			return false;
		}
		return true;
	}

	internal static bool IsCurrentRequest(Container container)
	{
		if (_running && (Object)(object)_currentContainer != (Object)null)
		{
			return (Object)(object)container == (Object)(object)_currentContainer;
		}
		return false;
	}

	internal static bool TryHandleStackResponse(Container container, bool granted)
	{
		if (!IsCurrentRequest(container))
		{
			return false;
		}
		try
		{
			if (!granted)
			{
				Plugin.Log.LogInfo((object)("Nearby stash denied: " + ((Object)container).name));
				return true;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return true;
			}
			ZNetView nView = GetNView(container);
			if ((Object)(object)nView == (Object)null || !nView.IsValid())
			{
				Plugin.Log.LogWarning((object)("Nearby stash: invalid ZNetView for " + ((Object)container).name));
				return true;
			}
			if (!nView.IsOwner())
			{
				nView.ClaimOwnership();
			}
			if (!nView.IsOwner())
			{
				Plugin.Log.LogWarning((object)("Nearby stash: ownership failed for " + ((Object)container).name));
				return true;
			}
			int num = StackMatching(container, localPlayer);
			if (num > 0)
			{
				_movedItems += num;
				Plugin.Log.LogInfo((object)("Nearby stash: moved " + num + " to " + ((Object)container).name));
			}
			return true;
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Nearby stash response failed for " + ((Object)container).name + ": " + ex));
			return true;
		}
		finally
		{
			_receivedResponse = true;
		}
	}

	private static int StackMatching(Container container, Player player)
	{
		if ((Object)(object)container == (Object)null || (Object)(object)player == (Object)null)
		{
			return 0;
		}
		ZNetView nView = GetNView(container);
		if ((Object)(object)nView == (Object)null || !nView.IsValid() || !nView.IsOwner())
		{
			return 0;
		}
		Inventory inventory = container.GetInventory();
		if (inventory == null)
		{
			return 0;
		}
		if (!TryGetPlayerInventoryArea(player, out var inventory2, out var width, out var regularHeight))
		{
			return 0;
		}
		List<ItemData> list = new List<ItemData>(inventory2.GetAllItems());
		int num = 0;
		foreach (ItemData item in list)
		{
			if (CanMoveItem(item, player, width, regularHeight) && inventory.ContainsItemByName(item.m_shared.m_name))
			{
				int stack = item.m_stack;
				int num2;
				if (inventory.AddItem(item))
				{
					inventory2.RemoveItem(item);
					num2 = stack;
				}
				else
				{
					num2 = stack - item.m_stack;
				}
				if (num2 > 0)
				{
					num += num2;
				}
			}
		}
		if (num <= 0)
		{
			return 0;
		}
		MarkInventoryChanged(inventory);
		MarkInventoryChanged(inventory2);
		SaveContainer(container);
		return num;
	}

	private static ZNetView GetNView(Container container)
	{
		if ((Object)(object)container == (Object)null)
		{
			return null;
		}
		try
		{
			ZNetView value = Traverse.Create((object)container).Field<ZNetView>("m_nview").Value;
			if ((Object)(object)value != (Object)null)
			{
				return value;
			}
		}
		catch
		{
		}
		return ((Component)container).GetComponent<ZNetView>();
	}

	private static void MarkInventoryChanged(Inventory inventory)
	{
		if (inventory != null)
		{
			Traverse.Create((object)inventory).Method("Changed", new object[2] { false, false }).GetValue();
		}
	}

	private static void SaveContainer(Container container)
	{
		if (!((Object)(object)container == (Object)null))
		{
			Traverse.Create((object)container).Method("Save", Array.Empty<object>()).GetValue();
		}
	}

	private static void ShowMessage(Player player, string key)
	{
		ShowRawMessage(player, LocalizationManager.Translate(key));
	}

	private static void ShowRawMessage(Player player, string text)
	{
		if (!((Object)(object)player == (Object)null) && !string.IsNullOrWhiteSpace(text))
		{
			((Character)player).Message((MessageType)2, text, 0, (Sprite)null, false);
		}
	}
}
[HarmonyPatch(typeof(Container), "RPC_StackResponse")]
internal static class ContainerStackResponsePatch
{
	[HarmonyPrefix]
	private static bool Prefix(Container __instance, bool granted)
	{
		if (!NearbyStashManager.TryHandleStackResponse(__instance, granted))
		{
			return true;
		}
		return false;
	}
}
internal static class PlayerInventorySorter
{
	internal static void Sort(InventoryGui gui, ContainerSortMode mode, bool ascending)
	{
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)gui == (Object)null)
		{
			return;
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return;
		}
		Inventory inventory = ((Humanoid)localPlayer).GetInventory();
		if (inventory == null)
		{
			return;
		}
		int width = inventory.GetWidth();
		if (width <= 0 || !ExtraSlotsCompatibility.TryGetRegularInventoryHeight(inventory, out var regularHeight) || regularHeight <= 1)
		{
			return;
		}
		List<ItemData> list = new List<ItemData>(inventory.GetAllItems());
		List<ItemData> list2 = list.Where((ItemData item) => IsInsideSortableArea(item, width, regularHeight)).ToList();
		if (list2.Count == 0)
		{
			return;
		}
		List<Vector2i> list3 = BuildAvailableSlots(list, list2, width, regularHeight);
		if (list3.Count < list2.Count)
		{
			Plugin.Log.LogWarning((object)"Player inventory sorting aborted: not enough regular inventory cells.");
			return;
		}
		CompactStacks(inventory, list2);
		List<ItemData> list4 = (mode switch
		{
			ContainerSortMode.Weight => ascending ? list2.OrderBy((ItemData item) => item.GetWeight(-1)).ThenBy(GetLocalizedName) : list2.OrderByDescending((ItemData item) => item.GetWeight(-1)).ThenBy(GetLocalizedName), 
			ContainerSortMode.Type => ascending ? list2.OrderBy(GetItemType).ThenBy(GetLocalizedName) : list2.OrderByDescending(GetItemType).ThenBy(GetLocalizedName), 
			_ => ascending ? list2.OrderBy(GetLocalizedName).ThenBy((ItemData item) => item.m_quality).ThenBy((ItemData item) => item.m_variant) : list2.OrderByDescending(GetLocalizedName).ThenBy((ItemData item) => item.m_quality).ThenBy((ItemData item) => item.m_variant), 
		}).ToList();
		for (int num = 0; num < list4.Count; num++)
		{
			list4[num].m_gridPos = list3[num];
		}
		Traverse.Create((object)inventory).Method("Changed", new object[2] { true, false }).GetValue();
		Traverse.Create((object)gui).Method("UpdateInventory", new object[1] { localPlayer }).GetValue();
	}

	private static bool IsInsideSortableArea(ItemData item, int width, int regularHeight)
	{
		if (item == null || item.m_shared == null)
		{
			return false;
		}
		int x = item.m_gridPos.x;
		int y = item.m_gridPos.y;
		if (x < 0 || x >= width)
		{
			return false;
		}
		if (y <= 0)
		{
			return false;
		}
		if (y >= regularHeight)
		{
			return false;
		}
		return true;
	}

	private static List<Vector2i> BuildAvailableSlots(List<ItemData> allItems, List<ItemData> sortableItems, int width, int regularHeight)
	{
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		HashSet<ItemData> hashSet = new HashSet<ItemData>(sortableItems);
		HashSet<int> hashSet2 = new HashSet<int>();
		foreach (ItemData allItem in allItems)
		{
			if (allItem != null && !hashSet.Contains(allItem))
			{
				int x = allItem.m_gridPos.x;
				int y = allItem.m_gridPos.y;
				if (x >= 0 && x < width && y > 0 && y < regularHeight)
				{
					int item = y * width + x;
					hashSet2.Add(item);
				}
			}
		}
		List<Vector2i> list = new List<Vector2i>();
		for (int i = 1; i < regularHeight; i++)
		{
			for (int j = 0; j < width; j++)
			{
				int item2 = i * width + j;
				if (!hashSet2.Contains(item2))
				{
					list.Add(new Vector2i(j, i));
				}
			}
		}
		return list;
	}

	private static void CompactStacks(Inventory inventory, List<ItemData> items)
	{
		if (inventory == null || items == null || items.Count == 0)
		{
			return;
		}
		for (int i = 0; i < items.Count; i++)
		{
			ItemData val = items[i];
			if (val == null || val.m_shared == null)
			{
				continue;
			}
			int maxStackSize = val.m_shared.m_maxStackSize;
			if (maxStackSize <= 1 || val.m_stack >= maxStackSize)
			{
				continue;
			}
			for (int j = i + 1; j < items.Count; j++)
			{
				ItemData val2 = items[j];
				if (!CanStackTogether(val, val2))
				{
					continue;
				}
				int num = maxStackSize - val.m_stack;
				if (num <= 0)
				{
					break;
				}
				int num2 = Math.Min(num, val2.m_stack);
				if (num2 > 0)
				{
					val.m_stack += num2;
					val2.m_stack -= num2;
					if (val2.m_stack <= 0)
					{
						inventory.RemoveItem(val2);
						items.RemoveAt(j);
						j--;
					}
				}
			}
		}
	}

	private static bool CanStackTogether(ItemData first, ItemData second)
	{
		if (first == null || second == null || first.m_shared == null || second.m_shared == null)
		{
			return false;
		}
		if (first.m_shared.m_maxStackSize <= 1 || second.m_shared.m_maxStackSize <= 1)
		{
			return false;
		}
		if (first.m_shared.m_name == second.m_shared.m_name && first.m_quality == second.m_quality && first.m_variant == second.m_variant)
		{
			return first.m_shared.m_maxStackSize == second.m_shared.m_maxStackSize;
		}
		return false;
	}

	private static string GetLocalizedName(ItemData item)
	{
		if (item == null || item.m_shared == null)
		{
			return "";
		}
		if (Localization.instance == null)
		{
			return item.m_shared.m_name ?? "";
		}
		return Localization.instance.Localize(item.m_shared.m_name);
	}

	private static string GetItemType(ItemData item)
	{
		if (item == null || item.m_shared == null)
		{
			return "";
		}
		return ((object)Unsafe.As<ItemType, ItemType>(ref item.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString();
	}
}
internal static class PlayerSortState
{
	private static ContainerSortMode? _activeMode;

	private static bool _ascending;

	internal static bool GetNextDirection(ContainerSortMode mode, bool defaultAscending)
	{
		if (_activeMode == mode)
		{
			return !_ascending;
		}
		return defaultAscending;
	}

	internal static void Set(ContainerSortMode mode, bool ascending)
	{
		_activeMode = mode;
		_ascending = ascending;
	}

	internal static void Clear()
	{
		_activeMode = null;
	}
}
internal static class PlayerSortToolbarBuilder
{
	private const float Spacing = 2f;

	internal static void Build(GameObject buttonTemplate, Transform playerTransform, float standardButtonSize)
	{
		if ((Object)(object)buttonTemplate == (Object)null || (Object)(object)playerTransform == (Object)null)
		{
			return;
		}
		bool flag = ModConfig.ShowPlayerSortNameButton != null && ModConfig.ShowPlayerSortNameButton.Value;
		bool flag2 = ModConfig.ShowPlayerSortWeightButton != null && ModConfig.ShowPlayerSortWeightButton.Value;
		bool flag3 = ModConfig.ShowPlayerSortTypeButton != null && ModConfig.ShowPlayerSortTypeButton.Value;
		bool flag4 = ModConfig.ShowNearbyStashButton != null && ModConfig.ShowNearbyStashButton.Value;
		int num = 0;
		if (flag)
		{
			num++;
		}
		if (flag2)
		{
			num++;
		}
		if (flag3)
		{
			num++;
		}
		if (flag4)
		{
			num++;
		}
		if (num != 0)
		{
			float num2 = standardButtonSize * 0.65f;
			float iconSize = Mathf.Max(9f, num2 - 2f);
			float totalWidth = standardButtonSize * (float)num + 2f * (float)(num - 1);
			Transform transform = PlayerSortToolbarLayout.Create(playerTransform, totalWidth, num2, 2f).transform;
			if (flag)
			{
				PlayerSortNameButton.Create(buttonTemplate, transform, standardButtonSize, num2, iconSize);
			}
			if (flag2)
			{
				PlayerSortWeightButton.Create(buttonTemplate, transform, standardButtonSize, num2, iconSize);
			}
			if (flag3)
			{
				PlayerSortTypeButton.Create(buttonTemplate, transform, standardButtonSize, num2, iconSize);
			}
			if (flag4)
			{
				NearbyStashButton.Create(buttonTemplate, transform, standardButtonSize, num2, iconSize);
			}
		}
	}
}
[BepInPlugin("dellarion.valheim.vanillainventoryplus", "Vanilla Inventory Plus", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "dellarion.valheim.vanillainventoryplus";

	public const string PluginName = "Vanilla Inventory Plus";

	public const string PluginVersion = "1.0.1";

	internal static ManualLogSource Log;

	private Harmony _harmony;

	private void Awake()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		ModConfig.Bind(((BaseUnityPlugin)this).Config);
		_harmony = new Harmony("dellarion.valheim.vanillainventoryplus");
		_harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Vanilla Inventory Plus 1.0.1 loaded!");
	}

	private void Update()
	{
		//IL_0021: 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)
		if (ModConfig.NearbyStashEnableHotkey == null || ModConfig.NearbyStashHotkey == null || !ModConfig.NearbyStashEnableHotkey.Value)
		{
			return;
		}
		KeyboardShortcut value = ModConfig.NearbyStashHotkey.Value;
		if (((KeyboardShortcut)(ref value)).IsDown())
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				NearbyStashManager.Run(localPlayer);
			}
		}
	}

	private void OnDestroy()
	{
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}
}
internal static class SortState
{
	private static ContainerSortMode? _activeMode;

	private static bool _ascending;

	internal static bool GetNextDirection(ContainerSortMode mode, bool defaultAscending)
	{
		if (_activeMode == mode)
		{
			return !_ascending;
		}
		return defaultAscending;
	}

	internal static void Set(ContainerSortMode mode, bool ascending)
	{
		_activeMode = mode;
		_ascending = ascending;
	}

	internal static void Clear()
	{
		_activeMode = null;
	}
}
internal static class SpriteLoader
{
	internal static Sprite Load(string fileName)
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Expected O, but got Unknown
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		string text = "VanillaInventoryPlus.Resources." + fileName;
		using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text);
		if (stream == null)
		{
			Plugin.Log.LogError((object)("Icon resource not found: " + text));
			return null;
		}
		byte[] array;
		using (BinaryReader binaryReader = new BinaryReader(stream))
		{
			array = binaryReader.ReadBytes((int)stream.Length);
		}
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
		((Object)val).name = fileName;
		if (!ImageConversion.LoadImage(val, array, false))
		{
			Plugin.Log.LogError((object)("Failed to load icon: " + fileName));
			Object.Destroy((Object)(object)val);
			return null;
		}
		((Texture)val).filterMode = (FilterMode)1;
		((Texture)val).wrapMode = (TextureWrapMode)1;
		Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		((Object)obj).name = fileName;
		return obj;
	}
}
internal static class TooltipManager
{
	private const float CursorOffsetX = 18f;

	private const float CursorOffsetY = -18f;

	private const float MaxWidth = 360f;

	private const float MinWidth = 120f;

	private const float PaddingX = 12f;

	private const float PaddingY = 8f;

	private const float LineSpacing = 4f;

	private const float MinBodyFontSize = 16f;

	private const float MinHotkeyFontSize = 14f;

	private static readonly Color TitleColor = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)161, (byte)61, byte.MaxValue));

	private static GameObject _root;

	private static RectTransform _rect;

	private static Canvas _canvas;

	private static RectTransform _canvasRect;

	private static TMP_Text _titleText;

	private static TMP_Text _bodyText;

	private static TMP_Text _hotkeyText;

	internal static void EnsureExists(GameObject source, TMP_Text template)
	{
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)source == (Object)null)
		{
			return;
		}
		Canvas componentInParent = source.GetComponentInParent<Canvas>();
		if ((Object)(object)componentInParent == (Object)null)
		{
			return;
		}
		if ((Object)(object)_root != (Object)null && (Object)(object)_canvas == (Object)(object)componentInParent)
		{
			ApplyTextStyle(template);
			return;
		}
		if ((Object)(object)_root != (Object)null)
		{
			Object.Destroy((Object)(object)_root);
		}
		_canvas = componentInParent;
		Transform transform = ((Component)componentInParent).transform;
		_canvasRect = (RectTransform)(object)((transform is RectTransform) ? transform : null);
		_root = new GameObject("VIT_Tooltip", new Type[3]
		{
			typeof(RectTransform),
			typeof(Image),
			typeof(TooltipCursorFollower)
		});
		_root.transform.SetParent(((Component)componentInParent).transform, false);
		_rect = _root.GetComponent<RectTransform>();
		_rect.anchorMin = new Vector2(0.5f, 0.5f);
		_rect.anchorMax = new Vector2(0.5f, 0.5f);
		_rect.pivot = new Vector2(0f, 1f);
		Image component = _root.GetComponent<Image>();
		((Graphic)component).color = new Color(0.05f, 0.05f, 0.05f, 0.96f);
		((Graphic)component).raycastTarget = false;
		_titleText = CreateText("Title");
		_bodyText = CreateText("Body");
		_hotkeyText = CreateText("Hotkey");
		ApplyTextStyle(template);
		_root.SetActive(false);
	}

	internal static void Show(string localizationKey)
	{
		Show(localizationKey, null, null);
	}

	internal static void Show(string titleKey, string descriptionKey, string hotkey)
	{
		if (!((Object)(object)_root == (Object)null))
		{
			string text = Translate(titleKey);
			string text2 = Translate(descriptionKey);
			string text3 = string.Empty;
			if (!string.IsNullOrWhiteSpace(hotkey))
			{
				string text4 = Translate("$vit_hotkey");
				text3 = "\n" + text4 + ": <color=#FFA13D>" + hotkey + "</color>";
			}
			_titleText.text = text;
			_bodyText.text = text2;
			_hotkeyText.text = text3;
			((Component)_titleText).gameObject.SetActive(!string.IsNullOrWhiteSpace(text));
			((Component)_bodyText).gameObject.SetActive(!string.IsNullOrWhiteSpace(text2));
			((Component)_hotkeyText).gameObject.SetActive(!string.IsNullOrWhiteSpace(text3));
			_root.SetActive(true);
			_root.transform.SetAsLastSibling();
			RebuildLayout();
			UpdatePosition();
		}
	}

	internal static void Hide()
	{
		if ((Object)(object)_root != (Object)null)
		{
			_root.SetActive(false);
		}
	}

	internal static void UpdatePosition()
	{
		//IL_0039: 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)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_root == (Object)null) && _root.activeSelf && !((Object)(object)_rect == (Object)null) && !((Object)(object)_canvasRect == (Object)null))
		{
			Camera val = (((int)_canvas.renderMode == 0) ? null : _canvas.worldCamera);
			Vector2 val2 = default(Vector2);
			if (RectTransformUtility.ScreenPointToLocalPointInRectangle(_canvasRect, Vector2.op_Implicit(Input.mousePosition), val, ref val2))
			{
				Vector2 val3 = val2 + new Vector2(18f, -18f);
				Rect rect = _canvasRect.rect;
				float x = _rect.sizeDelta.x;
				float y = _rect.sizeDelta.y;
				val3.x = Mathf.Clamp(val3.x, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).xMax - x);
				val3.y = Mathf.Clamp(val3.y, ((Rect)(ref rect)).yMin + y, ((Rect)(ref rect)).yMax);
				_rect.anchoredPosition = val3;
			}
		}
	}

	private static TMP_Text CreateText(string objectName)
	{
		//IL_0021: 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)
		GameObject val = new GameObject(objectName, new Type[2]
		{
			typeof(RectTransform),
			typeof(TextMeshProUGUI)
		});
		val.transform.SetParent(_root.transform, false);
		TMP_Text component = val.GetComponent<TMP_Text>();
		component.alignment = (TextAlignmentOptions)257;
		component.textWrappingMode = (TextWrappingModes)1;
		component.overflowMode = (TextOverflowModes)0;
		((Graphic)component).raycastTarget = false;
		component.richText = true;
		return component;
	}

	private static void ApplyTextStyle(TMP_Text template)
	{
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		float num = 16f;
		if ((Object)(object)template != (Object)null)
		{
			if ((Object)(object)template.font != (Object)null)
			{
				_titleText.font = template.font;
				_bodyText.font = template.font;
				_hotkeyText.font = template.font;
			}
			num = Mathf.Max(16f, template.fontSize);
		}
		_titleText.fontSize = num + 1f;
		_titleText.fontStyle = (FontStyles)1;
		((Graphic)_titleText).color = TitleColor;
		_bodyText.fontSize = num;
		_bodyText.fontStyle = (FontStyles)0;
		((Graphic)_bodyText).color = Color.white;
		_hotkeyText.fontSize = Mathf.Max(14f, num - 1f);
		_hotkeyText.fontStyle = (FontStyles)0;
		((Graphic)_hotkeyText).color = Color.white;
	}

	private static void RebuildLayout()
	{
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		float num = 336f;
		float num2 = 96f;
		num2 = Mathf.Max(num2, GetPreferredWidth(_titleText, num));
		num2 = Mathf.Max(num2, GetPreferredWidth(_bodyText, num));
		num2 = Mathf.Max(num2, GetPreferredWidth(_hotkeyText, num));
		num2 = Mathf.Min(num2, num);
		float preferredHeight = GetPreferredHeight(_titleText, num2);
		float preferredHeight2 = GetPreferredHeight(_bodyText, num2);
		float preferredHeight3 = GetPreferredHeight(_hotkeyText, num2);
		int num3 = 0;
		if (((Component)_titleText).gameObject.activeSelf)
		{
			num3++;
		}
		if (((Component)_bodyText).gameObject.activeSelf)
		{
			num3++;
		}
		if (((Component)_hotkeyText).gameObject.activeSelf)
		{
			num3++;
		}
		float num4 = (float)Mathf.Max(0, num3 - 1) * 4f;
		float num5 = 16f + preferredHeight + preferredHeight2 + preferredHeight3 + num4;
		_rect.sizeDelta = new Vector2(num2 + 24f, num5);
		float y = -8f;
		PositionText(_titleText, num2, preferredHeight, ref y);
		PositionText(_bodyText, num2, preferredHeight2, ref y);
		PositionText(_hotkeyText, num2, preferredHeight3, ref y);
	}

	private static void PositionText(TMP_Text text, float width, float height, ref float y)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)text == (Object)null) && ((Component)text).gameObject.activeSelf)
		{
			RectTransform rectTransform = text.rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(0f, 1f);
			rectTransform.pivot = new Vector2(0f, 1f);
			rectTransform.anchoredPosition = new Vector2(12f, y);
			rectTransform.sizeDelta = new Vector2(width, height);
			y -= height + 4f;
		}
	}

	private static float GetPreferredWidth(TMP_Text text, float maxWidth)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)text == (Object)null || !((Component)text).gameObject.activeSelf)
		{
			return 0f;
		}
		return text.GetPreferredValues(text.text, maxWidth, 0f).x;
	}

	private static float GetPreferredHeight(TMP_Text text, float width)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)text == (Object)null || !((Component)text).gameObject.activeSelf)
		{
			return 0f;
		}
		return text.GetPreferredValues(text.text, width, 0f).y;
	}

	private static string Translate(string localizationKey)
	{
		if (string.IsNullOrWhiteSpace(localizationKey))
		{
			return string.Empty;
		}
		return LocalizationManager.Translate(localizationKey);
	}
}
internal sealed class TooltipCursorFollower : MonoBehaviour
{
	private void Update()
	{
		TooltipManager.UpdatePosition();
	}
}
internal sealed class ButtonTooltip : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
{
	private string _titleKey;

	private string _descriptionKey;

	private Func<string> _hotkeyProvider;

	internal void Setup(string titleKey, string descriptionKey = null, Func<string> hotkeyProvider = null)
	{
		_titleKey = titleKey;
		_descriptionKey = descriptionKey;
		_hotkeyProvider = hotkeyProvider;
		TMP_Text componentInChildren = ((Component)this).GetComponentInChildren<TMP_Text>(true);
		TooltipManager.EnsureExists(((Component)this).gameObject, componentInChildren);
	}

	public void OnPointerEnter(PointerEventData eventData)
	{
		string hotkey = ((_hotkeyProvider != null) ? _hotkeyProvider() : null);
		TooltipManager.Show(_titleKey, _descriptionKey, hotkey);
	}

	public void OnPointerExit(PointerEventData eventData)
	{
		TooltipManager.Hide();
	}

	private void OnDisable()
	{
		TooltipManager.Hide();
	}
}
internal static class PlayerSortToolbarLayout
{
	private const float VerticalOffset = -6f;

	internal static GameObject Create(Transform parent, float totalWidth, float toolbarHeight, float spacing)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Expected O, but got Unknown
		GameObject val = new GameObject("VIT_PlayerSortToolbar", new Type[3]
		{
			typeof(RectTransform),
			typeof(HorizontalLayoutGroup),
			typeof(PlayerToolbarGridFollower)
		});
		val.transform.SetParent(parent, false);
		RectTransform component = val.GetComponent<RectTransform>();
		component.sizeDelta = new Vector2(totalWidth, toolbarHeight);
		HorizontalLayoutGroup component2 = val.GetComponent<HorizontalLayoutGroup>();
		((HorizontalOrVerticalLayoutGroup)component2).spacing = spacing;
		((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true;
		((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true;
		((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false;
		((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false;
		val.GetComponent<PlayerToolbarGridFollower>().Setup(component, ((Component)parent).GetComponent<RectTransform>(), ModConfig.PlayerInventoryToolbarSide.Value, -6f);
		val.transform.SetAsLastSibling();
		return val;
	}
}
internal sealed class PlayerToolbarGridFollower : MonoBehaviour
{
	private RectTransform _toolbarRect;

	private RectTransform _parentRect;

	private InventoryGrid _playerGrid;

	private Transform _gridRoot;

	private PlayerToolbarSide _side;

	private float _verticalOffset;

	private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4];

	internal void Setup(RectTransform toolbarRect, RectTransform parentRect, PlayerToolbarSide side, float verticalOffset)
	{
		_toolbarRect = toolbarRect;
		_parentRect = parentRect;
		_side = side;
		_verticalOffset = verticalOffset;
		FindGrid();
		UpdatePosition();
	}

	private void LateUpdate()
	{
		if ((Object)(object)_playerGrid == (Object)null || (Object)(object)_gridRoot == (Object)null || (Object)(object)_parentRect == (Object)null || (Object)(object)_toolbarRect == (Object)null)
		{
			FindGrid();
		}
		UpdatePosition();
	}

	private void FindGrid()
	{
		InventoryGui instance = InventoryGui.instance;
		if ((Object)(object)instance == (Object)null)
		{
			_playerGrid = null;
			_gridRoot = null;
			return;
		}
		try
		{
			_playerGrid = Traverse.Create((object)instance).Field<InventoryGrid>("m_playerGrid").Value;
		}
		catch
		{
			_playerGrid = null;
		}
		if ((Object)(object)_playerGrid == (Object)null)
		{
			_gridRoot = null;
			return;
		}
		try
		{
			object value = Traverse.Create((object)_playerGrid).Field("m_gridRoot").GetValue();
			GameObject val = (GameObject)((value is GameObject) ? value : null);
			if (val != null)
			{
				_gridRoot = val.transform;
				return;
			}
			Transform val2 = (Transform)((value is Transform) ? value : null);
			if (val2 != null)
			{
				_gridRoot = val2;
				return;
			}
			Component val3 = (Component)((value is Component) ? value : null);
			if (val3 != null)
			{
				_gridRoot = val3.transform;
				return;
			}
		}
		catch
		{
		}
		_gridRoot = null;
	}

	private void UpdatePosition()
	{
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_toolbarRect == (Object)null || (Object)(object)_parentRect == (Object)null || (Object)(object)_playerGrid == (Object)null || (Object)(object)_gridRoot == (Object)null)
		{
			return;
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return;
		}
		Inventory inventory = ((Humanoid)localPlayer).GetInventory();
		if (inventory == null)
		{
			return;
		}
		int width = inventory.GetWidth();
		if (width <= 0 || !ExtraSlotsCompatibility.TryGetRegularInventoryHeight(inventory, out var height) || height <= 0)
		{
			return;
		}
		int num2;
		int num = (num2 = (height - 1) * width) + width - 1;
		if (num2 < 0 || num < 0 || num2 >= _gridRoot.childCount || num >= _gridRoot.childCount)
		{
			return;
		}
		Transform child = _gridRoot.GetChild(num2);
		Transform child2 = _gridRoot.GetChild(num);
		if ((Object)(object)child == (Object)null || (Object)(object)child2 == (Object)null)
		{
			return;
		}
		RectTransform component = ((Component)child).GetComponent<RectTransform>();
		RectTransform component2 = ((Component)child2).GetComponent<RectTransform>();
		if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null))
		{
			Vector3 val;
			if (_side == PlayerToolbarSide.DownLeft)
			{
				component.GetWorldCorners(_corners);
				val = _corners[0];
				_toolbarRect.pivot = new Vector2(0f, 1f);
			}
			else
			{
				component2.GetWorldCorners(_corners);
				val = _corners[3];
				_toolbarRect.pivot = new Vector2(1f, 1f);
			}
			Vector3 val2 = ((Transform)_parentRect).InverseTransformPoint(val);
			((Transform)_toolbarRect).localPosition = new Vector3(val2.x, val2.y + _verticalOffset, 0f);
		}
	}
}
internal sealed class ToolbarButtonView
{
	internal GameObject GameObject;

	internal RectTransform Rect;

	internal Button Button;

	internal Image Icon;
}
internal static class ToolbarButtonFactory
{
	internal static ToolbarButtonView Create(GameObject template, Transform parent, string objectName, Sprite icon, float buttonSize, float iconSize)
	{
		return Create(template, parent, objectName, icon, buttonSize, buttonSize, iconSize);
	}

	internal static ToolbarButtonView Create(GameObject template, Transform parent, string objectName, Sprite icon, float buttonWidth, float buttonHeight, float iconSize)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Object.Instantiate<GameObject>(template, parent);
		((Object)val).name = objectName;
		Button component = val.GetComponent<Button>();
		RectTransform component2 = val.GetComponent<RectTransform>();
		component2.sizeDelta = new Vector2(buttonWidth, buttonHeight);
		LayoutElement val2 = val.GetComponent<LayoutElement>();
		if ((Object)(object)val2 == (Object)null)
		{
			val2 = val.AddComponent<LayoutElement>();
		}
		val2.minWidth = buttonWidth;
		val2.minHeight = buttonHeight;
		val2.preferredWidth = buttonWidth;
		val2.preferredHeight = buttonHeight;
		val2.flexibleWidth = 0f;
		val2.flexibleHeight = 0f;
		TMP_Text[] componentsInChildren = val.GetComponentsInChildren<TMP_Text>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			((Component)componentsInChildren[i]).gameObject.SetActive(false);
		}
		GameObject val3 = new GameObject("Icon", new Type[2]
		{
			typeof(RectTransform),
			typeof(Image)
		});
		val3.transform.SetParent(val.transform, false);
		RectTransform component3 = val3.GetComponent<RectTransform>();
		component3.anchorMin = new Vector2(0.5f, 0.5f);
		component3.anchorMax = new Vector2(0.5f, 0.5f);
		component3.pivot = new Vector2(0.5f, 0.5f);
		component3.anchoredPosition = Vector2.zero;
		component3.sizeDelta = new Vector2(iconSize, iconSize);
		Image component4 = val3.GetComponent<Image>();
		component4.sprite = icon;
		component4.preserveAspect = true;
		((Graphic)component4).raycastTarget = false;
		((Graphic)component4).color = ((ModConfig.IconColor != null) ? ModConfig.IconColor.Value : Color.white);
		val.SetActive(true);
		return new ToolbarButtonView
		{
			GameObject = val,
			Rect = component2,
			Button = component,
			Icon = component4
		};
	}
}
internal static class ToolbarLayout
{
	private const float BaseMargin = 12f;

	private const float HorizontalEdgeMargin = 8f;

	private const float CompactBottomMargin = 1f;

	internal static bool IsCompactHorizontalMode()
	{
		if (ModConfig.ContainerToolbarSmallHorizontalButtons == null || !ModConfig.ContainerToolbarSmallHorizontalButtons.Value)
		{
			return false;
		}
		ToolbarSide value = ModConfig.ContainerToolbarSide.Value;
		if (value != ToolbarSide.DownLeft)
		{
			return value == ToolbarSide.DownRight;
		}
		return true;
	}

	internal static GameObject Create(Transform parent, int buttonCount, float buttonWidth, float buttonHeight)
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Expected O, but got Unknown
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Expected O, but got Unknown
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		ToolbarSide value = ModConfig.ContainerToolbarSide.Value;
		bool flag = IsVertical(value);
		bool compactHorizontal = IsCompactHorizontalMode();
		GameObject val = ((!flag) ? new GameObject("VIT_ContainerToolbar", new Type[2]
		{
			typeof(RectTransform),
			typeof(HorizontalLayoutGroup)
		}) : new GameObject("VIT_ContainerToolbar", new Type[2]
		{
			typeof(RectTransform),
			typeof(VerticalLayoutGroup)
		}));
		val.transform.SetParent(parent, false);
		RectTransform component = val.GetComponent<RectTransform>();
		float value2 = ModConfig.ContainerToolbarSpacing.Value;
		int num = Mathf.Max(0, buttonCount - 1);
		if (flag)
		{
			component.sizeDelta = new Vector2(buttonWidth, buttonHeight * (float)buttonCount + value2 * (float)num);
			VerticalLayoutGroup component2 = val.GetComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component2).spacing = value2;
			((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false;
		}
		else
		{
			component.sizeDelta = new Vector2(buttonWidth * (float)buttonCount + value2 * (float)num, buttonHeight);
			HorizontalLayoutGroup component3 = val.GetComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component3).spacing = value2;
			((HorizontalOrVerticalLayoutGroup)component3).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component3).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component3).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)component3).childForceExpandHeight = false;
		}
		Position(component, value, compactHorizontal);
		val.transform.SetAsLastSibling();
		return val;
	}

	private static bool IsVertical(ToolbarSide side)
	{
		if (side != ToolbarSide.RightTop && side != ToolbarSide.LeftTop)
		{
			return side == ToolbarSide.LeftDown;
		}
		return true;
	}

	private static void Position(RectTransform rect, ToolbarSide side, bool compactHorizontal)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		float value = ModConfig.ContainerToolbarOffsetX.Value;
		float value2 = ModConfig.ContainerToolbarOffsetY.Value;
		float num = (compactHorizontal ? 1f : 12f);
		switch (side)
		{
		case ToolbarSide.RightTop:
			rect.anchorMin = new Vector2(1f, 1f);
			rect.anchorMax = new Vector2(1f, 1f);
			rect.pivot = new Vector2(0f, 1f);
			rect.anchoredPosition = new Vector2(12f + value, value2);
			break;
		case ToolbarSide.LeftTop:
			rect.anchorMin = new Vector2(0f, 1f);
			rect.anchorMax = new Vector2(0f, 1f);
			rect.pivot = new Vector2(1f, 1f);
			rect.anchoredPosition = new Vector2(-12f + value, value2);
			break;
		case ToolbarSide.LeftDown:
			rect.anchorMin = new Vector2(0f, 0f);
			rect.anchorMax = new Vector2(0f, 0f);
			rect.pivot = new Vector2(1f, 0f);
			rect.anchoredPosition = new Vector2(-12f + value, value2);
			break;
		case ToolbarSide.DownLeft:
			rect.anchorMin = new Vector2(0f, 0f);
			rect.anchorMax = new Vector2(0f, 0f);
			rect.pivot = new Vector2(0f, 1f);
			rect.anchoredPosition = new Vector2(8f + value, 0f - num + value2);
			break;
		case ToolbarSide.DownRight:
			rect.anchorMin = new Vector2(1f, 0f);
			rect.anchorMax = new Vector2(1f, 0f);
			rect.pivot = new Vector2(1f, 1f);
			rect.anchoredPosition = new Vector2(-8f + value, 0f - num + value2);
			break;
		}
	}
}
internal static class TooltipUtility
{
	internal static void Add(GameObject buttonObject, string titleKey, string descriptionKey = null, Func<string> hotkeyProvider = null)
	{
		if (!((Object)(object)buttonObject == (Object)null))
		{
			ButtonTooltip buttonTooltip = buttonObject.GetComponent<ButtonTooltip>();
			if ((Object)(object)buttonTooltip == (Object)null)
			{
				buttonTooltip = buttonObject.AddComponent<ButtonTooltip>();
			}
			buttonTooltip.Setup(titleKey, descriptionKey, hotkeyProvider);
		}
	}
}