Decompiled source of CardDataEditor v1.1.3

plugins/CardDataEditor.dll

Decompiled 8 hours 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 System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CardChoiceSpawnUniqueCardPatch.CustomCategories;
using CardDataEditor.DataEditting;
using CardDataEditor.DataEditting.Config;
using CardDataEditor.DataEditting.Properties;
using CardDataEditor.DataEditting.Registries;
using CardDataEditor.Interfaces;
using CardDataEditor.UI;
using CardDataEditor.UI.Buttons;
using CardDataEditor.UI.Panels;
using CardDataEditor.UI.Properites;
using CardDataEditor.Utils;
using CardDataEditor.Utils.Debug;
using ClassesManagerReborn;
using ClassesManagerReborn.Util;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using ModdingUtils.Utils;
using Photon.Pun;
using RarityLib.Utils;
using TMPro;
using ToggleCardsCategories;
using UnboundLib;
using UnboundLib.Networking;
using UnboundLib.Utils;
using UnboundLib.Utils.UI;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
using WillsWackyManagers.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CardDataEditor
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("Rounds.exe")]
	[BepInPlugin("AALUND13.Card.Data.Editor", "Card Data Editor", "1.1.3")]
	public class CardDataEditor : BaseUnityPlugin
	{
		public const string ModId = "AALUND13.Card.Data.Editor";

		public const string ModName = "Card Data Editor";

		public const string ModInitials = "CDE";

		public const string Version = "1.1.3";

		public static AssetBundle Assets;

		public static List<BaseUnityPlugin> Plugins;

		public static readonly ConfigFile ModConfig = new ConfigFile(Path.Combine(Paths.ConfigPath, "CardDataEditor", "CardDataEditor.cfg"), true);

		public static CardDataEditor Instance { get; private set; }

		public static ManualLogSource ModLogger { get; private set; }

		public static bool IsFirstRun { get; internal set; } = true;

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			ModLogger = ((BaseUnityPlugin)this).Logger;
			new Harmony("AALUND13.Card.Data.Editor").PatchAll();
			((Component)this).gameObject.AddComponent<Profiler>();
			((Component)this).gameObject.AddComponent<CardDataEditorMenuHandler>();
			Assets = AssetUtils.LoadAssetBundleFromResources("card_data_editor", typeof(CardDataEditor).Assembly);
		}

		private void Start()
		{
			Plugins = (List<BaseUnityPlugin>)typeof(Chainloader).GetField("_plugins", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
			CardDataEditorConfig.RegisterMenu(ModConfig);
			PropertyRegistry.RegisterDefaultProperties();
			UIPropetyRegsitry.Init();
			ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)this, 60, (Action)delegate
			{
				CardOptionRegistry.RegisterAllCardOptions();
				CardOptionsConfigManager.RegisterConfig();
				CardDataEditorMenu.Instance.Init(CardOptionsConfigManager.Config);
			});
			Unbound.RegisterHandshake("AALUND13.Card.Data.Editor", (Action)OnHandShakeCompleted);
			CreateCardDataEditorCanvas();
		}

		private void CreateCardDataEditorCanvas()
		{
			if (!((Object)(object)CardDataEditorMenu.Instance != (Object)null))
			{
				GameObject obj = Object.Instantiate<GameObject>(Assets.LoadAsset<GameObject>("Card Data Editor Canvas"));
				Camera component = GameObject.Find("MainCamera").GetComponent<Camera>();
				obj.GetComponent<Canvas>().renderMode = (RenderMode)1;
				obj.GetComponent<Canvas>().worldCamera = component;
				Object.DontDestroyOnLoad((Object)(object)obj);
				LoggerUtils.LogInfo("Created Card Data Editor Canvas.");
			}
		}

		private void OnHandShakeCompleted()
		{
			if (PhotonNetwork.IsMasterClient)
			{
				CardOptionsConfigManager.Config.SyncWithConfig();
				byte[] array = CardOptionRegistry.Serialize();
				NetworkingManager.RPC_Others(typeof(CardDataEditor), "SyncCardsOptions", new object[1] { array });
			}
		}

		[UnboundRPC]
		private static void SyncCardsOptions(byte[] data)
		{
			CardOptionRegistry.Deserialize(data);
		}
	}
	public static class CardDataEditorConfig
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__1_0;

			internal void <RegisterMenu>b__1_0()
			{
			}
		}

		public static ConfigEntry<bool> DangerMode;

		public static void RegisterMenu(ConfigFile config)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			DangerMode = config.Bind<bool>("Card Data Editor", "DangerMode", false, "Enable or disable \"Danger Mode\" which will allow you to detech ANY class cards from thier classes.");
			object obj = <>c.<>9__1_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
				};
				<>c.<>9__1_0 = val;
				obj = (object)val;
			}
			Unbound.RegisterMenu("Card Data Editor Options", (UnityAction)obj, (Action<GameObject>)CreateMenu, (GameObject)null, false);
		}

		public static void CreateMenu(GameObject menuObject)
		{
			TextMeshProUGUI val = default(TextMeshProUGUI);
			MenuHandler.CreateText("<b>Card Data Editor</b>", menuObject, ref val, 70, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			AddBlank(menuObject, 50);
			GameObject toggle = null;
			toggle = MenuHandler.CreateToggle(DangerMode.Value, "<color=#8b0000>Danger Mode</color>", menuObject, (UnityAction<bool>)delegate(bool value)
			{
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Expected O, but got Unknown
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Expected O, but got Unknown
				Toggle toggleComponent = toggle.GetComponentInChildren<Toggle>();
				if (!value)
				{
					DangerMode.Value = false;
				}
				else if (!DangerMode.Value)
				{
					toggleComponent.isOn = false;
					Unbound.BuildModal().Title("Are you sure?").Message("Are you sure you want to enable <color=#8b0000>Danger Mode</color>?\n<color=#ff0000>THIS COULD BREAK SOME CARDS IF YOU DO NOT KNOW WHAT YOU ARE DOING.</color>")
						.CancelButton("No", (UnityAction)delegate
						{
							toggleComponent.isOn = false;
						})
						.ConfirmButton("Yes", (UnityAction)delegate
						{
							DangerMode.Value = true;
							toggleComponent.isOn = true;
						})
						.Show();
				}
			}, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		}

		private static void AddBlank(GameObject menu, int size = 30)
		{
			TextMeshProUGUI val = default(TextMeshProUGUI);
			MenuHandler.CreateText(" ", menu, ref val, size, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		}
	}
}
namespace CardDataEditor.UI
{
	public class CardDataEditorMenu : MonoBehaviour
	{
		[Header("References")]
		public ModSelectionPanel ModSelectionPanel;

		public CardSelectionPanel CardsSelectionPanel;

		public CardPreviewPanel CardPreviewPanel;

		public CardPropertiesPanel CardPropertiesPanel;

		private readonly List<string> createdModCategories = new List<string>();

		public static CardDataEditorMenu Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
		}

		private void Start()
		{
			((Component)this).gameObject.SetActive(false);
		}

		public void Init(CardOptionsConfig configFile)
		{
			foreach (CardOptionsConfigCategory category in configFile.Categories)
			{
				string cardModCategory = GetCardModCategory(category.CardOptions.Card);
				if (!createdModCategories.Contains(cardModCategory))
				{
					ModSelectionPanel.CreateModButton(cardModCategory);
					CardsSelectionPanel.CreateModCategory(cardModCategory);
					createdModCategories.Add(cardModCategory);
				}
				CardsSelectionPanel.GetModCategory(cardModCategory).CreateCardButton(category);
			}
		}

		public void OpenMenu()
		{
			((Component)this).gameObject.SetActive(true);
			ModSelectionPanel.OpenMod("Vanilla");
			CardsSelectionPanel.GetModCategory("Vanilla").CardButtons[0].OpenCard();
		}

		public void CloseMenu()
		{
			((Component)this).gameObject.SetActive(false);
		}

		public void OpenMod(string modCategory)
		{
			CardsSelectionPanel.OpenModCategory(modCategory);
		}

		public void OpenCard(CardOptionsConfigCategory category)
		{
			CardPreviewPanel.CreateCardPreview(category);
			CardPropertiesPanel.CreateCardProperties(category);
		}

		private string GetCardModCategory(CardInfo cardInfo)
		{
			return CardManager.cards.First((KeyValuePair<string, Card> c) => (Object)(object)c.Value.cardInfo == (Object)(object)cardInfo).Value.category;
		}
	}
	public class CardDataEditorMenuHandler : MonoBehaviour
	{
		public static CardDataEditorMenuHandler Instance;

		public bool isOpened;

		private void Awake()
		{
			Instance = this;
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)27))
			{
				CloseMenu();
			}
		}

		internal void CreateMenu()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			GameObject val = (GameObject)ExtensionMethods.GetFieldValue((object)ModOptions.instance, "modOptionsMenu");
			MenuHandler.CreateButton("Card Data Editor", val, new UnityAction(OpenMenu), 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		}

		public void OpenMenu()
		{
			if (!isOpened)
			{
				if (MainMenuHandler.instance.isOpen)
				{
					MainMenuHandler.instance.Close();
				}
				Camera component = GameObject.Find("MainCamera").GetComponent<Camera>();
				Canvas component2 = ((Component)CardDataEditorMenu.Instance).GetComponent<Canvas>();
				component2.renderMode = (RenderMode)1;
				component2.worldCamera = component;
				CardDataEditorMenu.Instance.OpenMenu();
				LoggerUtils.Log((LogLevel)32, "Card data edttor menu have been opened.");
				isOpened = true;
			}
		}

		public void CloseMenu()
		{
			if (isOpened)
			{
				if (!MainMenuHandler.instance.isOpen)
				{
					MainMenuHandler.instance.Open();
				}
				CardDataEditorMenu.Instance.CloseMenu();
				LoggerUtils.Log((LogLevel)32, "Card data edttor menu have been closed.");
				isOpened = false;
			}
		}
	}
	public class UICategory : MonoBehaviour
	{
		[Header("Prefabs")]
		public CardButton UICardOptionsPrefab;

		[Header("References")]
		public TextMeshProUGUI CategoryText;

		public Button DropdownButton;

		public Sprite dropdownOpenImage;

		public Sprite dropdownCloseImage;

		public GameObject Viewport;

		public GameObject ButtonContents;

		public GameObject CategoryContents;

		internal ModCardsCategory modCardsCategory;

		public UICategory ParentCategory { get; private set; }

		public bool IsOpened { get; private set; }

		public CardButton CreateButton(CardOptionsConfigCategory category)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)Object.Instantiate<CardButton>(UICardOptionsPrefab)).gameObject;
			CardButton component = gameObject.GetComponent<CardButton>();
			gameObject.transform.SetParent(ButtonContents.transform);
			gameObject.transform.localScale = Vector3.one;
			component.Init(category);
			ButtonContents.SetActive(true);
			return component;
		}

		public UICategory CreateCategory(string categoryName)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)Object.Instantiate<UICategory>(modCardsCategory.UICategoryPrefab)).gameObject;
			UICategory component = gameObject.GetComponent<UICategory>();
			gameObject.transform.SetParent(CategoryContents.transform);
			gameObject.transform.localScale = Vector3.one;
			((TMP_Text)component.CategoryText).text = categoryName;
			component.modCardsCategory = modCardsCategory;
			component.ParentCategory = this;
			CategoryContents.SetActive(true);
			return component;
		}

		public void ToggleCategory()
		{
			if (IsOpened)
			{
				CloseCategory();
			}
			else
			{
				OpenCategory();
			}
		}

		public void OpenCategory()
		{
			if (!IsOpened)
			{
				Viewport.SetActive(true);
				((Selectable)DropdownButton).image.sprite = dropdownOpenImage;
				IsOpened = true;
			}
		}

		public void CloseCategory()
		{
			if (IsOpened)
			{
				Viewport.SetActive(false);
				((Selectable)DropdownButton).image.sprite = dropdownCloseImage;
				IsOpened = false;
			}
		}
	}
}
namespace CardDataEditor.UI.Properites
{
	public class UIBoolProperty : MonoBehaviour
	{
		[Header("References")]
		public TextMeshProUGUI PropertyNameText;

		public Toggle PropertyToggle;

		private CardPropertyConfigEntry<bool> cardProperty;

		public void Init(CardPropertyConfigEntry<bool> propertyConfigEntry)
		{
			cardProperty = propertyConfigEntry;
			((TMP_Text)PropertyNameText).text = propertyConfigEntry.CardOptionProperty.GetPropertyName();
			PropertyToggle.isOn = propertyConfigEntry.ValueTyped;
			((UnityEvent<bool>)(object)PropertyToggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
			{
				propertyConfigEntry.Value = value;
			});
		}

		public void ResetToDefault()
		{
			PropertyToggle.isOn = cardProperty.DefaultValueTyped;
		}
	}
	public class UIDropdownItemButton : MonoBehaviour
	{
		[Header("References")]
		public TextMeshProUGUI PropertyNameText;

		public Button EnumValueButton;

		public void Init(UIPropertyDropdown dropdown, UIPropertyDropdown.DropdownItem dropdownItem)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			((TMP_Text)PropertyNameText).text = dropdownItem.name;
			((UnityEvent)EnumValueButton.onClick).AddListener((UnityAction)delegate
			{
				dropdown.ValueChanged(dropdownItem);
			});
		}
	}
	public class UIFloatProperty : MonoBehaviour
	{
		[Header("References")]
		public TextMeshProUGUI PropertyNameText;

		public TMP_InputField PropertyInputField;

		private CardPropertyConfigEntry<float> cardProperty;

		public void Init(CardPropertyConfigEntry<float> propertyConfigEntry)
		{
			cardProperty = propertyConfigEntry;
			((TMP_Text)PropertyNameText).text = propertyConfigEntry.CardOptionProperty.GetPropertyName();
			PropertyInputField.text = propertyConfigEntry.ValueTyped.ToString();
			((UnityEvent<string>)(object)PropertyInputField.onValueChanged).AddListener((UnityAction<string>)delegate(string text)
			{
				if (float.TryParse(text, out var result))
				{
					propertyConfigEntry.Value = result;
				}
			});
		}

		public void ResetToDefault()
		{
			TMP_InputField propertyInputField = PropertyInputField;
			float defaultValueTyped = cardProperty.DefaultValueTyped;
			propertyInputField.text = defaultValueTyped.ToString();
		}
	}
	public class UIIntProperty : MonoBehaviour
	{
		[Header("References")]
		public TextMeshProUGUI PropertyNameText;

		public TMP_InputField PropertyInputField;

		private CardPropertyConfigEntry<int> cardProperty;

		public void Init(CardPropertyConfigEntry<int> propertyConfigEntry)
		{
			cardProperty = propertyConfigEntry;
			((TMP_Text)PropertyNameText).text = propertyConfigEntry.CardOptionProperty.GetPropertyName();
			PropertyInputField.text = propertyConfigEntry.ValueTyped.ToString();
			((UnityEvent<string>)(object)PropertyInputField.onValueChanged).AddListener((UnityAction<string>)delegate(string text)
			{
				if (int.TryParse(text, out var result))
				{
					propertyConfigEntry.Value = result;
				}
			});
		}

		public void ResetToDefault()
		{
			TMP_InputField propertyInputField = PropertyInputField;
			int defaultValueTyped = cardProperty.DefaultValueTyped;
			propertyInputField.text = defaultValueTyped.ToString();
		}
	}
	public class UIPropertyDropdown : MonoBehaviour
	{
		public struct DropdownItem : IEquatable<DropdownItem>
		{
			public string name;

			public string value;

			public DropdownItem(string name, string value)
			{
				this.name = name;
				this.value = value;
			}

			public bool Equals(DropdownItem other)
			{
				if (name == other.name)
				{
					return value == other.value;
				}
				return false;
			}

			public override bool Equals(object obj)
			{
				if (obj is DropdownItem other)
				{
					return Equals(other);
				}
				return false;
			}

			public override int GetHashCode()
			{
				return (17 * 31 + (name?.GetHashCode() ?? 0)) * 31 + (value?.GetHashCode() ?? 0);
			}

			public static bool operator ==(DropdownItem left, DropdownItem right)
			{
				return left.Equals(right);
			}

			public static bool operator !=(DropdownItem left, DropdownItem right)
			{
				return !left.Equals(right);
			}
		}

		[Header("Prefabs")]
		public UIDropdownItemButton propertyButtonPrefab;

		[Header("References")]
		public TextMeshProUGUI PropertyNameText;

		public RectTransform PropertyValuesContent;

		public RectTransform PropertyDropdownViewport;

		public TMP_InputField PropertySearchInputField;

		public Action<DropdownItem> OnValueChanged;

		public Dictionary<DropdownItem, UIDropdownItemButton> PropertyDropdownItems = new Dictionary<DropdownItem, UIDropdownItemButton>();

		public DropdownItem[] DropdownItems;

		public DropdownItem SelectedDropdownItem;

		public DropdownItem DefaultDropdownItem;

		private void Awake()
		{
			((Component)PropertyDropdownViewport).gameObject.SetActive(false);
		}

		public void Init(string name, DropdownItem[] dropdownItems, DropdownItem selectedDropdownItem, DropdownItem defaultDropdownItem)
		{
			if (!dropdownItems.Contains(selectedDropdownItem))
			{
				throw new ArgumentException("Selected dropdown item '" + selectedDropdownItem.value + "' does not exist in the dropdown items.", "selectedDropdownItem");
			}
			if (!dropdownItems.Contains(defaultDropdownItem))
			{
				throw new ArgumentException("Default dropdown item '" + selectedDropdownItem.value + "' does not exist in the dropdown items.", "defaultDropdownItem");
			}
			((TMP_Text)PropertyNameText).text = name;
			DropdownItems = dropdownItems;
			SelectedDropdownItem = selectedDropdownItem;
			DefaultDropdownItem = defaultDropdownItem;
			foreach (DropdownItem dropdownItem in dropdownItems)
			{
				GameObject obj = Object.Instantiate<GameObject>(((Component)propertyButtonPrefab).gameObject);
				UIDropdownItemButton component = obj.GetComponent<UIDropdownItemButton>();
				obj.transform.SetParent((Transform)(object)PropertyValuesContent);
				component.Init(this, dropdownItem);
				PropertyDropdownItems.Add(dropdownItem, component);
			}
			((UnityEvent<string>)(object)PropertySearchInputField.onValueChanged).AddListener((UnityAction<string>)FilterItems);
			((UnityEvent<string>)(object)PropertySearchInputField.onSubmit).AddListener((UnityAction<string>)SelectItem);
			((UnityEvent<string>)(object)PropertySearchInputField.onSelect).AddListener((UnityAction<string>)OnSearchSelected);
			PropertySearchInputField.SetTextWithoutNotify(selectedDropdownItem.name);
		}

		private void OnSearchSelected(string value)
		{
			LoggerUtils.Log((LogLevel)16, "Dropdown have been selected.");
			((Component)PropertyDropdownViewport).gameObject.SetActive(true);
			DropdownItem[] dropdownItems = DropdownItems;
			foreach (DropdownItem key in dropdownItems)
			{
				((Component)PropertyDropdownItems[key]).gameObject.SetActive(true);
			}
			((Selectable)PropertySearchInputField).Select();
			PropertySearchInputField.selectionAnchorPosition = 0;
			PropertySearchInputField.selectionFocusPosition = PropertySearchInputField.text.Length;
		}

		private void FilterItems(string search)
		{
			search = RemoveTags(search.Trim());
			DropdownItem[] dropdownItems = DropdownItems;
			for (int i = 0; i < dropdownItems.Length; i++)
			{
				DropdownItem key = dropdownItems[i];
				string text = RemoveTags(key.name);
				bool active = string.IsNullOrEmpty(search) || text.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0;
				((Component)PropertyDropdownItems[key]).gameObject.SetActive(active);
			}
		}

		private void SelectItem(string search)
		{
			DropdownItem[] itemsFromSearch = GetItemsFromSearch(search);
			if (itemsFromSearch.Length != 0)
			{
				ValueChanged(itemsFromSearch[0]);
			}
			else
			{
				ValueChanged(DefaultDropdownItem);
			}
		}

		public DropdownItem[] GetItemsFromSearch(string value)
		{
			value = RemoveTags(value);
			return DropdownItems.Where((DropdownItem i) => RemoveTags(i.name).IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0).ToArray();
		}

		public void ValueChanged(DropdownItem value)
		{
			EventSystem.current.SetSelectedGameObject((GameObject)null);
			SelectedDropdownItem = value;
			PropertySearchInputField.SetTextWithoutNotify(value.name);
			((Component)PropertyDropdownViewport).gameObject.SetActive(false);
			OnValueChanged?.Invoke(value);
		}

		public void ResetToDefault()
		{
			ValueChanged(DefaultDropdownItem);
		}

		private string RemoveTags(string value)
		{
			return Regex.Replace(value, "<.*?>", "");
		}
	}
	public class UIPropetyRegsitry : MonoBehaviour
	{
		[Header("References")]
		public UIIntProperty UIIntPropertyPrefab;

		public UIFloatProperty UIFloatPropertyPrefab;

		public UIBoolProperty UIBoolPropertyPrefab;

		public UIPropertyDropdown UIEnumPropertyPrefab;

		public static UIPropetyRegsitry Instance { get; private set; }

		internal static void Init()
		{
			Instance = CardDataEditor.Assets.LoadAsset<GameObject>("UI Propety Regsitry").GetComponent<UIPropetyRegsitry>();
		}
	}
}
namespace CardDataEditor.UI.Panels
{
	public class ModCardsCategory : MonoBehaviour
	{
		[Header("Prefabs")]
		public CardButton UICardOptionsPrefab;

		public UICategory UICategoryPrefab;

		[Header("References")]
		public Transform CategoryButtonContents;

		public Transform CardsButtonContents;

		public readonly List<CardButton> CardButtons = new List<CardButton>();

		public readonly List<UICategory> CategoryToCollapses = new List<UICategory>();

		private readonly Dictionary<string, UICategory> Subcategories = new Dictionary<string, UICategory>();

		private readonly Dictionary<CardButton, UICategory> ButtonsToCategory = new Dictionary<CardButton, UICategory>();

		private void Awake()
		{
			((Component)this).gameObject.SetActive(false);
		}

		public void SearchCards(string searchValue)
		{
			foreach (UICategory categoryToCollapse in CategoryToCollapses)
			{
				categoryToCollapse.CloseCategory();
			}
			CategoryToCollapses.Clear();
			foreach (CardButton cardButton in CardButtons)
			{
				string cardName = cardButton.Category.CardOptions.Card.cardName;
				bool flag = string.IsNullOrEmpty(searchValue) || cardName.IndexOf(searchValue, StringComparison.OrdinalIgnoreCase) >= 0;
				((Component)cardButton).gameObject.SetActive(flag);
				if (!flag || Utility.IsNullOrWhiteSpace(searchValue))
				{
					continue;
				}
				foreach (UICategory cardCategory in GetCardCategories(cardButton))
				{
					if (!CategoryToCollapses.Contains(cardCategory) && !cardCategory.IsOpened)
					{
						CategoryToCollapses.Add(cardCategory);
						cardCategory.OpenCategory();
					}
				}
			}
		}

		public void CreateCardButton(CardOptionsConfigCategory category)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			string cardSubcategory = ToggleCardsCategorieInterface.GetCardSubcategory(category.CardOptions.Card);
			if (!Utility.IsNullOrWhiteSpace(cardSubcategory))
			{
				UICategory orCreateCategory = GetOrCreateCategory(cardSubcategory);
				CardButton cardButton = orCreateCategory.CreateButton(category);
				CardButtons.Add(cardButton);
				ButtonsToCategory.Add(cardButton, orCreateCategory);
			}
			else
			{
				GameObject gameObject = ((Component)Object.Instantiate<CardButton>(UICardOptionsPrefab)).gameObject;
				CardButton component = gameObject.GetComponent<CardButton>();
				gameObject.transform.SetParent(CardsButtonContents);
				gameObject.transform.localScale = Vector3.one;
				component.Init(category);
				CardButtons.Add(component);
			}
		}

		public UICategory CreateCategory(string categoryName)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)Object.Instantiate<UICategory>(UICategoryPrefab)).gameObject;
			UICategory component = gameObject.GetComponent<UICategory>();
			gameObject.transform.SetParent(CategoryButtonContents);
			gameObject.transform.localScale = Vector3.one;
			((TMP_Text)component.CategoryText).text = categoryName;
			component.modCardsCategory = this;
			return component;
		}

		public List<UICategory> GetCardCategories(CardButton cardButton)
		{
			List<UICategory> list = new List<UICategory>();
			if (ButtonsToCategory.TryGetValue(cardButton, out var value))
			{
				UICategory uICategory = value;
				while ((Object)(object)uICategory != (Object)null)
				{
					list.Add(uICategory);
					uICategory = uICategory.ParentCategory;
				}
			}
			return list;
		}

		private UICategory GetOrCreateCategory(string categoryPath)
		{
			string[] array = categoryPath.Split(new char[1] { '/' });
			string text = array[0];
			UICategory uICategory = null;
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i];
				if (i > 0)
				{
					text = text + "/" + text2;
				}
				if (Subcategories.ContainsKey(text))
				{
					uICategory = Subcategories[text];
				}
				else if (!Subcategories.ContainsKey(text))
				{
					if ((Object)(object)uICategory == (Object)null)
					{
						uICategory = CreateCategory(text2);
						Subcategories.Add(text, uICategory);
					}
					else
					{
						uICategory = uICategory.CreateCategory(text2);
						Subcategories.Add(text, uICategory);
					}
				}
			}
			return uICategory;
		}
	}
	public class CardPreviewPanel : MonoBehaviour
	{
		[Header("References")]
		public Transform CardPreviewHolder;

		private GameObject CurrentPreviewCard;

		private CardOptionsConfigCategory CurrentCardOptions;

		public void CreateCardPreview(CardOptionsConfigCategory cardOptions)
		{
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)CurrentPreviewCard != (Object)null)
			{
				CurrentCardOptions.OnEntryChanged -= ApplyPropertyToPreviewCard;
				Object.Destroy((Object)(object)CurrentPreviewCard);
			}
			CurrentCardOptions = cardOptions;
			CurrentPreviewCard = Object.Instantiate<GameObject>(((Component)cardOptions.CardOptions.Card).gameObject, CardPreviewHolder);
			CurrentPreviewCard.SetActive(true);
			GameObject val = FindObjectInChildren(CurrentPreviewCard, "Front");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			GameObject val2 = FindObjectInChildren(CurrentPreviewCard, "Back");
			GameObject obj = FindObjectInChildren(CurrentPreviewCard, "Damagable");
			Object.Destroy((Object)(object)val2);
			Object.Destroy((Object)(object)obj);
			CardVisuals[] componentsInChildren = CurrentPreviewCard.GetComponentsInChildren<CardVisuals>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].firstValueToSet = true;
			}
			GameObject obj2 = FindObjectInChildren(CurrentPreviewCard, "BlockFront");
			if (obj2 != null)
			{
				obj2.SetActive(false);
			}
			CurrentPreviewCard.GetComponentsInChildren<CanvasGroup>().ToList().ForEach(delegate(CanvasGroup canvasGroup)
			{
				canvasGroup.alpha = 1f;
			});
			GameObject val3 = FindObjectInChildren(val.gameObject, "UI_ParticleSystem");
			if ((Object)(object)val3 != (Object)null)
			{
				Object.Destroy((Object)(object)val3);
			}
			GameObject val4 = FindObjectInChildren(val.gameObject, "Background");
			if ((Object)(object)val4 != (Object)null)
			{
				RectTransform component = val4.GetComponent<RectTransform>();
				((Transform)component).localScale = new Vector3(1f, 1f, 1f);
				component.anchorMin = new Vector2(0.5f, 0.5f);
				component.anchorMax = new Vector2(0.5f, 0.5f);
				component.sizeDelta = new Vector2(1500f, 1500f);
				Image componentInChildren = val4.gameObject.GetComponentInChildren<Image>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.preserveAspect = true;
					((Graphic)componentInChildren).color = new Color(0.16f, 0.16f, 0.16f, 1f);
				}
				Mask componentInChildren2 = val4.gameObject.GetComponentInChildren<Mask>(true);
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren2.showMaskGraphic = true;
				}
			}
			RectTransform orAddComponent = ExtensionMethods.GetOrAddComponent<RectTransform>(CurrentPreviewCard, false);
			((Transform)orAddComponent).localScale = 16f * Vector3.one;
			orAddComponent.anchorMin = Vector2.zero;
			orAddComponent.anchorMax = Vector2.one;
			orAddComponent.offsetMin = Vector2.zero;
			orAddComponent.offsetMax = Vector2.zero;
			orAddComponent.pivot = new Vector2(0.5f, 0.5f);
			((Transform)orAddComponent).localPosition = new Vector3(0f, -10f, 0f);
			((TMP_Text)((Component)val.transform).GetComponentInChildren<TextMeshProUGUI>()).text = cardOptions.CardOptions.Card.cardName.ToUpper();
			foreach (CardProperty value in cardOptions.CardOptions.Properties.Values)
			{
				value.ApplyPropertyToPreviewCard(CurrentPreviewCard, CurrentPreviewCard.GetComponent<CardInfo>());
			}
			CurrentCardOptions.OnEntryChanged += ApplyPropertyToPreviewCard;
		}

		private void ApplyPropertyToPreviewCard(CardPropertyConfigEntry cardPropertyConfigEntry)
		{
			cardPropertyConfigEntry.CardOptionProperty.ApplyPropertyToPreviewCard(CurrentPreviewCard, CurrentPreviewCard.GetComponent<CardInfo>());
		}

		private static GameObject FindObjectInChildren(GameObject gameObject, string gameObjectName)
		{
			Transform? obj = ((IEnumerable<Transform>)gameObject.GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform i) => ((Object)((Component)i).gameObject).name == gameObjectName));
			if (obj == null)
			{
				return null;
			}
			return ((Component)obj).gameObject;
		}
	}
	public class CardPropertiesPanel : MonoBehaviour
	{
		[Header("Prefabs")]
		public GameObject HeaderText;

		[Header("References")]
		public RectTransform PropertiesHolder;

		private readonly Dictionary<string, List<GameObject>> CategoryToPropertiesMap = new Dictionary<string, List<GameObject>>();

		private readonly List<GameObject> CurrentlyActiveProperties = new List<GameObject>();

		public void CreateCardProperties(CardOptionsConfigCategory category)
		{
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			CategoryToPropertiesMap.Clear();
			foreach (GameObject currentlyActiveProperty in CurrentlyActiveProperties)
			{
				Object.Destroy((Object)(object)currentlyActiveProperty);
			}
			foreach (CardProperty value in category.CardOptions.Properties.Values)
			{
				if (value.CanShowProperty())
				{
					string categoryName = value.GetCategoryName();
					if (!CategoryToPropertiesMap.ContainsKey(categoryName))
					{
						CategoryToPropertiesMap.Add(categoryName, new List<GameObject>());
					}
					GameObject item = value.CreateUIProperty(category.GetEntry(value.GetSerializeName()));
					CategoryToPropertiesMap[categoryName].Add(item);
				}
			}
			foreach (KeyValuePair<string, List<GameObject>> item2 in CategoryToPropertiesMap)
			{
				GameObject val = Object.Instantiate<GameObject>(HeaderText);
				((TMP_Text)val.GetComponentInChildren<TextMeshProUGUI>()).text = item2.Key;
				val.transform.SetParent((Transform)(object)PropertiesHolder);
				val.transform.localScale = Vector3.one;
				CurrentlyActiveProperties.Add(val);
				foreach (GameObject item3 in item2.Value)
				{
					item3.transform.SetParent((Transform)(object)PropertiesHolder);
					item3.transform.localScale = Vector3.one;
					CurrentlyActiveProperties.Add(item3);
				}
			}
		}
	}
	public class CardSelectionPanel : MonoBehaviour
	{
		[Header("Prefabs")]
		public ModCardsCategory ModCardsCategoryPrefab;

		[Header("References")]
		public TMP_InputField SearchInputField;

		public TextMeshProUGUI TitleText;

		public Transform ModsContents;

		private readonly Dictionary<string, ModCardsCategory> modCardsCategories = new Dictionary<string, ModCardsCategory>();

		private ModCardsCategory currentModCategory;

		private CardButton currentCardButton;

		private void Awake()
		{
			((UnityEvent<string>)(object)SearchInputField.onValueChanged).AddListener((UnityAction<string>)delegate(string value)
			{
				currentModCategory.SearchCards(value);
			});
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)ModsContents);
		}

		public void OpenCard(CardOptionsConfigCategory category, CardButton button)
		{
			if ((Object)(object)currentCardButton != (Object)null)
			{
				currentCardButton.IsSelected = false;
				currentCardButton.UpdateVisualAnimation();
			}
			currentCardButton = button;
			currentCardButton.IsSelected = true;
			currentCardButton.UpdateVisualAnimation();
			((Component)this).GetComponentInParent<CardDataEditorMenu>().OpenCard(category);
		}

		public void CreateModCategory(string modCategory)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!modCardsCategories.ContainsKey(modCategory))
			{
				GameObject gameObject = ((Component)Object.Instantiate<ModCardsCategory>(ModCardsCategoryPrefab)).gameObject;
				ModCardsCategory component = gameObject.GetComponent<ModCardsCategory>();
				gameObject.transform.SetParent(ModsContents);
				gameObject.transform.localScale = Vector3.one;
				modCardsCategories.Add(modCategory, component);
			}
		}

		public void OpenModCategory(string modCategory)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			if (modCardsCategories.TryGetValue(modCategory, out var value))
			{
				if ((Object)(object)currentModCategory != (Object)null)
				{
					((Component)currentModCategory).gameObject.SetActive(false);
				}
				currentModCategory = value;
				((Component)currentModCategory).gameObject.SetActive(true);
				currentModCategory.SearchCards(SearchInputField.text);
				((TMP_Text)TitleText).text = "CARDS (" + modCategory + ")";
				LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)((Component)currentModCategory).transform);
			}
		}

		public ModCardsCategory GetModCategory(string modCategory)
		{
			return modCardsCategories[modCategory];
		}
	}
	public class ModSelectionPanel : MonoBehaviour
	{
		[Header("Prefabs")]
		public SelectModButton SelectModButtonPrefab;

		[Header("References")]
		public Transform ItemContents;

		private readonly Dictionary<string, SelectModButton> modButtons = new Dictionary<string, SelectModButton>();

		private SelectModButton CurrentSelectedModButton;

		private CardDataEditorMenu CardDataEditor;

		private void Awake()
		{
			CardDataEditor = ((Component)this).GetComponentInParent<CardDataEditorMenu>();
		}

		public void CreateModButton(string modCategory)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!modButtons.ContainsKey(modCategory))
			{
				GameObject gameObject = ((Component)Object.Instantiate<SelectModButton>(SelectModButtonPrefab)).gameObject;
				SelectModButton component = gameObject.GetComponent<SelectModButton>();
				gameObject.transform.SetParent(ItemContents);
				gameObject.transform.localScale = Vector3.one;
				component.Init(modCategory);
				modButtons.Add(modCategory, component);
				SortModButtons();
			}
		}

		public void OpenMod(string modCategory)
		{
			if (modButtons.TryGetValue(modCategory, out var value))
			{
				if ((Object)(object)CurrentSelectedModButton != (Object)null)
				{
					CurrentSelectedModButton.DeselectMod();
				}
				value.SelecteMod();
				CurrentSelectedModButton = value;
				CardDataEditor.OpenMod(modCategory);
			}
		}

		private void SortModButtons()
		{
			int num = 0;
			if (modButtons.TryGetValue("Vanilla", out var value))
			{
				((Component)value).transform.SetSiblingIndex(num++);
			}
			foreach (KeyValuePair<string, SelectModButton> item in from x in modButtons
				where x.Key != "Vanilla"
				orderby x.Key
				select x)
			{
				((Component)item.Value).transform.SetSiblingIndex(num++);
			}
		}
	}
}
namespace CardDataEditor.UI.Buttons
{
	public class CardButton : MonoBehaviour
	{
		[Header("References")]
		public TextMeshProUGUI CardNameText;

		public Graphic RarityGraphic;

		public Graphic ThemeGraphic;

		public Button OpenButton;

		[Header("Options")]
		public float SelectMultiplier = 0.85f;

		public float DeselectMultiplier = 0.7f;

		[HideInInspector]
		public bool IsSelected;

		[HideInInspector]
		public CardOptionsConfigCategory Category;

		private Coroutine colorAnimation;

		public void Init(CardOptionsConfigCategory category)
		{
			Category = category;
			Category.OnEntryChanged += delegate
			{
				UpdateVisual();
			};
			UpdateVisual();
		}

		public void OpenCard()
		{
			((Component)this).GetComponentInParent<CardSelectionPanel>().OpenCard(Category, this);
		}

		public void UpdateVisualAnimation()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (colorAnimation != null)
			{
				((MonoBehaviour)this).StopCoroutine(colorAnimation);
			}
			Color startColor = RarityGraphic.color;
			if (((Component)this).gameObject.activeInHierarchy)
			{
				colorAnimation = ((MonoBehaviour)this).StartCoroutine(EaseUtils.EaseCoroutine(0.25f, EaseUtils.EaseType.easeInOutSine, delegate(float t)
				{
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					//IL_002c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0032: Unknown result type (might be due to invalid IL or missing references)
					RarityGraphic.color = Color.Lerp(startColor, GetCardRarityColor(Category.CardOptions.Card), t);
				}));
			}
			else
			{
				UpdateVisual();
			}
		}

		public void UpdateVisual()
		{
			//IL_003c: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)CardNameText).text = Category.CardOptions.Card.cardName.ToUpper();
			RarityGraphic.color = GetCardRarityColor(Category.CardOptions.Card);
			ThemeGraphic.color = CardChoice.instance.GetCardColor(Category.CardOptions.Card.colorTheme);
			if (colorAnimation != null)
			{
				((MonoBehaviour)this).StopCoroutine(colorAnimation);
			}
		}

		private Color GetCardRarityColor(CardInfo card)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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)
			float num = (IsSelected ? SelectMultiplier : DeselectMultiplier);
			Color val = RarityUtils.GetRarityData(card.rarity).color * num;
			return (((double)Mathf.Max(new float[3] { val.r, val.g, val.b }) < 0.2) ? (Color.white * 0.7f) : val) * num;
		}
	}
	public class SelectModButton : MonoBehaviour
	{
		[Header("References")]
		public Graphic SelectionGraphic;

		public Button Button;

		public TextMeshProUGUI ModText;

		[Header("Selection Options")]
		public Color SelectionColor = Color.white * 0.75f;

		public Color DeselectionColor = Color.white * 0.45f;

		private Coroutine colorAnimation;

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			SelectionGraphic.color = DeselectionColor;
		}

		public void Init(string modCategory)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			((TMP_Text)ModText).text = modCategory;
			((UnityEvent)Button.onClick).AddListener((UnityAction)delegate
			{
				((Component)this).GetComponentInParent<ModSelectionPanel>().OpenMod(modCategory);
			});
		}

		public void SelecteMod()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (colorAnimation != null)
			{
				((MonoBehaviour)this).StopCoroutine(colorAnimation);
			}
			Color startColor = SelectionGraphic.color;
			colorAnimation = ((MonoBehaviour)this).StartCoroutine(EaseUtils.EaseCoroutine(0.25f, EaseUtils.EaseType.easeInOutSine, delegate(float t)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				SelectionGraphic.color = Color.Lerp(startColor, SelectionColor, t);
			}));
		}

		public void DeselectMod()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			Color startColor = SelectionGraphic.color;
			colorAnimation = ((MonoBehaviour)this).StartCoroutine(EaseUtils.EaseCoroutine(0.25f, EaseUtils.EaseType.easeInOutSine, delegate(float t)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				SelectionGraphic.color = Color.Lerp(startColor, DeselectionColor, t);
			}));
		}
	}
}
namespace CardDataEditor.Patches
{
	[HarmonyPatch(typeof(DevConsole), "Update")]
	public class DevConsolePatch
	{
		private static bool Prefix()
		{
			if (CardDataEditorMenuHandler.Instance.isOpened)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ModOptions), "CreatModOptionsMenu")]
	internal class ModOptionsPatch
	{
		public static void Postfix(bool pauseMenu)
		{
			if (!pauseMenu)
			{
				CardDataEditorMenuHandler.Instance.CreateMenu();
			}
		}
	}
}
namespace CardDataEditor.Scripts.Patches
{
	[HarmonyPatch(typeof(MainMenuHandler), "Awake")]
	public class MainMenuHandlerPatch
	{
		public static void Postfix(MainMenuHandler __instance)
		{
			if (CardDataEditor.IsFirstRun)
			{
				CardDataEditor.IsFirstRun = false;
			}
			else
			{
				CardOptionsConfigManager.Config.SyncWithConfig();
			}
		}
	}
	[HarmonyPatch(typeof(ToggleCardsMenuHandler), "UpdateVisualsCardObj")]
	public class UpdateVisualsCardObjPatch
	{
		public static void Postfix(ToggleCardsMenuHandler __instance, GameObject cardObject)
		{
			if (!ToggleCardsMenuHandler.cardMenuCanvas.gameObject.activeSelf)
			{
				return;
			}
			CardInfo componentInChildren = cardObject.GetComponentInChildren<CardInfo>(false);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			string text = ((Object)cardObject.GetComponentInChildren<CardInfo>()).name.Substring(0, ((Object)cardObject.GetComponentInChildren<CardInfo>()).name.Length - 7);
			CardOptions cardOptions = CardOptionRegistry.GetCardOptions(Cards.instance.GetCardWithObjectName(text));
			if (cardOptions == null)
			{
				return;
			}
			foreach (CardProperty value in cardOptions.Properties.Values)
			{
				value.ApplyPropertyToPreviewCard(cardObject, componentInChildren);
			}
		}
	}
}
namespace CardDataEditor.Scripts.Migration
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Rarity.Toggle", "'Rarity Toggle' -> 'Card Data Editor' Migration", "9999.9999.9999")]
	[BepInProcess("Rounds.exe")]
	public class RarityToggleMigration : BaseUnityPlugin
	{
		private const string ModId = "Rarity.Toggle";

		private const string ModName = "'Rarity Toggle' -> 'Card Data Editor' Migration";

		public const string Version = "9999.9999.9999";

		private readonly Regex sanitizeRegex = new Regex("[\\n\\t\\\\\"'\\[\\]]+", RegexOptions.Compiled);

		private List<CardInfo> allCards => (from v in CardManager.cards.Values
			select v.cardInfo into c
			orderby c.cardName
			select c).ToList();

		private void Start()
		{
			CardOptionsConfigManager.OnConfigFirstCreated += delegate(CardOptionsConfig config)
			{
				MigrateRarityToggle(config);
			};
		}

		public unsafe void MigrateRarityToggle(CardOptionsConfig configFile)
		{
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			Profiler.Start("RarityToggleMigration.MigrateRarityToggle");
			Dictionary<string, CardInfo> dictionary = new Dictionary<string, CardInfo>();
			foreach (CardInfo allCard in allCards)
			{
				dictionary.Add(SanitizeText(((Object)allCard).name), allCard);
			}
			configFile.SaveOnChange = false;
			foreach (KeyValuePair<ConfigDefinition, string> entry in (Dictionary<ConfigDefinition, string>)ExtensionMethods.GetPropertyValue((object)((BaseUnityPlugin)this).Config, "OrphanedEntries"))
			{
				if (!dictionary.TryGetValue(entry.Key.Key, out var value) || entry.Value == "DEFAULT")
				{
					continue;
				}
				CardPropertyConfigEntry<Rarity> entry2 = configFile.FindCategory(((Object)value).name).GetEntry<Rarity>();
				if (Enum.GetValues(typeof(Rarity)).Cast<Rarity>().Any((Rarity r) => ((object)(*(Rarity*)(&r))/*cast due to .constrained prefix*/).ToString() == entry.Value))
				{
					Rarity valueTyped = Enum.GetValues(typeof(Rarity)).Cast<Rarity>().FirstOrDefault((Func<Rarity, bool>)((Rarity r) => ((object)(*(Rarity*)(&r))/*cast due to .constrained prefix*/).ToString() == entry.Value));
					entry2.ValueTyped = valueTyped;
				}
			}
			configFile.SaveOnChange = true;
			Profiler.End("RarityToggleMigration.MigrateRarityToggle");
		}

		private string SanitizeText(string text)
		{
			return sanitizeRegex.Replace(text, "");
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Theme.Toggle", "'Theme Toggle' -> 'Card Data Editor' Migration", "9999.9999.9999")]
	[BepInProcess("Rounds.exe")]
	public class ThemeToggleMigration : BaseUnityPlugin
	{
		private const string ModId = "Theme.Toggle";

		private const string ModName = "'Theme Toggle' -> 'Card Data Editor' Migration";

		public const string Version = "9999.9999.9999";

		private void Start()
		{
			CardOptionsConfigManager.OnConfigFirstCreated += delegate(CardOptionsConfig config)
			{
				MigrateRarityToggle(config);
			};
		}

		public void MigrateRarityToggle(CardOptionsConfig configFile)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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)
			Profiler.Start("ThemeToggleMigration.MigrateRarityToggle");
			configFile.SaveOnChange = false;
			foreach (KeyValuePair<ConfigDefinition, string> item in (Dictionary<ConfigDefinition, string>)ExtensionMethods.GetPropertyValue((object)((BaseUnityPlugin)this).Config, "OrphanedEntries"))
			{
				if (!int.TryParse(item.Value, out var value) || value == -1)
				{
					continue;
				}
				CardInfo cardWithObjectName = Cards.instance.GetCardWithObjectName(item.Key.Key);
				CardPropertyConfigEntry<CardThemeColorType> entry = configFile.FindCategory(((Object)cardWithObjectName).name).GetEntry<CardThemeColorType>();
				if (Enum.GetValues(typeof(CardThemeColorType)).Cast<CardThemeColorType>().Any((CardThemeColorType t) => (int)t == value))
				{
					CardThemeColorType valueTyped = Enum.GetValues(typeof(CardThemeColorType)).Cast<CardThemeColorType>().FirstOrDefault((Func<CardThemeColorType, bool>)((CardThemeColorType t) => (int)t == value));
					entry.ValueTyped = valueTyped;
				}
			}
			configFile.SaveOnChange = true;
			Profiler.End("ThemeToggleMigration.MigrateRarityToggle");
		}
	}
}
namespace CardDataEditor.Interfaces
{
	public static class ToggleCardsCategorieInterface
	{
		public static string GetCardSubcategory(CardInfo cardInfo)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (CardDataEditor.Plugins.Exists((BaseUnityPlugin plugin) => plugin.Info.Metadata.GUID == "com.aalund13.rounds.toggle_cards_categories"))
			{
				IToggleCardCategory component = ((Component)cardInfo).GetComponent<IToggleCardCategory>();
				if (component != null)
				{
					return component.GetCardCategoryInfo().Name;
				}
				return "";
			}
			return "";
		}
	}
}
namespace CardDataEditor.Utils
{
	public static class EaseUtils
	{
		public enum EaseType
		{
			easeInSine,
			easeOutSine,
			easeInOutSine,
			easeInQuad,
			easeOutQuad,
			easeInOutQuad
		}

		public static float Ease(float time, float start, float end, float duration, EaseType easeType)
		{
			switch (easeType)
			{
			case EaseType.easeInSine:
				return 0f - Mathf.Cos(time / duration * ((float)Math.PI / 2f)) + 1f * (end - start) + start;
			case EaseType.easeOutSine:
				return Mathf.Sin(time / duration * ((float)Math.PI / 2f)) * (end - start) + start;
			case EaseType.easeInOutSine:
				return -0.5f * (Mathf.Cos((float)Math.PI * time / duration) - 1f) * (end - start) + start;
			case EaseType.easeInQuad:
				return (end - start) * (time /= duration) * time + start;
			case EaseType.easeOutQuad:
				return (0f - (end - start)) * (time /= duration) * (time - 2f) + start;
			case EaseType.easeInOutQuad:
				if (!((time /= duration / 2f) < 1f))
				{
					return (0f - (end - start)) / 2f * ((time -= 1f) * (time - 2f) - 1f) + start;
				}
				return (end - start) / 2f * time * time + start;
			default:
				return 0f;
			}
		}

		public static IEnumerator EaseCoroutine(float duration, EaseType easeType, Action<float> action, Action onComplete = null, float min = 0f, float max = 1f)
		{
			float time = 0f;
			while (time < duration)
			{
				action(Ease(time, min, max, duration, easeType));
				time += Time.deltaTime;
				yield return null;
			}
			action(Ease(duration, min, max, duration, easeType));
			onComplete?.Invoke();
		}
	}
}
namespace CardDataEditor.Utils.Debug
{
	public static class LoggerUtils
	{
		private static void Loginternal(LogLevel level, string message, bool bypassCheck = false)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			string name = new StackFrame(2).GetMethod().DeclaringType.Name;
			CardDataEditor.ModLogger.Log(level, (object)("[" + name + "] " + message));
		}

		public static void Log(LogLevel level, string message, bool bypassCheck = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Loginternal(level, message, bypassCheck);
		}

		public static void LogInfo(string message, bool bypassCheck = false)
		{
			Loginternal((LogLevel)16, message, bypassCheck);
		}

		public static void LogWarn(string message)
		{
			Loginternal((LogLevel)4, message, bypassCheck: true);
		}

		public static void LogError(string message)
		{
			Loginternal((LogLevel)2, message, bypassCheck: true);
		}
	}
	public class Profiler : MonoBehaviour
	{
		private class ProfilerSection
		{
			public string Name;

			public Stopwatch Stopwatch;

			public int CallCount;

			public Dictionary<string, ProfilerSection> Children;

			public ProfilerSection(string name)
			{
				Name = name;
				Stopwatch = new Stopwatch();
				CallCount = 0;
				Children = new Dictionary<string, ProfilerSection>();
			}

			public void Start()
			{
				Stopwatch.Start();
				CallCount++;
			}

			public void End()
			{
				Stopwatch.Stop();
			}
		}

		private static readonly Stack<ProfilerSection> sectionStack = new Stack<ProfilerSection>();

		private static readonly List<ProfilerSection> rootSections = new List<ProfilerSection>();

		private static Profiler instance;

		private void Awake()
		{
			if (!((Object)(object)instance != (Object)null))
			{
				instance = this;
			}
		}

		public static void Start(string name)
		{
			ProfilerSection value;
			if (sectionStack.Count == 0)
			{
				value = FindOrCreateRoot(name);
			}
			else
			{
				ProfilerSection profilerSection = sectionStack.Peek();
				if (!profilerSection.Children.TryGetValue(name, out value))
				{
					value = new ProfilerSection(name);
					profilerSection.Children.Add(name, value);
				}
			}
			value.Start();
			sectionStack.Push(value);
		}

		public static void End(string name)
		{
			if (sectionStack.Count == 0)
			{
				LoggerUtils.Log((LogLevel)4, "Profiler.End(\"" + name + "\") called without a matching Start().");
				return;
			}
			ProfilerSection profilerSection = sectionStack.Pop();
			if (profilerSection.Name != name)
			{
				LoggerUtils.Log((LogLevel)4, "Profiler section mismatch. Expected End(\"" + profilerSection.Name + "\"), got End(\"" + name + "\").");
			}
			profilerSection.End();
		}

		private static ProfilerSection FindOrCreateRoot(string name)
		{
			foreach (ProfilerSection rootSection in rootSections)
			{
				if (rootSection.Name == name)
				{
					return rootSection;
				}
			}
			ProfilerSection profilerSection = new ProfilerSection(name);
			rootSections.Add(profilerSection);
			return profilerSection;
		}

		private void LateUpdate()
		{
			Log();
		}

		private static void Log()
		{
			if (rootSections.Count == 0)
			{
				return;
			}
			foreach (ProfilerSection rootSection in rootSections)
			{
				LogSection(rootSection, 0);
			}
			rootSections.Clear();
		}

		private static void LogSection(ProfilerSection section, int depth)
		{
			string text = new string(' ', depth * 2);
			double totalMilliseconds = section.Stopwatch.Elapsed.TotalMilliseconds;
			double num = ((section.CallCount > 0) ? (totalMilliseconds / (double)section.CallCount) : 0.0);
			LoggerUtils.Log((LogLevel)32, text + " " + section.Name + ": " + $"Total {totalMilliseconds:F2} ms, " + $"Calls {section.CallCount}, " + $"Avg {num:F4} ms");
			foreach (ProfilerSection value in section.Children.Values)
			{
				LogSection(value, depth + 1);
			}
		}
	}
}
namespace CardDataEditor.DataEditting
{
	public class CardOptions
	{
		public readonly CardInfo Card;

		public readonly Dictionary<Type, CardProperty> Properties = new Dictionary<Type, CardProperty>();

		public CardOptions(CardInfo cardInfo)
		{
			Profiler.Start("CardOptions.CardOptions");
			Card = cardInfo;
			Profiler.End("CardOptions.CardOptions");
		}

		public void AddProperty(Type type)
		{
			Profiler.Start("CardOptions.AddProperty");
			if (typeof(CardProperty).IsAssignableFrom(type))
			{
				CardProperty value = (CardProperty)Activator.CreateInstance(type, Card);
				Properties[type] = value;
			}
			Profiler.End("CardOptions.AddProperty");
		}

		public void AddProperty<T>() where T : CardProperty, new()
		{
			Profiler.Start("CardOptions.AddProperty<T>");
			T val = new T();
			if (val.CanShowProperty())
			{
				Properties[typeof(T)] = val;
			}
			Profiler.End("CardOptions.AddProperty<T>");
		}

		public T GetProperty<T>() where T : CardProperty
		{
			if (Properties.TryGetValue(typeof(T), out var value))
			{
				return value as T;
			}
			return null;
		}

		public byte[] Serialize()
		{
			Profiler.Start("CardOptions.Serialize");
			using MemoryStream memoryStream = new MemoryStream();
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			foreach (CardProperty value in Properties.Values)
			{
				byte[] array = value.SerializeValue(value.GetProperty());
				binaryWriter.Write(array.Length);
				binaryWriter.Write(array);
			}
			byte[] result = memoryStream.ToArray();
			Profiler.End("CardOptions.Serialize");
			return result;
		}

		public void Deserialize(byte[] data)
		{
			Profiler.Start("CardOptions.Deserialize");
			using (MemoryStream input = new MemoryStream(data))
			{
				using BinaryReader binaryReader = new BinaryReader(input);
				foreach (CardProperty value in Properties.Values)
				{
					int count = binaryReader.ReadInt32();
					byte[] data2 = binaryReader.ReadBytes(count);
					value.ApplyProperty(value.DeserializeValue(data2));
				}
			}
			Profiler.End("CardOptions.Deserialize");
		}

		public override string ToString()
		{
			return $"CardOptions for {((Object)Card).name} with {Properties.Count} properties.";
		}
	}
}
namespace CardDataEditor.DataEditting.Registries
{
	public static class CardOptionRegistry
	{
		private static Dictionary<CardInfo, CardOptions> cardOptionsRegistry = new Dictionary<CardInfo, CardOptions>();

		private static List<CardInfo> allCards => (from v in CardManager.cards.Values
			select v.cardInfo into c
			orderby c.cardName
			select c).ToList();

		public static IEnumerable<CardOptions> AllCardOptions => cardOptionsRegistry.Values;

		internal static void RegisterAllCardOptions()
		{
			Profiler.Start("RegisterAllCardOptions");
			foreach (CardInfo allCard in allCards)
			{
				RegisterCardOptions(allCard);
			}
			Profiler.End("RegisterAllCardOptions");
		}

		public static void RegisterCardOptions(CardInfo cardInfo)
		{
			Profiler.Start("RegisterCardOptions");
			if (!cardOptionsRegistry.ContainsKey(cardInfo))
			{
				CardOptions cardOptions = new CardOptions(cardInfo);
				PropertyRegistry.AddProperties(cardOptions);
				cardOptionsRegistry[cardInfo] = cardOptions;
			}
			Profiler.End("RegisterCardOptions");
		}

		public static CardOptions GetCardOptions(CardInfo cardInfo)
		{
			if (cardOptionsRegistry.TryGetValue(cardInfo, out var value))
			{
				return value;
			}
			return null;
		}

		public static byte[] Serialize()
		{
			Profiler.Start("CardOptionRegistry.Serialize");
			using MemoryStream memoryStream = new MemoryStream();
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			binaryWriter.Write(cardOptionsRegistry.Values.Count);
			foreach (CardOptions value in cardOptionsRegistry.Values)
			{
				binaryWriter.Write(((Object)value.Card).name);
				byte[] array = value.Serialize();
				binaryWriter.Write(array.Length);
				binaryWriter.Write(array);
			}
			byte[] result = memoryStream.ToArray();
			Profiler.End("CardOptionRegistry.Serialize");
			return result;
		}

		public static void Deserialize(byte[] data)
		{
			Profiler.Start("CardOptionRegistry.Deserialize");
			using (MemoryStream input = new MemoryStream(data))
			{
				using BinaryReader binaryReader = new BinaryReader(input);
				int num = binaryReader.ReadInt32();
				for (int i = 0; i < num; i++)
				{
					string text = binaryReader.ReadString();
					CardInfo cardWithObjectName = Cards.instance.GetCardWithObjectName(text);
					if ((Object)(object)cardWithObjectName == (Object)null)
					{
						LoggerUtils.Log((LogLevel)4, "Could not find CardInfo for card '" + text + "', skipping deserialization for this card.");
						continue;
					}
					CardOptions cardOptions = cardOptionsRegistry[cardWithObjectName];
					int num2 = binaryReader.ReadInt32();
					byte[] array = binaryReader.ReadBytes(num2);
					if (array.Length != num2)
					{
						LoggerUtils.Log((LogLevel)4, $"Expected {num2} bytes for card '{text}', but only read {array.Length} bytes. Skipping deserialization for this card.");
					}
					else
					{
						cardOptions.Deserialize(array);
					}
				}
			}
			Profiler.End("CardOptionRegistry.Deserialize");
		}
	}
	public static class PropertyRegistry
	{
		private static readonly List<Type> registeredProperties = new List<Type>();

		private static readonly Dictionary<CardInfo, List<Type>> registeredCardProperties = new Dictionary<CardInfo, List<Type>>();

		internal static void RegisterDefaultProperties()
		{
			RegisterProperty<RarityCardProperty>();
			RegisterProperty<ThemeCardProperty>();
			RegisterProperty<DetachClassProperty>();
			RegisterProperty<AmountCardProperty>();
			if (CardDataEditor.Plugins.Exists((BaseUnityPlugin plugin) => plugin.Info.Metadata.GUID == "com.willuwontu.rounds.managers"))
			{
				RegisterProperty<DetechCurseProperty>();
			}
		}

		public static void RegisterProperty<T>() where T : CardProperty
		{
			Type typeFromHandle = typeof(T);
			if (registeredProperties.Contains(typeFromHandle))
			{
				throw new InvalidOperationException("The card property '" + typeFromHandle.Name + "' is already registered globally.");
			}
			registeredProperties.Add(typeFromHandle);
		}

		public static void RegisterPropertyForCard<T>(CardInfo card) where T : CardProperty
		{
			if ((Object)(object)card == (Object)null)
			{
				throw new ArgumentNullException("card");
			}
			Type typeFromHandle = typeof(T);
			if (registeredProperties.Contains(typeFromHandle))
			{
				throw new InvalidOperationException("The card property '" + typeFromHandle.Name + "' is already registered globally and cannot be registered specifically for card '" + ((Object)card).name + "'.");
			}
			if (!registeredCardProperties.TryGetValue(card, out var value))
			{
				value = new List<Type>();
				registeredCardProperties.Add(card, value);
			}
			if (value.Contains(typeFromHandle))
			{
				throw new InvalidOperationException("The card property '" + typeFromHandle.Name + "' is already registered for card '" + ((Object)card).name + "'.");
			}
			value.Add(typeFromHandle);
		}

		public static void AddProperties(CardOptions cardOptions)
		{
			foreach (Type registeredProperty in registeredProperties)
			{
				cardOptions.AddProperty(registeredProperty);
			}
			if (!registeredCardProperties.TryGetValue(cardOptions.Card, out var value))
			{
				return;
			}
			foreach (Type item in value)
			{
				cardOptions.AddProperty(item);
			}
		}
	}
}
namespace CardDataEditor.DataEditting.Properties
{
	public class AmountCardProperty : CardProperty<int>
	{
		public AmountCardProperty(CardInfo card)
			: base(card)
		{
		}

		public override GameObject CreateUIProperty(CardPropertyConfigEntry entry)
		{
			GameObject obj = Object.Instantiate<GameObject>(((Component)UIPropetyRegsitry.Instance.UIIntPropertyPrefab).gameObject);
			obj.GetComponent<UIIntProperty>().Init((CardPropertyConfigEntry<int>)entry);
			return obj;
		}

		public override string GetCategoryName()
		{
			return "Basic";
		}

		public override string GetPropertyName()
		{
			return "Card Limit";
		}

		public override string GetSerializeName()
		{
			return "Amount";
		}

		public override void ApplyProperty(int value)
		{
			ClassObject val = ClassesRegistry.Get(base.Card);
			if (val == null)
			{
				val = ClassesRegistry.Register(base.Card, (CardType)32, value);
			}
			val.cap = value;
			if (value > 1)
			{
				base.Card.allowMultiple = true;
			}
			else if (value > 0)
			{
				base.Card.allowMultiple = false;
			}
			else if (value <= 0)
			{
				base.Card.allowMultiple = true;
			}
		}

		public override int GetPropertyTyped()
		{
			return ClassesRegistry.Get(base.Card)?.cap ?? ((!base.Card.allowMultiple) ? 1 : 0);
		}

		public override byte[] SerializeValueTyped(int value)
		{
			return BitConverter.GetBytes(value);
		}

		public override int DeserializeValueTyped(byte[] data)
		{
			return BitConverter.ToInt32(data, 0);
		}
	}
	public abstract class CardProperty
	{
		public CardInfo Card { get; private set; }

		public CardProperty(CardInfo card)
		{
			Card = card;
		}

		public virtual bool CanShowProperty()
		{
			return true;
		}

		public virtual GameObject CreateUIProperty(CardPropertyConfigEntry entry)
		{
			return null;
		}

		public virtual void ApplyPropertyToPreviewCard(GameObject cardObject, CardInfo cardInfo)
		{
		}

		public abstract CardPropertyConfigEntry CreateCardPropertyConfigEntry(CardOptionsConfig configFile);

		public abstract string GetCategoryName();

		public abstract string GetPropertyName();

		public virtual string GetDescription()
		{
			return null;
		}

		public virtual string GetSerializeName()
		{
			return GetPropertyName();
		}

		public abstract void ApplyProperty(object value);

		public abstract object GetProperty();

		public abstract byte[] SerializeValue(object value);

		public abstract object DeserializeValue(byte[] data);
	}
	public abstract class CardProperty<T> : CardProperty
	{
		public CardProperty(CardInfo card)
			: base(card)
		{
		}

		public abstract void ApplyProperty(T value);

		public abstract T GetPropertyTyped();

		public abstract byte[] SerializeValueTyped(T value);

		public abstract T DeserializeValueTyped(byte[] data);

		public override CardPropertyConfigEntry CreateCardPropertyConfigEntry(CardOptionsConfig configFile)
		{
			return new CardPropertyConfigEntry<T>(GetSerializeName(), this, configFile);
		}

		public override void ApplyProperty(object value)
		{
			ApplyProperty((T)value);
		}

		public override object GetProperty()
		{
			return GetPropertyTyped();
		}

		public override byte[] SerializeValue(object value)
		{
			return SerializeValueTyped((T)value);
		}

		public override object DeserializeValue(byte[] data)
		{
			return DeserializeValueTyped(data);
		}
	}
	public class DetachClassProperty : CardProperty<bool>
	{
		private bool haveBeenDetach;

		private readonly CardInfo[][] savedRequiredClassesTree = new CardInfo[1][] { (CardInfo[])(object)new CardInfo[0] };

		private readonly CardType savedCardType = (CardType)32;

		public DetachClassProperty(CardInfo card)
			: base(card)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			ClassObject val = ClassesRegistry.Get(base.Card);
			if (val != null)
			{
				savedRequiredClassesTree = val.RequiredClassesTree;
				savedCardType = val.type;
			}
		}

		public override GameObject CreateUIProperty(CardPropertyConfigEntry entry)
		{
			GameObject obj = Object.Instantiate<GameObject>(((Component)UIPropetyRegsitry.Instance.UIBoolPropertyPrefab).gameObject);
			obj.GetComponent<UIBoolProperty>().Init((CardPropertyConfigEntry<bool>)entry);
			return obj;
		}

		public override string GetCategoryName()
		{
			return "Detachments";
		}

		public override string GetPropertyName()
		{
			return "Detach From Class";
		}

		public override string GetSerializeName()
		{
			return "Detach Class";
		}

		public override void ApplyPropertyToPreviewCard(GameObject cardObject, CardInfo cardInfo)
		{
			ClassObject obj = ClassesRegistry.Get(base.Card);
			ClassNameMono component = cardObject.GetComponent<ClassNameMono>();
			if (obj == null || (Object)(object)component == (Object)null)
			{
				return;
			}
			Transform val = ((Component)((IEnumerable<RectTransform>)cardObject.GetComponentsInChildren<RectTransform>(true)).FirstOrDefault((Func<RectTransform, bool>)((RectTransform x) => ((Object)x).name == "EdgePart (1)"))).transform.Find("ExtraCardText(Clone)");
			if (GetPropertyTyped())
			{
				((Behaviour)component).enabled = false;
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
			else
			{
				((Behaviour)component).enabled = true;
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(true);
				}
			}
		}

		public override bool CanShowProperty()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Invalid comparison between Unknown and I4
			ClassObject val = ClassesRegistry.Get(base.Card);
			if (val != null && (base.Card.categories.Contains(CustomCardCategories.instance.CardCategory("ClassDetachable")) || CardDataEditorConfig.DangerMode.Value))
			{
				if ((int)val.type == 32 || (int)val.type == 1)
				{
					return haveBeenDetach;
				}
				return true;
			}
			return haveBeenDetach;
		}

		public override void ApplyProperty(bool value)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			ClassObject val = ClassesRegistry.Get(base.Card);
			if (val == null)
			{
				return;
			}
			ClassNameMono component = ((Component)base.Card).GetComponent<ClassNameMono>();
			if (value)
			{
				if ((Object)(object)component != (Object)null)
				{
					((Behaviour)component).enabled = false;
				}
				val.RequiredClassesTree = new CardInfo[1][] { (CardInfo[])(object)new CardInfo[0] };
				ExtensionMethods.SetPropertyValue((object)val, "type", (object)(CardType)32);
				haveBeenDetach = true;
			}
			else
			{
				if ((Object)(object)component != (Object)null)
				{
					((Behaviour)component).enabled = true;
				}
				val.RequiredClassesTree = savedRequiredClassesTree;
				ExtensionMethods.SetPropertyValue((object)val, "type", (object)savedCardType);
				haveBeenDetach = false;
			}
		}

		public override bool GetPropertyTyped()
		{
			return haveBeenDetach;
		}

		public override byte[] SerializeValueTyped(bool value)
		{
			return BitConverter.GetBytes(value);
		}

		public override bool DeserializeValueTyped(byte[] data)
		{
			return BitConverter.ToBoolean(data, 0);
		}
	}
	public class DetechCurseProperty : CardProperty<bool>
	{
		private readonly bool hasCurseCategory;

		private bool haveBeenDetach;

		private bool isCurseCard;

		public DetechCurseProperty(CardInfo card)
			: base(card)
		{
			hasCurseCategory = base.Card.categories.Contains(CustomCardCategories.instance.CardCategory("Curse"));
			isCurseCard = CurseManager.instance.IsCurse(base.Card);
		}

		public override GameObject CreateUIProperty(CardPropertyConfigEntry entry)
		{
			GameObject obj = Object.Instantiate<GameObject>(((Component)UIPropetyRegsitry.Instance.UIBoolPropertyPrefab).gameObject);
			obj.GetComponent<UIBoolProperty>().Init((CardPropertyConfigEntry<bool>)entry);
			return obj;
		}

		public override string GetCategoryName()
		{
			return "Detachments";
		}

		public override string GetPropertyName()
		{
			return "Detach From Curse";
		}

		public override string GetSerializeName()
		{
			return "Detach Curse";
		}

		public override bool CanShowProperty()
		{
			bool flag = CurseManager.instance.IsCurse(base.Card);
			if (isCurseCard)
			{
				if (!flag)
				{
					return haveBeenDetach;
				}
				return true;
			}
			return false;
		}

		public override void ApplyProperty(bool value)
		{
			if (!isCurseCard)
			{
				return;
			}
			List<CardInfo> list = (List<CardInfo>)ExtensionMethods.GetFieldValue((object)CurseManager.instance, "curses");
			CardCategory curseCategory = CustomCardCategories.instance.CardCategory("Curse");
			if (value)
			{
				if (hasCurseCategory)
				{
					base.Card.categories = base.Card.categories.Where((CardCategory category) => (Object)(object)category != (Object)(object)curseCategory).ToArray();
				}
				list.Remove(base.Card);
				haveBeenDetach = true;
				return;
			}
			if (hasCurseCategory && !base.Card.categories.Contains(curseCategory))
			{
				base.Card.categories = base.Card.categories.Append(curseCategory).ToArray();
			}
			if (!list.Contains(base.Card))
			{
				list.Add(base.Card);
			}
			haveBeenDetach = false;
		}

		public override bool GetPropertyTyped()
		{
			return haveBeenDetach;
		}

		public override byte[] SerializeValueTyped(bool value)
		{
			return BitConverter.GetBytes(value);
		}

		public override bool DeserializeValueTyped(byte[] data)
		{
			return BitConverter.ToBoolean(data, 0);
		}
	}
	public class RarityCardProperty : CardProperty<Rarity>
	{
		public RarityCardProperty(CardInfo card)
			: base(card)
		{
		}

		public unsafe override GameObject CreateUIProperty(CardPropertyConfigEntry entry)
		{
			GameObject obj = Object.Instantiate<GameObject>(((Component)UIPropetyRegsitry.Instance.UIEnumPropertyPrefab).gameObject);
			UIPropertyDropdown component = obj.GetComponent<UIPropertyDropdown>();
			UIPropertyDropdown.DropdownItem[] array = (from r in Enum.GetValues(typeof(Rarity)).Cast<Rarity>().ToArray()
				select new UIPropertyDropdown.DropdownItem("<color=#" + ColorUtility.ToHtmlStringRGB(GetCardRarityColor(r)) + ">" + ((object)(*(Rarity*)(&r))/*cast due to .constrained prefix*/).ToString().ToUpper() + ((((object)(*(Rarity*)(&r))/*cast due to .constrained prefix*/).ToString() == entry.DefaultValue.ToString()) ? " (Default)" : ""), ((object)(*(Rarity*)(&r))/*cast due to .constrained prefix*/).ToString())).ToArray();
			component.Init(selectedDropdownItem: array.First((UIPropertyDropdown.DropdownItem i) => i.value == entry.Value.ToString()), defaultDropdownItem: array.First((UIPropertyDropdown.DropdownItem i) => i.value == entry.DefaultValue.ToString()), name: GetPropertyName(), dropdownItems: array);
			component.OnValueChanged = (Action<UIPropertyDropdown.DropdownItem>)Delegate.Combine(component.OnValueChanged, (Action<UIPropertyDropdown.DropdownItem>)delegate(UIPropertyDropdown.DropdownItem dropdownItem)
			{
				//IL_002d: 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)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				Rarity val = Enum.GetValues(typeof(Rarity)).Cast<Rarity>().FirstOrDefault((Func<Rarity, bool>)((Rarity r) => ((object)(*(Rarity*)(&r))/*cast due to .constrained prefix*/).ToString() == dropdownItem.value));
				entry.Value = val;
			});
			return obj;
		}

		public override string GetCategoryName()
		{
			return "Basic";
		}

		public override string GetPropertyName()
		{
			return "Rarity";
		}

		public override void ApplyPropertyToPreviewCard(GameObject toggleCardObject, CardInfo toggleCardInfo)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			toggleCardInfo.rarity = GetPropertyTyped();
			toggleCardObject.GetComponentsInChildren<CardRarityColor>(false).ToList().ForEach(delegate(CardRarityColor r)
			{
				r.Toggle(true);
			});
		}

		public override void ApplyProperty(Rarity value)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			base.Card.rarity = value;
		}

		public override Rarity GetPropertyTyped()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return base.Card.rarity;
		}

		public unsafe override byte[] SerializeValueTyped(Rarity rarity)
		{
			return Encoding.UTF8.GetBytes(((object)(*(Rarity*)(&rarity))/*cast due to .constrained prefix*/).ToString());
		}

		public unsafe override Rarity DeserializeValueTyped(byte[] data)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			string value = Encoding.UTF8.GetString(data);
			return Enum.GetValues(typeof(Rarity)).Cast<Rarity>().FirstOrDefault((Func<Rarity, bool>)((Rarity r) => ((object)(*(Rarity*)(&r))/*cast due to .constrained prefix*/).ToString() == value));
		}

		private Color GetCardRarityColor(Rarity rarity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			Color val = RarityUtils.GetRarityData(rarity).color * 0.85f;
			return (((double)Mathf.Max(new float[3] { val.r, val.g, val.b }) < 0.2) ? (Color.white * 0.7f) : val) * 0.85f;
		}
	}
	public class ThemeCardProperty : CardProperty<CardThemeColorType>
	{
		public ThemeCardProperty(CardInfo card)
			: base(card)
		{
		}

		public unsafe override GameObject CreateUIProperty(CardPropertyConfigEntry entry)
		{
			GameObject obj = Object.Instantiate<GameObject>(((Component)UIPropetyRegsitry.Instance.UIEnumPropertyPrefab).gameObject);
			UIPropertyDropdown component = obj.GetComponent<UIPropertyDropdown>();
			UIPropertyDropdown.DropdownItem[] array = (from t in Enum.GetValues(typeof(CardThemeColorType)).Cast<CardThemeColorType>().ToArray()
				select new UIPropertyDropdown.DropdownItem("<color=#" + ColorUtility.ToHtmlStringRGB(CardChoice.instance.GetCardColor(t)) + ">" + ((object)(*(CardThemeColorType*)(&t))/*cast due to .constrained prefix*/).ToString().ToUpper() + ((((object)(*(CardThemeColorType*)(&t))/*cast due to .constrained prefix*/).ToString() == entry.DefaultValue.ToString()) ? " (Default)" : ""), ((object)(*(CardThemeColorType*)(&t))/*cast due to .constrained prefix*/).ToString())).ToArray();
			component.Init(selectedDropdownItem: array.First((UIPropertyDropdown.DropdownItem i) => i.value == entry.Value.ToString()), defaultDropdownItem: array.First((UIPropertyDropdown.DropdownItem i) => i.value == entry.DefaultValue.ToString()), name: GetPropertyName(), dropdownItems: array);
			component.OnValueChanged = (Action<UIPropertyDropdown.DropdownItem>)Delegate.Combine(component.OnValueChanged, (Action<UIPropertyDropdown.DropdownItem>)delegate(UIPropertyDropdown.DropdownItem dropdownItem)
			{
				//IL_002d: 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)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				CardThemeColorType val = Enum.GetValues(typeof(CardThemeColorType)).Cast<CardThemeColorType>().FirstOrDefault((Func<CardThemeColorType, bool>)((CardThemeColorType r) => ((object)(*(CardThemeColorType*)(&r))/*cast due to .constrained prefix*/).ToString() == dropdownItem.value));
				entry.Value = val;
			});
			return obj;
		}

		public override string GetCategoryName()
		{
			return "Basic";
		}

		public override string GetPropertyName()
		{
			return "Theme";
		}

		public override void ApplyPropertyToPreviewCard(GameObject toggleCardObject, CardInfo toggleCardInfo)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			toggleCardInfo.colorTheme = GetPropertyTyped();
			CardVisuals componentInChildren = toggleCardObject.GetComponentInChildren<CardVisuals>(false);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.images.ToList().ForEach(delegate(Image t)
				{
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					((Graphic)t).color = CardChoice.instance.GetCardColor(toggleCardInfo.colorTheme);
				});
				((Graphic)componentInChildren.nameText).color = CardChoice.instance.GetCardColor(toggleCardInfo.colorTheme);
			}
		}

		public override void ApplyProperty(CardThemeColorType value)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			base.Card.colorTheme = value;
		}

		public override CardThemeColorType GetPropertyTyped()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return base.Card.colorTheme;
		}

		public unsafe override byte[] SerializeValueTyped(CardThemeColorType theme)
		{
			return Encoding.UTF8.GetBytes(((object)(*(CardThemeColorType*)(&theme))/*cast due to .constrained prefix*/).ToString());
		}

		public unsafe override CardThemeColorType DeserializeValueTyped(byte[] data)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			string value = Encoding.UTF8.GetString(data);
			return Enum.GetValues(typeof(CardThemeColorType)).Cast<CardThemeColorType>().FirstOrDefault((Func<CardThemeColorType, bool>)((CardThemeColorType r) => ((object)(*(CardThemeColorType*)(&r))/*cast due to .constrained prefix*/).ToString() == value));
		}
	}
}
namespace CardDataEditor.DataEditting.Config
{
	public class CardOptionsConfig
	{
		public readonly List<CardOptionsConfigCategory> Categories = new List<CardOptionsConfigCategory>();

		private const string ConfigFileName = "CardOptions.bin";

		private const string ConfigFolderName = "CardDataEditor";

		public bool SaveOnChange = true;

		private static string ConfigPath => Path.Combine(Paths.ConfigPath, "CardDataEditor", "CardOptions.bin");

		public static bool DoesConfigFileExists => File.Exists(ConfigPath);

		public event Action<CardOptionsConfigCategory, CardPropertyConfigEntry> CategoryChanged;

		public CardOptionsConfigCategory AddCategory(CardOptions cardOptions)
		{
			CardOptionsConfigCategory category = new CardOptionsConfigCategory(cardOptions, this);
			category.OnEntryChanged += delegate(CardPropertyConfigEntry entry)
			{
				this.CategoryChanged?.Invoke(category, entry);
				if (SaveOnChange)
				{
					SaveConfig();
				}
			};
			Categories.Add(category);
			return category;
		}

		public void SaveConfig()
		{
			Profiler.Start("CardOptionsConfig.SaveConfig");
			string directoryName = Path.GetDirectoryName(ConfigPath);
			if (!Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			using (FileStream output = new FileStream(ConfigPath, FileMode.Create, FileAccess.Write, FileShare.None))
			{
				using BinaryWriter binaryWriter = new BinaryWriter(output);
				CardOptionsConfigCategory[] array = Categories.Where((CardOptionsConfigCategory category) => !category.IsDefaultValues).ToArray();
				binaryWriter.Write((byte)1);
				binaryWriter.Write((ushort)array.Length);
				CardOptionsConfigCategory[] array2 = array;
				foreach (CardOptionsConfigCategory cardOptionsConfigCategory in array2)
				{
					if (!cardOptionsConfigCategory.IsDefaultValues)
					{
						string name = ((Object)cardOptionsConfigCategory.CardOptions.Card).name;
						binaryWriter.Write(name);
						byte[] array3 = cardOptionsConfigCategory.SerializeCategory();
						binaryWriter.Write(array3.Length);
						binaryWriter.Write(array3);
					}
				}
			}
			Profiler.End("CardOptionsConfig.SaveConfig");
		}

		public void SyncWithConfig()
		{
			Profiler.Start("CardOptionsConfig.SyncWithConfig");
			foreach (CardOptionsConfigCategory category in Categories)
			{
				category.SyncWithConfig();
			}
			Profiler.End("CardOptionsConfig.SyncWithConfig");
		}

		public void LoadConfig()
		{
			Profiler.Start("CardOptionsConfig.LoadConfig");
			if (!File.Exists(ConfigPath))
			{
				return;
			}
			SaveOnChange = false;
			using (FileStream fileStream = new FileStream(ConfigPath, FileMode.Open, FileAccess.Read, FileShare.Read))
			{
				using BinaryReader binaryReader = new BinaryReader(fileStream);
				byte b = binaryReader.ReadByte();
				if (b != 1)
				{
					throw new InvalidDataException($"Unsupported CardOptionsConfig version: {b}");
				}
				ushort num = binaryReader.ReadUInt16();
				if (num < 0)
				{
					throw new InvalidDataException("Invalid category count.");
				}
				for (int i = 0; i < num; i++)
				{
					string text = binaryReader.ReadString();
					int num2 = binaryReader.ReadInt32();
					if (num2 < 0 || num2 > fileStream.Length - fileStream.Position)
					{
						throw new InvalidDataException("Invalid data length for category '" + text + "'.");
					}
					byte[] array = binaryReader.ReadBytes(num2);
					if (array.Length != num2)
					{
						throw new EndOfStreamException("Unexpected end of config while reading category '" + text + "'.");
					}
					CardOptionsConfigCategory cardOptionsConfigCategory = FindCategory(text);
					if (cardOptionsConfigCategory == null)
					{
						LoggerUtils.Log((LogLevel)4, "Unknow category name '" + text + "', skipping category.");
					}
					else
					{
						cardOptionsConfigCategory.DeserializeCategory(array);
					}
				}
			}
			SaveOnChange = true;
			Profiler.End("CardOptionsConfig.LoadConfig");
		}

		public CardOptionsConfigCategory FindCategory(string name)
		{
			foreach (CardOptionsConfigCategory category in Categories)
			{
				if (((Object)category.CardOptions.Card).name == name)
				{
					return category;
				}
			}
			return null;
		}
	}
	public class CardOptionsConfigCategory
	{
		public readonly CardOptions CardOptions;

		public readonly CardOptionsConfig ConfigFile;

		public readonly List<CardPropertyConfigEntry> ConfigEntries = new List<CardPropertyConfigEntry>();

		public bool IsDefaultValues => ConfigEntries.TrueForAll((CardPropertyConfigEntry entry) => entry.IsDefaultValue);

		public event Action<CardPropertyConfigEntry> OnEntryChanged;

		public CardOptionsConfigCategory(CardOptions cardOptions, CardOptionsConfig configFile)
		{
			CardOptions = cardOptions;
			ConfigFile = configFile;
			foreach (CardProperty value in cardOptions.Properties.Values)
			{
				CardPropertyConfigEntry entry = value.CreateCardPropertyConfigEntry(configFile);
				entry.OnValueChanged += delegate
				{
					this.OnEntryChanged(entry);
				};
				ConfigEntries.Add(entry);
			}
		}

		public List<CardPropertyConfigEntry> GetNonDefaultEntries()
		{
			return ConfigEntries.Where((CardPropertyConfigEntry entry) => !entry.IsDefaultValue).ToList();
		}

		public void SyncWithConfig()
		{
			Profiler.Start("CardOptionsConfigCategory.SyncWithConfig");
			foreach (CardPropertyConfigEntry configEntry in ConfigEntries)
			{
				configEntry.SyncWithConfig();
			}
			Profiler.End("CardOptionsConfigCategory.SyncWithConfig");
		}

		public byte[] SerializeCategory()
		{
			Profiler.Start("CardOptionsConfigCategory.SerializeCategory");
			using MemoryStream memoryStream = new MemoryStream();
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			List<CardPropertyConfigEntry> nonDefaultEntries = GetNonDefaultEntries();
			binaryWriter.Write((byte)nonDefaultEntries.Count);
			foreach (CardPropertyConfigEntry item in nonDefaultEntries)
			{
				binaryWriter.Write(item.Name);
				byte[] array = item.SerializeValue();
				binaryWriter.Write(array.Length);
				binaryWriter.Write(array);
			}
			Profiler.End("CardOptionsConfigCategory.SerializeCategory");
			return memoryStream.ToArray();
		}

		public void DeserializeCategory(byte[] data)
		{
			Profiler.Start("CardOptionsConfigCategory.DeserializeCategory");
			using (MemoryStream memoryStream = new MemoryStream(data))
			{
				using BinaryReader binaryReader = new BinaryReader(memoryStream);
				byte b = binaryReader.ReadByte();
				if (b < 0)
				{
					LoggerUtils.Log((LogLevel)2, "Invalid config entry count.");
					return;
				}
				for (int i = 0; i < b; i++)
				{
					string text = binaryReader.ReadString();
					int num = binaryReader.ReadInt32();
					if (num < 0 || num > memoryStream.Length - memoryStream.Position)
					{
						LoggerUtils.Log((LogLevel)4, $"Invalid data length {num} for config entry '{text}'. Skipping entry.");
						continue;
					}
					byte[] array = binaryReader.ReadBytes(num);
					if (array.Length != num)
					{
						LoggerUtils.Log((LogLevel)4, "Unexpected end of data while reading config entry '" + text + "'. Skipping entry.");
						continue;
					}
					CardPropertyConfigEntry entry = GetEntry(text);
					if (entry == null)
					{
						LoggerUtils.Log((LogLevel)4, "Unknow property name '" + text + "', skipping property.");
					}
					else
					{
						entry.DeserializeValue(array);
					}
				}
			}
			Profiler.End("CardOptionsConfigCategory.DeserializeCategory");
		}

		public CardPropertyConfigEntry GetEntry(string name)
		{
			return ConfigEntries.FirstOrDefault((CardPropertyConfigEntry entry) => entry.Name == name);
		}

		public CardPropertyConfigEntry<T> GetEntry<T>()
		{
			return (CardPropertyConfigEntry<T>)ConfigEntries.FirstOrDefault((CardPropertyConfigEntry entry) => entry is CardPropertyConfigEntry<T>);
		}

		public override string ToString()
		{
			return $"CardOptionsConfigCategory: {((Object)CardOptions.Card).name} with {ConfigEntries.Count} entries";
		}
	}
	public static class CardOptionsConfigManager
	{
		public static CardOptionsConfig Config { get; private set; }

		public static event Action<CardOptionsConfig> OnConfigFirstCreated;

		public static void RegisterConfig()
		{
			Profiler.Start("CardOptionsConfigManager.RegisterConfig");
			Config = new CardOptionsConfig();
			try
			{
				LoggerUtils.Log((LogLevel)16, "Loading cards options config...");
				Profiler.Start("CardOptionsConfigManager.RegisterConfig.AddCategories");
				foreach (CardOptions allCardOption in CardOptionRegistry.AllCardOptions)
				{
					Config.AddCategory(allCardOption);
				}
				Profiler.End("CardOptionsConfigManager.RegisterConfig.AddCategories");
				Profiler.Start("CardOptionsConfigManager.RegisterConfig.LoadOrCreate");
				if (!CardOptionsConfig.DoesConfigFileExists)
				{
					CardOptionsConfigManager.OnConfigFirstCreated?.Invoke(Config);
					Config.SaveConfig();
				}
				else
				{
					Config.LoadConfig();
				}
				Profiler.End("CardOptionsConfigManager.RegisterConfig.LoadOrCreate");
				LoggerUtils.Log((LogLevel)16, "CardOptionsConfig loaded successfully.");
			}
			catch (Exception arg)
			{
				LoggerUtils.Log((LogLevel)2, $"Failed to load CardOptionsConfig: {arg}");
				try
				{
					Config.SaveConfig();
				}
				catch (Exception arg2)
				{
					LoggerUtils.Log((LogLevel)2, $"Failed to save new CardOptionsConfig: {arg2}");
				}
			}
			Profiler.End("CardOptionsConfigManager.RegisterConfig");
		}
	}
	public abstract class CardPropertyConfigEntry
	{
		public readonly string Name;

		public readonly CardProperty CardOptionProperty;

		public readonly CardOptionsConfig ConfigFile;

		private object value;

		public object DefaultValue { get; }

		public bool IsDefaultValue => object.Equals(CardOptionProperty.GetProperty(), DefaultValue);

		public object Value
		{
			get
			{
				return value;
			}
			set
			{
				this.value = value;
				CardOptionProperty.ApplyProperty(value);
				this.OnValueChanged?.Invoke();
			}
		}

		public event Action OnValueChanged;

		protected CardPropertyConfigEntry(string name, CardProperty cardOptionProperty, CardOptionsConfig configFile)
		{
			Name = name;
			CardOptionProperty = cardOptionProperty;
			ConfigFile = configFile;
			DefaultValue = cardOptionProperty.GetProperty();
			value = DefaultValue;
		}

		public void SyncWithConfig()
		{
			CardOptionProperty.ApplyProperty(Value);
		}

		public byte[] SerializeValue()
		{
			return CardOptionProperty.SerializeValue(Value);
		}

		public void DeserializeValue(byte[] data)
		{
			Value = CardOptionProperty.DeserializeValue(data);
		}
	}
	public class CardPropertyConfigEntry<T> : CardPropertyConfigEntry
	{
		public readonly CardProperty<T> CardOptionPropertyTyped;

		public readonly T DefaultValueTyped;

		public bool IsDefaultValueTyped => EqualityComparer<T>.Default.Equals(CardOptionPropertyTyped.GetPropertyTyped(), DefaultValueTyped);

		public T ValueTyped
		{
			get
			{
				return (T)base.Value;
			}
			set
			{
				base.Value = value;
			}
		}

		public CardPropertyConfigEntry(string name, CardProperty<T> cardOptionProperty, CardOptionsConfig configFile)
			: base(name, cardOptionProperty, configFile)
		{
			CardOptionPropertyTyped = cardOptionProperty;
			DefaultValueTyped = cardOptionProperty.GetPropertyTyped();
		}

		public byte[] SerializeValueTyped(T value)
		{
			return CardOptionPropertyTyped.SerializeValueTyped(value);
		}

		public T DeserializeValueTyped(byte[] data)
		{
			return CardOptionPropertyTyped.DeserializeValueTyped(data);
		}
	}
}