Decompiled source of FeastPlanner v1.0.0

BepInEx\plugins\FeastPlanner\FeastPlanner.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FeastPlanner.Config;
using FeastPlanner.Core;
using FeastPlanner.Runtime;
using FeastPlanner.UI;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("FeastPlanner")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3d86f14e8a42c9e6f2d9b8523fed2e3759fd3cf6")]
[assembly: AssemblyProduct("FeastPlanner")]
[assembly: AssemblyTitle("FeastPlanner")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FeastPlanner
{
	[BepInPlugin("com.valheimmodlab.feastplanner", "Feast Planner", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[DefaultExecutionOrder(-900)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.valheimmodlab.feastplanner";

		public const string PluginName = "Feast Planner";

		public const string PluginVersion = "1.0.0";

		private FeastPlannerConfig? _config;

		private FeastPlannerController? _controller;

		private FeastPlannerShell? _shell;

		private ManualLogSource? _log;

		private void Awake()
		{
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			_log = ((BaseUnityPlugin)this).Logger;
			_config = FeastPlannerConfig.Bind(((BaseUnityPlugin)this).Config);
			FoodTierTable tierTable = VanillaFoodTierTable.CreateDefault();
			JsonSavedMealStore savedMealStore = new JsonSavedMealStore(Path.Combine(Paths.ConfigPath, "FeastPlanner", "custom-meals-v1.json"));
			_controller = new FeastPlannerController(new ValheimFoodLoader(tierTable), new ValheimInventoryReader(), new ValheimContainerReader(new ContainerInventoryScanner(new ContainerScanRules(_config.ContainerScanRadius.Value, _config.ContainerScanMaxContainers.Value, _config.ContainerScanCooldownSeconds.Value))), new ValheimKnowledgeReader(), new ValheimActiveFoodReader(), new FeastRecommendationEngine(tierTable), tierTable, savedMealStore);
			_shell = new FeastPlannerShell(((BaseUnityPlugin)this).Logger, (PlannerRole role, TargetBiome biome) => _controller.BuildViewModel(role, biome), delegate(PlannerViewMode mode)
			{
				_controller.SetMode(mode);
			}, delegate(string mealId)
			{
				_controller.SelectSavedMeal(mealId);
			}, delegate
			{
				_controller.DeleteSelectedMeal();
			}, delegate(string name)
			{
				_controller.RenameSelectedMeal(name);
			}, delegate(int slotIndex, string foodPrefabName, PlannerRole role, TargetBiome biome)
			{
				_controller.AssignFoodToSlot(slotIndex, foodPrefabName, role, biome);
			}, delegate(string? savedMealId, string name, IReadOnlyList<string> foodPrefabNames, PlannerRole role, TargetBiome biome)
			{
				_controller.SaveCustomMealDraft(savedMealId, name, foodPrefabNames, role, biome);
			});
			_shell.Register();
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Press {2} to open the planner.", "Feast Planner", "1.0.0", _config.TogglePlanner.Value));
		}

		private void OnDestroy()
		{
			_shell?.Dispose();
		}

		private void Update()
		{
			//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)
			if (_config == null)
			{
				return;
			}
			KeyboardShortcut value = _config.TogglePlanner.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				try
				{
					_controller?.RefreshCatalog();
				}
				catch (Exception arg)
				{
					ManualLogSource? log = _log;
					if (log != null)
					{
						log.LogError((object)$"Failed to refresh Feast Planner catalog: {arg}");
					}
				}
				try
				{
					_shell?.Toggle();
				}
				catch (Exception arg2)
				{
					ManualLogSource? log2 = _log;
					if (log2 != null)
					{
						log2.LogError((object)$"Failed to toggle Feast Planner shell: {arg2}");
					}
				}
			}
			FeastPlannerShell? shell = _shell;
			if (shell != null && shell.IsOpen && Input.GetKeyDown((KeyCode)27))
			{
				_shell.Close();
			}
			_shell?.UpdateInputBlock();
		}
	}
}
namespace FeastPlanner.UI
{
	public sealed class CustomEditDraft
	{
		public string? SavedMealId { get; }

		public string Name { get; }

		public IReadOnlyList<string> Slots { get; }

		public IReadOnlyList<string> FoodPrefabNames => new ReadOnlyCollection<string>(Slots.Where((string slot) => !string.IsNullOrWhiteSpace(slot)).ToList());

		public bool HasUnsavedChanges { get; }

		public bool RequiresDiscardConfirmation => HasUnsavedChanges;

		public string DiscardText
		{
			get
			{
				if (!RequiresDiscardConfirmation)
				{
					return string.Empty;
				}
				return "Discard changes?";
			}
		}

		private CustomEditDraft(string? savedMealId, string name, IEnumerable<string> slots, bool hasUnsavedChanges)
		{
			SavedMealId = savedMealId;
			Name = SavedMealLibrary.CleanName(name);
			Slots = new ReadOnlyCollection<string>(NormalizeSlots(slots).ToList());
			HasUnsavedChanges = hasUnsavedChanges;
		}

		public static CustomEditDraft New(string name)
		{
			return new CustomEditDraft(null, name, Array.Empty<string>(), hasUnsavedChanges: false);
		}

		public static CustomEditDraft FromSavedMeal(SavedMeal meal)
		{
			return new CustomEditDraft(meal.Id, meal.Name, meal.FoodPrefabNames, hasUnsavedChanges: false);
		}

		public static CustomEditDraft FromValues(string? savedMealId, string name, IEnumerable<string> foodPrefabNames)
		{
			return new CustomEditDraft(savedMealId, name, foodPrefabNames, hasUnsavedChanges: false);
		}

		public CustomEditDraft WithName(string name)
		{
			return new CustomEditDraft(SavedMealId, name, Slots, hasUnsavedChanges: true);
		}

		public CustomEditDraft WithSlot(int slotIndex, string foodPrefabName)
		{
			if (slotIndex < 0 || slotIndex >= 3)
			{
				return this;
			}
			List<string> list = Slots.ToList();
			list[slotIndex] = (foodPrefabName ?? string.Empty).Trim();
			return new CustomEditDraft(SavedMealId, Name, list, hasUnsavedChanges: true);
		}

		public CustomEditDraft ClearDraft()
		{
			return new CustomEditDraft(SavedMealId, Name, Array.Empty<string>(), hasUnsavedChanges: true);
		}

		public CustomEditDraft MarkSaved(string savedMealId)
		{
			return new CustomEditDraft(savedMealId, Name, Slots, hasUnsavedChanges: false);
		}

		private static IEnumerable<string> NormalizeSlots(IEnumerable<string> slots)
		{
			List<string> list = (from slot in (slots ?? Array.Empty<string>()).Take(3)
				select slot?.Trim() ?? string.Empty).ToList();
			while (list.Count < 3)
			{
				list.Add(string.Empty);
			}
			return list;
		}
	}
	public sealed class CustomFoodPickerProjection
	{
		public IReadOnlyList<FoodPickerRow> Rows { get; }

		public FoodPickerRow? PreviewRow { get; }

		public int PageIndex { get; }

		public int PageCount { get; }

		public bool HasPreviousPage => PageIndex > 0;

		public bool HasNextPage => PageIndex + 1 < PageCount;

		public string PageText => $"Page {PageIndex + 1}/{PageCount}";

		private CustomFoodPickerProjection(IReadOnlyList<FoodPickerRow> rows, FoodPickerRow? previewRow, int pageIndex, int pageCount)
		{
			Rows = rows;
			PreviewRow = previewRow;
			PageIndex = pageIndex;
			PageCount = pageCount;
		}

		public static CustomFoodPickerProjection From(IEnumerable<FoodDefinition> visibleFoods, string searchText, FoodPickerCategory category, TargetBiome? biomeFilter, int pageIndex, int pageSize, string? previewPrefabName = null)
		{
			int num = Math.Max(1, pageSize);
			List<FoodDefinition> list = SavedMealFoodPicker.Filter(visibleFoods, searchText, biomeFilter, category).ToList();
			int num2 = Math.Max(1, (int)Math.Ceiling((double)list.Count / (double)num));
			int num3 = Math.Max(0, Math.Min(pageIndex, num2 - 1));
			List<FoodDefinition> source = list.Skip(num3 * num).Take(num).ToList();
			FoodDefinition previewFood = source.FirstOrDefault((FoodDefinition food) => string.Equals(food.PrefabName, previewPrefabName, StringComparison.OrdinalIgnoreCase)) ?? source.FirstOrDefault();
			List<FoodPickerRow> list2 = source.Select((FoodDefinition food) => FoodPickerRow.From(food, previewFood != null && string.Equals(food.PrefabName, previewFood.PrefabName, StringComparison.OrdinalIgnoreCase))).ToList();
			return new CustomFoodPickerProjection(previewRow: list2.FirstOrDefault((FoodPickerRow row) => row.IsPreviewed), rows: new ReadOnlyCollection<FoodPickerRow>(list2), pageIndex: num3, pageCount: num2);
		}
	}
	public sealed class FoodPickerRow
	{
		private sealed class PickerIngredientPreviewBuilder
		{
			public string PrefabName { get; }

			public string DisplayName { get; }

			public Sprite? Icon { get; }

			public int Amount { get; set; }

			public PickerIngredientPreviewBuilder(string prefabName, string displayName, Sprite? icon)
			{
				PrefabName = prefabName;
				DisplayName = displayName;
				Icon = icon;
			}

			public PickerIngredientPreview ToPreview()
			{
				return new PickerIngredientPreview(PrefabName, DisplayName, Amount, Icon);
			}
		}

		public string PrefabName { get; }

		public string DisplayName { get; }

		public string DisplayText { get; }

		public string StatsText { get; }

		public string HealingText { get; }

		public string DurationText { get; }

		public string InlineStatsText { get; }

		public IReadOnlyList<PickerIngredientPreview> Ingredients { get; }

		public IReadOnlyList<string> IngredientTexts => Ingredients.Select((PickerIngredientPreview ingredient) => ingredient.DisplayText).ToList();

		public bool IsPreviewed { get; }

		public Sprite? Icon { get; }

		private FoodPickerRow(string prefabName, string displayName, string displayText, string statsText, string healingText, string durationText, string inlineStatsText, IReadOnlyList<PickerIngredientPreview> ingredients, bool isPreviewed, Sprite? icon)
		{
			PrefabName = prefabName;
			DisplayName = displayName;
			DisplayText = displayText;
			StatsText = statsText;
			HealingText = healingText;
			DurationText = durationText;
			InlineStatsText = inlineStatsText;
			Ingredients = ingredients;
			IsPreviewed = isPreviewed;
			Icon = icon;
		}

		public static FoodPickerRow From(FoodDefinition food, bool isPreviewed = false)
		{
			return new FoodPickerRow(food.PrefabName, food.DisplayName, TruncateText(food.DisplayName, 30), $"H{food.Stats.Health:0} S{food.Stats.Stamina:0} E{food.Stats.Eitr:0}", $"HP/s {food.Stats.Healing:0.#}", FormatDuration(food.Stats.Duration), $"H{food.Stats.Health:0} S{food.Stats.Stamina:0} E{food.Stats.Eitr:0} HP/s {food.Stats.Healing:0.#} {FormatDuration(food.Stats.Duration)}", FlattenIngredients(food.Ingredients), isPreviewed, food.Icon);
		}

		private static IReadOnlyList<PickerIngredientPreview> FlattenIngredients(IReadOnlyList<FoodIngredient> ingredients)
		{
			Dictionary<string, PickerIngredientPreviewBuilder> flattened = new Dictionary<string, PickerIngredientPreviewBuilder>(StringComparer.OrdinalIgnoreCase);
			List<PickerIngredientPreviewBuilder> list = new List<PickerIngredientPreviewBuilder>();
			foreach (FoodIngredient ingredient in ingredients)
			{
				AddFlattenedIngredient(flattened, list, ingredient, ingredient.Amount);
			}
			return list.Select((PickerIngredientPreviewBuilder value) => value.ToPreview()).ToList();
		}

		private static void AddFlattenedIngredient(Dictionary<string, PickerIngredientPreviewBuilder> flattened, List<PickerIngredientPreviewBuilder> ordered, FoodIngredient ingredient, int requiredAmount)
		{
			if (ingredient.HasRecipe)
			{
				int num = (int)Math.Ceiling((double)requiredAmount / (double)ingredient.OutputAmount);
				{
					foreach (FoodIngredient recipeIngredient in ingredient.RecipeIngredients)
					{
						AddFlattenedIngredient(flattened, ordered, recipeIngredient, recipeIngredient.Amount * num);
					}
					return;
				}
			}
			if (!flattened.TryGetValue(ingredient.PrefabName, out PickerIngredientPreviewBuilder value))
			{
				value = new PickerIngredientPreviewBuilder(ingredient.PrefabName, ingredient.DisplayName, ingredient.Icon);
				ordered.Add(value);
			}
			value.Amount += requiredAmount;
			flattened[ingredient.PrefabName] = value;
		}

		private static string FormatDuration(float durationSeconds)
		{
			int num = Math.Max(0, (int)Math.Round(durationSeconds / 60f));
			return $"{num}m";
		}

		private static string TruncateText(string value, int maxCharacters)
		{
			if (value.Length <= maxCharacters)
			{
				return value;
			}
			if (maxCharacters > 3)
			{
				return value.Substring(0, maxCharacters - 3) + "...";
			}
			return value.Substring(0, maxCharacters);
		}
	}
	public sealed class PickerIngredientPreview
	{
		public string PrefabName { get; }

		public string DisplayName { get; }

		public int Amount { get; }

		public Sprite? Icon { get; }

		public string DisplayText => $"{DisplayName} x{Amount:0}";

		public PickerIngredientPreview(string prefabName, string displayName, int amount, Sprite? icon)
		{
			PrefabName = prefabName;
			DisplayName = displayName;
			Amount = Math.Max(0, amount);
			Icon = icon;
		}
	}
	public sealed class CustomPlanProjection
	{
		private const int MaxRows = 8;

		public IReadOnlyList<CustomPlanRow> Rows { get; }

		private CustomPlanProjection(IEnumerable<CustomPlanRow> rows)
		{
			Rows = new ReadOnlyCollection<CustomPlanRow>(rows.Take(8).ToList());
		}

		public static CustomPlanProjection From(FeastPlannerViewModel model, string activeTargetName, string? pendingDeleteSavedMealId)
		{
			Dictionary<string, FoodDefinition> visibleByPrefab = model.VisibleFoods.GroupBy<FoodDefinition, string>((FoodDefinition food) => food.PrefabName, StringComparer.OrdinalIgnoreCase).ToDictionary<IGrouping<string, FoodDefinition>, string, FoodDefinition>((IGrouping<string, FoodDefinition> group) => group.Key, (IGrouping<string, FoodDefinition> group) => group.First(), StringComparer.OrdinalIgnoreCase);
			return new CustomPlanProjection(model.SavedMeals.Select((SavedMeal meal) => CustomPlanRow.From(meal, visibleByPrefab, string.Equals(meal.Id, model.SelectedSavedMealId, StringComparison.OrdinalIgnoreCase), string.Equals(meal.Name, activeTargetName, StringComparison.OrdinalIgnoreCase), string.Equals(meal.Id, pendingDeleteSavedMealId, StringComparison.OrdinalIgnoreCase))));
		}
	}
	public sealed class CustomPlanRow
	{
		public string Id { get; }

		public string Name { get; }

		public IReadOnlyList<FoodDefinition> Foods { get; }

		public FoodStats Totals { get; }

		public string FoodsText { get; }

		public string StatsText { get; }

		public string DurationText { get; }

		public string ReadinessText { get; }

		public bool IsSelected { get; }

		public bool IsActive { get; }

		public bool IsDeletePending { get; }

		private CustomPlanRow(string id, string name, IReadOnlyList<FoodDefinition> foods, FoodStats totals, string foodsText, string statsText, string durationText, string readinessText, bool isSelected, bool isActive, bool isDeletePending)
		{
			Id = id;
			Name = name;
			Foods = foods;
			Totals = totals;
			FoodsText = foodsText;
			StatsText = statsText;
			DurationText = durationText;
			ReadinessText = readinessText;
			IsSelected = isSelected;
			IsActive = isActive;
			IsDeletePending = isDeletePending;
		}

		public static CustomPlanRow From(SavedMeal meal, IReadOnlyDictionary<string, FoodDefinition> visibleByPrefab, bool isSelected, bool isActive, bool isDeletePending)
		{
			List<FoodDefinition> list = new List<FoodDefinition>();
			List<string> list2 = new List<string>();
			int num = 0;
			foreach (string foodPrefabName in meal.FoodPrefabNames)
			{
				if (visibleByPrefab.TryGetValue(foodPrefabName, out FoodDefinition value))
				{
					list.Add(value);
					list2.Add(value.DisplayName);
				}
				else
				{
					num++;
					list2.Add("Hidden saved food");
				}
			}
			FoodStats foodStats = Total(list);
			string readinessText = ((list.Count == 0) ? "Unavailable" : ((num > 0) ? "Warnings" : "Saved"));
			return new CustomPlanRow(meal.Id, meal.Name, new ReadOnlyCollection<FoodDefinition>(list), foodStats, string.Join(", ", list2), FormatStats(foodStats), FormatDuration(foodStats.Duration), readinessText, isSelected, isActive, isDeletePending);
		}

		private static FoodStats Total(IEnumerable<FoodDefinition> foods)
		{
			List<FoodDefinition> list = foods.ToList();
			return new FoodStats(list.Sum((FoodDefinition food) => food.Stats.Health), list.Sum((FoodDefinition food) => food.Stats.Stamina), list.Sum((FoodDefinition food) => food.Stats.Eitr), list.Sum((FoodDefinition food) => food.Stats.Healing), (list.Count == 0) ? 0f : list.Min((FoodDefinition food) => food.Stats.Duration));
		}

		private static string FormatStats(FoodStats stats)
		{
			return $"H {stats.Health:0}  S {stats.Stamina:0}  E {stats.Eitr:0}";
		}

		private static string FormatDuration(float seconds)
		{
			if (!(seconds <= 0f))
			{
				return $"{Math.Round(seconds / 60f):0}m";
			}
			return "0m";
		}
	}
	public sealed class FeastPlannerShell : IDisposable
	{
		private const float PanelWidth = 1260f;

		private const float PanelHeight = 640f;

		private const float HeaderHeight = 74f;

		private const float ActiveStripHeight = 64f;

		private const float FooterHeight = 58f;

		private const float Gutter = 18f;

		private const float LeftColumnRatio = 0.48f;

		private const float BodyPanelHeightBonus = 36f;

		private const float BodyPanelYOffset = 0f;

		private const int RecommendedRowCount = 8;

		private const int CustomRowCount = 8;

		private const int MaxCustomEditIngredientChips = 3;

		private readonly ManualLogSource _log;

		private readonly Func<PlannerRole, TargetBiome, FeastPlannerViewModel> _buildViewModel;

		private readonly Action<PlannerViewMode> _setPlannerMode;

		private readonly Action<string> _selectSavedMeal;

		private readonly Action _deleteSavedMeal;

		private readonly Action<string> _renameSavedMeal;

		private readonly Action<int, string, PlannerRole, TargetBiome> _assignFoodToSlot;

		private readonly Action<string?, string, IReadOnlyList<string>, PlannerRole, TargetBiome> _saveCustomMealDraft;

		private GameObject? _root;

		private Text? _activeTargetLabelText;

		private Text? _activeTargetText;

		private Text? _activeTargetHealthValueText;

		private Text? _activeTargetStaminaValueText;

		private Text? _activeTargetEitrValueText;

		private Text? _activeTargetDurationText;

		private Text? _activeTargetStatusText;

		private GameObject? _roleControlRoot;

		private GameObject? _biomeControlRoot;

		private GameObject? _recommendedTabButton;

		private GameObject? _customTabButton;

		private Text? _roleControlText;

		private Text? _biomeControlText;

		private GameObject? _roleDropdownRoot;

		private GameObject? _biomeDropdownRoot;

		private GameObject? _cookableToggleRoot;

		private Text? _cookableToggleText;

		private Text? _setActiveText;

		private Text? _clearActiveText;

		private GameObject? _deleteCustomButton;

		private Text? _deleteCustomText;

		private GameObject? _editCustomButton;

		private GameObject? _newCustomButton;

		private GameObject? _saveCustomButton;

		private GameObject? _clearDraftButton;

		private GameObject? _discardButton;

		private Text? _discardText;

		private Text? _detailsTitleText;

		private Text? _totalStatsText;

		private Text? _detailsDurationText;

		private Text? _ingredientSummaryText;

		private Text? _detailsHealthText;

		private Text? _detailsStaminaText;

		private Text? _detailsEitrText;

		private Text? _detailsHealthValueText;

		private Text? _detailsStaminaValueText;

		private Text? _detailsEitrValueText;

		private readonly Text?[] _foodDetailTexts = (Text?[])(object)new Text[3];

		private readonly Text?[] _ingredientDetailTexts = (Text?[])(object)new Text[6];

		private readonly Text?[] _rowNameTexts = (Text?[])(object)new Text[8];

		private readonly Text?[] _rowStatsTexts = (Text?[])(object)new Text[8];

		private readonly Text?[] _rowDurationTexts = (Text?[])(object)new Text[8];

		private readonly Text?[] _rowStatusTexts = (Text?[])(object)new Text[8];

		private readonly GameObject?[] _rowButtons = (GameObject?[])(object)new GameObject[8];

		private readonly Image?[,] _rowFoodIcons = new Image[8, 3];

		private readonly Text?[] _customRowNameTexts = (Text?[])(object)new Text[8];

		private readonly Text?[] _customRowStatsTexts = (Text?[])(object)new Text[8];

		private readonly Text?[] _customRowDurationTexts = (Text?[])(object)new Text[8];

		private readonly Text?[] _customRowStatusTexts = (Text?[])(object)new Text[8];

		private readonly Image?[,] _customRowFoodIcons = new Image[8, 3];

		private readonly Text?[] _slotButtonTexts = (Text?[])(object)new Text[3];

		private readonly Text?[] _slotPrimaryTexts = (Text?[])(object)new Text[3];

		private readonly Text?[] _slotStatsTexts = (Text?[])(object)new Text[3];

		private readonly Image?[] _slotFoodIcons = (Image?[])(object)new Image[3];

		private readonly Image?[] _customEditSlotShades = (Image?[])(object)new Image[3];

		private readonly Image?[,] _slotIngredientIcons = new Image[3, 3];

		private readonly Text?[,] _slotIngredientTexts = new Text[3, 3];

		private readonly Text?[] _pickerRowTexts = (Text?[])(object)new Text[5];

		private readonly Image?[] _pickerRowIcons = (Image?[])(object)new Image[5];

		private readonly GameObject?[] _pickerRowButtons = (GameObject?[])(object)new GameObject[5];

		private readonly Image?[] _foodDetailIcons = (Image?[])(object)new Image[3];

		private readonly Image?[] _foodDetailCardShades = (Image?[])(object)new Image[3];

		private readonly Image?[] _ingredientDetailIcons = (Image?[])(object)new Image[6];

		private readonly Image?[] _activeTargetFoodIcons = (Image?[])(object)new Image[3];

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

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

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

		private GameObject? _pickerMenuRoot;

		private InputField? _customNameInput;

		private InputField? _pickerSearchInput;

		private Text? _pickerCategoryText;

		private Text? _pickerBiomeText;

		private Text? _pickerDetailTitleText;

		private Text? _pickerDetailStatsText;

		private Image? _pickerDetailIcon;

		private GameObject? _addPickerFoodButton;

		private GameObject? _pickerCategoryDropdownRoot;

		private GameObject? _pickerBiomeDropdownRoot;

		private Text? _pickerPageText;

		private readonly Image?[] _pickerIngredientIcons = (Image?[])(object)new Image[6];

		private readonly Text?[] _pickerIngredientTexts = (Text?[])(object)new Text[6];

		private RecommendedPlanProjection? _projection;

		private CustomPlanProjection? _customProjection;

		private CustomFoodPickerProjection? _pickerProjection;

		private FeastPlannerViewModel? _latestModel;

		private CustomEditDraft? _editDraft;

		private RecommendedPlanRow? _selectedRow;

		private CustomPlanRow? _selectedCustomRow;

		private int? _selectedCustomFoodIndex;

		private MealCraftability _currentCraftability = MealCraftability.Empty;

		private string _activeTargetName = string.Empty;

		private string? _pendingDeleteSavedMealId;

		private int? _editingSlotIndex;

		private string? _pickerPreviewPrefabName;

		private int _pickerPageIndex;

		private int _lastDetailsFoodCount;

		private PlannerRole _selectedRole = PlannerRole.Balanced;

		private TargetBiome _selectedBiome;

		private PlannerViewMode _selectedMode;

		private FoodPickerCategory _pickerCategory;

		private TargetBiome? _pickerBiomeFilter;

		private bool _discardPending;

		private bool _isCustomEditing;

		private bool _cookableOnly;

		private bool _openRequested;

		private bool _registered;

		public bool IsOpen
		{
			get
			{
				if (RootExists())
				{
					return _root.activeSelf;
				}
				return false;
			}
		}

		public FeastPlannerShell(ManualLogSource log, Func<PlannerRole, TargetBiome, FeastPlannerViewModel> buildViewModel, Action<PlannerViewMode>? setPlannerMode = null, Action<string>? selectSavedMeal = null, Action? deleteSavedMeal = null, Action<string>? renameSavedMeal = null, Action<int, string, PlannerRole, TargetBiome>? assignFoodToSlot = null, Action<string?, string, IReadOnlyList<string>, PlannerRole, TargetBiome>? saveCustomMealDraft = null)
		{
			_log = log;
			_buildViewModel = buildViewModel;
			_setPlannerMode = setPlannerMode ?? ((Action<PlannerViewMode>)delegate
			{
			});
			_selectSavedMeal = selectSavedMeal ?? ((Action<string>)delegate
			{
			});
			_deleteSavedMeal = deleteSavedMeal ?? ((Action)delegate
			{
			});
			_renameSavedMeal = renameSavedMeal ?? ((Action<string>)delegate
			{
			});
			_assignFoodToSlot = assignFoodToSlot ?? ((Action<int, string, PlannerRole, TargetBiome>)delegate
			{
			});
			_saveCustomMealDraft = saveCustomMealDraft ?? ((Action<string, string, IReadOnlyList<string>, PlannerRole, TargetBiome>)delegate
			{
			});
		}

		public void Register()
		{
			if (!_registered)
			{
				GUIManager.OnCustomGUIAvailable += CreateOnGuiAvailable;
				_registered = true;
			}
		}

		public void Toggle()
		{
			SetOpen(!IsOpen);
		}

		public void Close()
		{
			SetOpen(open: false);
		}

		public void SetOpen(bool open)
		{
			_openRequested = open;
			if (!open)
			{
				UpdateInputBlock();
				if (RootExists())
				{
					_root.SetActive(false);
				}
				else
				{
					ForgetRoot();
				}
				return;
			}
			if (!CanShowPanel())
			{
				_openRequested = false;
				if (RootExists())
				{
					_root.SetActive(false);
				}
				else
				{
					ForgetRoot();
				}
				_log.LogDebug((object)"Feast Planner shell open ignored because Valheim HUD/player state is not ready.");
				return;
			}
			if (!RootExists())
			{
				ForgetRoot();
				CreateOnGuiAvailable();
			}
			if (RootExists())
			{
				_root.SetActive(true);
				RefreshRecommendedRows();
			}
		}

		public void Dispose()
		{
			UpdateInputBlock();
			if (_registered)
			{
				GUIManager.OnCustomGUIAvailable -= CreateOnGuiAvailable;
				_registered = false;
			}
			if (RootExists())
			{
				Object.Destroy((Object)(object)_root);
			}
			ForgetRoot();
		}

		private static bool CanShowPanel()
		{
			if (GUIManager.CustomGUIFront != null && Player.m_localPlayer != null)
			{
				return Hud.instance != null;
			}
			return false;
		}

		private void CreateOnGuiAvailable()
		{
			try
			{
				if (_openRequested && !RootExists() && GUIManager.CustomGUIFront != null)
				{
					ForgetRoot();
					Create(GUIManager.CustomGUIFront.transform);
				}
			}
			catch (Exception arg)
			{
				_log.LogError((object)$"Failed to create Feast Planner shell: {arg}");
			}
		}

		private void Create(Transform parent)
		{
			//IL_0013: 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_0027: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			GUIManager instance = GUIManager.Instance;
			_root = instance.CreateWoodpanel(parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 1260f, 640f, false);
			((Object)_root).name = "FeastPlanner_V06Shell";
			CreateShade(_root.transform, "FeastPlanner_RootShade", Vector2.zero, 1224f, 604f, new Color(0.08f, 0.05f, 0.03f, 0.26f));
			CreateHeader();
			CreateRegion("FeastPlanner_ActiveStrip", new Vector2(0f, 218f), 1224f, 64f);
			CreateShade(_root.transform, "FeastPlanner_ActiveIdentityTray", new Vector2(-480f, 218f), 214f, 44f, ActiveTraySurface());
			CreateShade(_root.transform, "FeastPlanner_ActiveFoodTray", new Vector2(-268f, 218f), 132f, 44f, ActiveTraySurface());
			CreateShade(_root.transform, "FeastPlanner_ActiveStatsTray", new Vector2(28f, 218f), 350f, 44f, ActiveTraySurface());
			for (int i = 0; i < 2; i++)
			{
				CreateShade(_root.transform, $"FeastPlanner_ActiveStatDivider_{i + 1}", new Vector2(-24f + (float)i * 118f, 218f), 2f, 32f, SummaryRuleSurface());
			}
			CreateShade(_root.transform, "FeastPlanner_ActiveStatusBadge", new Vector2(474f, 218f), 168f, 44f, ActiveBadgeSurface());
			_activeTargetLabelText = CreateLabel("Active", new Vector2(-548f, 229f), 82f, 18f, 12, instance.ValheimBeige, (TextAnchor)3);
			_activeTargetText = CreateLabel("none", new Vector2(-468f, 210f), 180f, 30f, 18, instance.ValheimYellow, (TextAnchor)3);
			for (int j = 0; j < _activeTargetFoodIcons.Length; j++)
			{
				_activeTargetFoodIcons[j] = CreateIconSlot(_root.transform, new Vector2(-304f + (float)j * 36f, 218f), 28f);
			}
			CreateLabel("Health", new Vector2(-122f, 231f), 74f, 16f, 11, new Color(1f, 0.34f, 0.3f, 0.92f), (TextAnchor)4);
			CreateLabel("Stamina", new Vector2(-4f, 231f), 86f, 16f, 11, new Color(1f, 0.68f, 0.12f, 0.92f), (TextAnchor)4);
			CreateLabel("Eitr", new Vector2(114f, 231f), 74f, 16f, 11, new Color(0.36f, 0.64f, 1f, 0.92f), (TextAnchor)4);
			_activeTargetHealthValueText = CreateLabel("", new Vector2(-122f, 210f), 74f, 26f, 20, new Color(1f, 0.34f, 0.3f, 1f), (TextAnchor)4);
			_activeTargetStaminaValueText = CreateLabel("", new Vector2(-4f, 210f), 86f, 26f, 20, new Color(1f, 0.68f, 0.12f, 1f), (TextAnchor)4);
			_activeTargetEitrValueText = CreateLabel("", new Vector2(114f, 210f), 74f, 26f, 20, new Color(0.36f, 0.64f, 1f, 1f), (TextAnchor)4);
			_activeTargetDurationText = CreateLabel("", new Vector2(474f, 225f), 146f, 22f, 20, instance.ValheimBeige, (TextAnchor)4);
			_activeTargetStatusText = CreateLabel("", new Vector2(474f, 205f), 146f, 20f, 13, instance.ValheimYellow, (TextAnchor)4);
			float num = 408f;
			float num2 = 168f - num / 2f + 0f;
			float num3 = 1206f * 0.48f;
			float num4 = 1206f - num3;
			float num5 = -612f + num3 / 2f;
			float num6 = num5 + num3 / 2f + 18f + num4 / 2f;
			GameObject val = CreateRegion("FeastPlanner_LeftColumn", new Vector2(num5, num2), num3, num);
			GameObject val2 = CreateRegion("FeastPlanner_RightDetails", new Vector2(num6, num2), num4, num);
			GameObject val3 = CreateRegion("FeastPlanner_FooterActions", new Vector2(0f, -273f), 1224f, 58f);
			CreateRecommendedControls(val.transform, num3, num);
			CreateRecommendedRows(val.transform, num3, num);
			CreateCustomRows(val.transform, num3, num);
			CreateRecommendedDetails(val2.transform, num4, num);
			CreateCustomEditMode(val2.transform, num4, num);
			CreateFoodPickerMenu();
			CreateFooterActions(val3.transform);
			_root.SetActive(false);
		}

		private void CreateHeader()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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)
			GUIManager instance = GUIManager.Instance;
			CreateShade(_root.transform, "FeastPlanner_HeaderRule", new Vector2(0f, 256f), 1168f, 2f, new Color(0.46f, 0.3f, 0.13f, 0.45f));
			CreateLabel("Feast Planner", new Vector2(-392f, 282f), 360f, 44f, 32, instance.ValheimBeige, (TextAnchor)3);
			_recommendedTabButton = CreateButton("Recommended", new Vector2(-72f, 282f), 190f, 42f, SelectRecommendedTab);
			_customTabButton = CreateButton("Custom", new Vector2(140f, 282f), 170f, 42f, SelectCustomTab);
			CreateLabel("Inv + Nearby", new Vector2(444f, 282f), 210f, 36f, 20, instance.ValheimBeige, (TextAnchor)5);
			CreateButton("X", new Vector2(588f, 282f), 44f, 44f, Close);
		}

		private void CreateRecommendedControls(Transform parent, float width, float height)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			float width2 = width / 2f - 24f;
			float num = 0f - width / 4f;
			float num2 = width / 4f;
			float num3 = height / 2f - 34f;
			_roleControlRoot = CreateButton("Role: Balanced", parent, new Vector2(num, num3), width2, 34f, ToggleRoleDropdown);
			_roleControlText = _roleControlRoot.GetComponentInChildren<Text>();
			_biomeControlRoot = CreateButton("Biome: Meadows", parent, new Vector2(num2, num3), width2, 34f, ToggleBiomeDropdown);
			_biomeControlText = _biomeControlRoot.GetComponentInChildren<Text>();
			_roleDropdownRoot = CreateRoleDropdown(parent, new Vector2(num, num3 - 126f), width2);
			_biomeDropdownRoot = CreateBiomeDropdown(parent, new Vector2(num2, num3 - 126f), width2);
		}

		private GameObject CreateRoleDropdown(Transform parent, Vector2 position, float width)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			PlannerRole[] array = new PlannerRole[7]
			{
				PlannerRole.Balanced,
				PlannerRole.BossFight,
				PlannerRole.ExploreGather,
				PlannerRole.BuildFarm,
				PlannerRole.MineHaul,
				PlannerRole.MagicEitr,
				PlannerRole.BestAvailable
			};
			GameObject val = CreateDropdownRoot(parent, "FeastPlanner_RoleDropdown", position, width, array.Length);
			for (int i = 0; i < array.Length; i++)
			{
				PlannerRole role = array[i];
				CreateButton(Display(role), val.transform, DropdownOptionPosition(i, array.Length), width - 18f, 26f, delegate
				{
					SelectPlannerRole(role);
				});
			}
			val.SetActive(false);
			return val;
		}

		private GameObject CreateBiomeDropdown(Transform parent, Vector2 position, float width)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			TargetBiome[] array = new TargetBiome[7]
			{
				TargetBiome.Meadows,
				TargetBiome.BlackForest,
				TargetBiome.Swamp,
				TargetBiome.Mountain,
				TargetBiome.Plains,
				TargetBiome.Mistlands,
				TargetBiome.Ashlands
			};
			GameObject val = CreateDropdownRoot(parent, "FeastPlanner_BiomeDropdown", position, width, array.Length);
			for (int i = 0; i < array.Length; i++)
			{
				TargetBiome biome = array[i];
				CreateButton(Display(biome), val.transform, DropdownOptionPosition(i, array.Length), width - 18f, 26f, delegate
				{
					SelectTargetBiome(biome);
				});
			}
			val.SetActive(false);
			return val;
		}

		private GameObject CreatePickerCategoryDropdown(Transform parent, Vector2 position, float width)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			FoodPickerCategory[] array = new FoodPickerCategory[5]
			{
				FoodPickerCategory.All,
				FoodPickerCategory.HealthHeavy,
				FoodPickerCategory.StaminaHeavy,
				FoodPickerCategory.Eitr,
				FoodPickerCategory.BalancedUtility
			};
			GameObject val = CreateDropdownRoot(parent, "FeastPlanner_PickerCategoryDropdown", position, width, array.Length);
			for (int i = 0; i < array.Length; i++)
			{
				FoodPickerCategory category = array[i];
				CreateButton(Display(category), val.transform, DropdownOptionPosition(i, array.Length), width - 18f, 26f, delegate
				{
					SelectPickerCategory(category);
				});
			}
			val.SetActive(false);
			return val;
		}

		private GameObject CreatePickerBiomeDropdown(Transform parent, Vector2 position, float width)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			TargetBiome?[] array = new TargetBiome?[8]
			{
				null,
				TargetBiome.Meadows,
				TargetBiome.BlackForest,
				TargetBiome.Swamp,
				TargetBiome.Mountain,
				TargetBiome.Plains,
				TargetBiome.Mistlands,
				TargetBiome.Ashlands
			};
			GameObject val = CreateDropdownRoot(parent, "FeastPlanner_PickerBiomeDropdown", position, width, array.Length);
			for (int i = 0; i < array.Length; i++)
			{
				TargetBiome? biome = array[i];
				CreateButton(biome.HasValue ? Display(biome.Value) : "Any Biome", val.transform, DropdownOptionPosition(i, array.Length), width - 18f, 26f, delegate
				{
					SelectPickerBiome(biome);
				});
			}
			val.SetActive(false);
			return val;
		}

		private void CreateRecommendedRows(Transform parent, float width, float height)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			_cookableToggleRoot = CreateButton("Cookable Now: Off", parent, new Vector2(0f, height / 2f - 78f), width - 32f, 36f, ToggleCookableOnly);
			_cookableToggleText = _cookableToggleRoot.GetComponentInChildren<Text>();
			float num = 72f;
			float num2 = 14f;
			float num3 = width - 32f;
			float num4 = 96f;
			float num5 = 58f;
			float num6 = 128f;
			float num7 = 46f;
			float num8 = 10f;
			float num9 = 14f;
			float num10 = num3 - num4 - num5 - num6 - num7 - num8 * 4f - num9 * 2f;
			float num11 = 0f - num3 / 2f + num9 + num7 / 2f;
			float num12 = num11 + num7 / 2f + num8 + num10 / 2f;
			float num13 = num12 + num10 / 2f + num8 + num6 / 2f;
			float num14 = num13 + num6 / 2f + num8 + num5 / 2f;
			float num15 = num3 / 2f - num9 - num4 / 2f;
			float num16 = height / 2f - 142f;
			for (int i = 0; i < 8; i++)
			{
				float num17 = num16 - (float)i * (num + num2);
				int index = i;
				GameObject val = CreateButton("", parent, new Vector2(0f, num17), num3, num, delegate
				{
					SelectVisibleRow(index);
				});
				((Object)val).name = $"FeastPlanner_RecommendedRow_{i + 1}";
				_rowButtons[i] = val;
				val.GetComponentInChildren<Text>().text = string.Empty;
				for (int num18 = 0; num18 < 1; num18++)
				{
					_rowFoodIcons[i, num18] = CreateIconSlot(val.transform, new Vector2(num11, 0f), 38f);
				}
				_rowNameTexts[i] = CreateChildLabel(val.transform, "", new Vector2(num12, 0f), num10, num, 15, GUIManager.Instance.ValheimBeige, (TextAnchor)3);
				_rowStatsTexts[i] = CreateChildLabel(val.transform, "", new Vector2(num13, 0f), num6, num, 13, GUIManager.Instance.ValheimBeige, (TextAnchor)4);
				_rowDurationTexts[i] = CreateChildLabel(val.transform, "", new Vector2(num14, 0f), num5, num, 13, GUIManager.Instance.ValheimBeige, (TextAnchor)4);
				_rowStatusTexts[i] = CreateChildLabel(val.transform, "", new Vector2(num15, 0f), num4, num, 13, GUIManager.Instance.ValheimYellow, (TextAnchor)5);
			}
		}

		private void CreateCustomRows(Transform parent, float width, float height)
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			float height2 = 32f;
			float num = width - 32f;
			float num2 = 82f;
			float num3 = 46f;
			float num4 = 116f;
			float num5 = 88f;
			float num6 = 6f;
			float num7 = 10f;
			float num8 = num - num2 - num3 - num4 - num5 - num6 * 4f - num7 * 2f;
			float num9 = 0f - num / 2f + num7 + num5 / 2f;
			float num10 = num9 + num5 / 2f + num6 + num8 / 2f;
			float num11 = num10 + num8 / 2f + num6 + num4 / 2f;
			float num12 = num11 + num4 / 2f + num6 + num3 / 2f;
			float num13 = num / 2f - num7 - num2 / 2f;
			for (int i = 0; i < 8; i++)
			{
				GameObject val = _rowButtons[i];
				if (val != null)
				{
					for (int j = 0; j < 3; j++)
					{
						_customRowFoodIcons[i, j] = CreateIconSlot(val.transform, new Vector2(num9 - 28f + (float)j * 28f, 0f), 24f);
					}
					_customRowNameTexts[i] = CreateChildLabel(val.transform, "", new Vector2(num10, 0f), num8, height2, 14, GUIManager.Instance.ValheimBeige, (TextAnchor)3);
					_customRowStatsTexts[i] = CreateChildLabel(val.transform, "", new Vector2(num11, 0f), num4, height2, 13, GUIManager.Instance.ValheimBeige, (TextAnchor)4);
					_customRowDurationTexts[i] = CreateChildLabel(val.transform, "", new Vector2(num12, 0f), num3, height2, 13, GUIManager.Instance.ValheimBeige, (TextAnchor)4);
					_customRowStatusTexts[i] = CreateChildLabel(val.transform, "", new Vector2(num13, 0f), num2, height2, 13, GUIManager.Instance.ValheimYellow, (TextAnchor)5);
				}
			}
		}

		private void CreateRecommendedDetails(Transform parent, float width, float height)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: 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_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0541: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_060c: Unknown result type (might be due to invalid IL or missing references)
			GUIManager instance = GUIManager.Instance;
			float num = width - 42f;
			float num2 = 0f - num / 2f;
			float num3 = height / 2f - 20f;
			float num4 = num3 - 42f;
			float num5 = num3 - 154f;
			float num6 = num3 - 284f;
			CreateDetailsRowShade(parent, "FeastPlanner_DetailsSummaryRow", new Vector2(0f, num4), num, 98f);
			CreateDetailsAccentShade(parent, "FeastPlanner_DetailsSummaryHeaderStrip", new Vector2(num2 + 124f, num4 + 28f), 190f, 28f, SummaryHeaderSurface());
			CreateDetailsAccentShade(parent, "FeastPlanner_DetailsSummaryRule", new Vector2(0f, num4 + 6f), num - 44f, 2f, SummaryRuleSurface());
			for (int i = 0; i < 2; i++)
			{
				CreateDetailsAccentShade(parent, $"FeastPlanner_DetailsSummaryStatDivider_{i + 1}", new Vector2(num2 + 142f + (float)i * 118f, num4 - 23f), 2f, 42f, SummaryRuleSurface());
			}
			CreateDetailsAccentShade(parent, "FeastPlanner_DetailsDurationBadge", new Vector2(num / 2f - 94f, num4 - 22f), 112f, 44f, SummaryBadgeSurface());
			float num7 = (num - 30f) / 3f;
			for (int j = 0; j < _foodDetailTexts.Length; j++)
			{
				float num8 = num2 + num7 / 2f + (float)j * (num7 + 15f);
				_foodDetailCardShades[j] = CreateDetailsRowShade(parent, $"FeastPlanner_DetailsFoodCard_{j + 1}", new Vector2(num8, num5), num7, 112f);
				AddFoodDetailCardClickHandler(_foodDetailCardShades[j], j);
			}
			CreateDetailsRowShade(parent, "FeastPlanner_DetailsIngredientsRow", new Vector2(0f, num6), num, 132f);
			_detailsTitleText = CreateChildLabel(parent, "Select a plan", new Vector2(num2 + 124f, num4 + 28f), 168f, 24f, 17, instance.ValheimBeige, (TextAnchor)3);
			_totalStatsText = CreateChildLabel(parent, "H 0  S 0  E 0", new Vector2(num2 + 96f, num4 - 32f), 1f, 1f, 1, new Color(1f, 1f, 1f, 0f), (TextAnchor)3);
			_detailsHealthText = CreateChildLabel(parent, "Health", new Vector2(num2 + 80f, num4 - 8f), 92f, 20f, 13, new Color(1f, 0.34f, 0.3f, 0.92f), (TextAnchor)4);
			_detailsStaminaText = CreateChildLabel(parent, "Stamina", new Vector2(num2 + 198f, num4 - 8f), 104f, 20f, 13, new Color(1f, 0.68f, 0.12f, 0.92f), (TextAnchor)4);
			_detailsEitrText = CreateChildLabel(parent, "Eitr", new Vector2(num2 + 316f, num4 - 8f), 92f, 20f, 13, new Color(0.36f, 0.64f, 1f, 0.92f), (TextAnchor)4);
			_detailsHealthValueText = CreateChildLabel(parent, "0", new Vector2(num2 + 80f, num4 - 32f), 92f, 32f, 27, new Color(1f, 0.34f, 0.3f, 1f), (TextAnchor)4);
			_detailsStaminaValueText = CreateChildLabel(parent, "0", new Vector2(num2 + 198f, num4 - 32f), 104f, 32f, 27, new Color(1f, 0.68f, 0.12f, 1f), (TextAnchor)4);
			_detailsEitrValueText = CreateChildLabel(parent, "0", new Vector2(num2 + 316f, num4 - 32f), 92f, 32f, 27, new Color(0.36f, 0.64f, 1f, 1f), (TextAnchor)4);
			_detailsDurationText = CreateChildLabel(parent, "0m", new Vector2(num / 2f - 94f, num4 - 22f), 96f, 40f, 25, instance.ValheimBeige, (TextAnchor)4);
			for (int k = 0; k < _foodDetailTexts.Length; k++)
			{
				float num9 = num2 + num7 / 2f + (float)k * (num7 + 15f);
				_foodDetailIcons[k] = CreateIconSlot(parent, new Vector2(num9, num5 + 28f), 34f);
				_foodDetailTexts[k] = CreateChildLabel(parent, "", new Vector2(num9, num5 - 22f), num7 - 20f, 66f, 13, instance.ValheimBeige, (TextAnchor)1);
				SetRaycastTarget((Graphic?)(object)_foodDetailIcons[k], raycastTarget: false);
				SetRaycastTarget((Graphic?)(object)_foodDetailTexts[k], raycastTarget: false);
				TrackDetailsControl((Component?)(object)_foodDetailIcons[k]);
			}
			_ingredientSummaryText = CreateChildLabel(parent, "Ingredients: none selected", new Vector2(num2 + 160f, num6 + 44f), 286f, 26f, 15, instance.ValheimBeige, (TextAnchor)3);
			float num10 = (num - 44f) / 2f;
			float num11 = num10 - 68f;
			for (int l = 0; l < _ingredientDetailTexts.Length; l++)
			{
				int num12 = l % 2;
				int num13 = l / 2;
				float num14 = num2 + 18f + (float)num12 * num10;
				float num15 = num6 + 16f - (float)num13 * 31f;
				float num16 = num14 + 42f + num11 / 2f;
				_ingredientDetailIcons[l] = CreateIconSlot(parent, new Vector2(num14 + 16f, num15), 22f);
				_ingredientDetailTexts[l] = CreateChildLabel(parent, "", new Vector2(num16, num15), num11, 26f, 13, instance.ValheimBeige, (TextAnchor)3);
				TrackDetailsControl((Component?)(object)_ingredientDetailIcons[l]);
			}
			TrackDetailsControl((Component?)(object)_detailsTitleText);
			TrackDetailsControl((Component?)(object)_totalStatsText);
			TrackDetailsControl((Component?)(object)_detailsDurationText);
			TrackDetailsControl((Component?)(object)_detailsHealthText);
			TrackDetailsControl((Component?)(object)_detailsStaminaText);
			TrackDetailsControl((Component?)(object)_detailsEitrText);
			TrackDetailsControl((Component?)(object)_detailsHealthValueText);
			TrackDetailsControl((Component?)(object)_detailsStaminaValueText);
			TrackDetailsControl((Component?)(object)_detailsEitrValueText);
			TrackDetailsControl((Component?)(object)_ingredientSummaryText);
			Text[] foodDetailTexts = _foodDetailTexts;
			foreach (Text component in foodDetailTexts)
			{
				TrackDetailsControl((Component?)(object)component);
			}
			foodDetailTexts = _ingredientDetailTexts;
			foreach (Text component2 in foodDetailTexts)
			{
				TrackDetailsControl((Component?)(object)component2);
			}
		}

		private void CreateCustomEditMode(Transform parent, float width, float height)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			GUIManager instance = GUIManager.Instance;
			float num = width - 42f;
			float num2 = height / 2f - 40f;
			Image val = CreateShade(parent, "FeastPlanner_CustomEditNameHeaderShade", new Vector2(0f, num2), num, 48f, SummaryHeaderSurface());
			_customEditControls.Add(((Component)val).gameObject);
			Text val2 = CreateChildLabel(parent, "Plan Name", new Vector2(0f - num / 2f + 68f, num2), 118f, 28f, 14, instance.ValheimBeige, (TextAnchor)3);
			_customEditControls.Add(((Component)val2).gameObject);
			_customNameInput = CreateInputField(parent, "Custom meal", new Vector2(92f, num2), num - 184f, 34f);
			((UnityEvent<string>)(object)_customNameInput.onEndEdit).AddListener((UnityAction<string>)delegate(string value)
			{
				RenameCustomDraft(value);
			});
			_customEditControls.Add(((Component)_customNameInput).gameObject);
			for (int num3 = 0; num3 < _slotButtonTexts.Length; num3++)
			{
				int slotIndex = num3;
				float num4 = num2 - 72f - (float)num3 * 86f;
				_customEditSlotShades[num3] = CreateShade(parent, $"FeastPlanner_CustomEditSlotShade_{num3 + 1}", new Vector2(0f, num4), num, 74f, PanelRowSurface());
				_customEditControls.Add(((Component)_customEditSlotShades[num3]).gameObject);
				GameObject val3 = CreateButton(string.Empty, parent, new Vector2(0f, num4), num - 18f, 66f, delegate
				{
					OpenFoodPicker(slotIndex);
				});
				_slotButtonTexts[num3] = val3.GetComponentInChildren<Text>();
				SetRowText(_slotButtonTexts[num3], string.Empty);
				_slotFoodIcons[num3] = CreateIconSlot(val3.transform, new Vector2(0f - num / 2f + 30f, 9f), 34f);
				Text val4 = CreateChildLabel(val3.transform, $"Slot {num3 + 1}", new Vector2(-212f, 14f), 70f, 20f, 12, instance.ValheimYellow, (TextAnchor)3);
				_customEditControls.Add(((Component)val4).gameObject);
				_slotPrimaryTexts[num3] = CreateChildLabel(val3.transform, "Choose food", new Vector2(-82f, 14f), 212f, 24f, 17, instance.ValheimOrange, (TextAnchor)3);
				_slotStatsTexts[num3] = CreateChildLabel(val3.transform, string.Empty, new Vector2(148f, 14f), 260f, 22f, 14, instance.ValheimBeige, (TextAnchor)3);
				for (int num5 = 0; num5 < 3; num5++)
				{
					CreateSlotIngredientChip(val3.transform, slotIndex, num5, new Vector2(0f - num / 2f + 88f + (float)num5 * 126f, -17f));
				}
				_customEditControls.Add(val3);
			}
			Image val5 = CreateShade(parent, "FeastPlanner_CustomEditActionBand", new Vector2(0f, num2 - 338f), num, 52f, PanelRegionSurface());
			_customEditControls.Add(((Component)val5).gameObject);
			_saveCustomButton = CreateButton("Save", parent, new Vector2(0f - num / 2f + 86f, num2 - 338f), 138f, 36f, SaveCustomDraft);
			_clearDraftButton = CreateButton("Clear Draft", parent, new Vector2(0f - num / 2f + 254f, num2 - 338f), 154f, 36f, ClearCustomDraft);
			_discardButton = CreateButton("Cancel", parent, new Vector2(0f - num / 2f + 424f, num2 - 338f), 128f, 36f, ConfirmDiscard);
			_discardText = _discardButton.GetComponentInChildren<Text>();
			_customEditControls.Add(_saveCustomButton);
			_customEditControls.Add(_clearDraftButton);
			_customEditControls.Add(_discardButton);
			SetEditControlsActive(active: false);
		}

		private void CreateSlotIngredientChip(Transform parent, int slotIndex, int chipIndex, Vector2 position)
		{
			//IL_001b: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			Image val = CreateShade(parent, $"FeastPlanner_CustomEditIngredientChip_{slotIndex + 1}_{chipIndex + 1}", position, 112f, 28f, ActiveTraySurface());
			_customEditControls.Add(((Component)val).gameObject);
			_slotIngredientIcons[slotIndex, chipIndex] = CreateIconSlot(parent, new Vector2(position.x - 38f, position.y), 22f);
			_slotIngredientTexts[slotIndex, chipIndex] = CreateChildLabel(parent, string.Empty, new Vector2(position.x + 8f, position.y), 76f, 20f, 11, GUIManager.Instance.ValheimBeige, (TextAnchor)3);
		}

		private void CreateFoodPickerMenu()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: 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_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0575: Unknown result type (might be due to invalid IL or missing references)
			//IL_05be: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0611: Unknown result type (might be due to invalid IL or missing references)
			_pickerMenuRoot = GUIManager.Instance.CreateWoodpanel(_root.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -18f), 760f, 460f, false);
			((Object)_pickerMenuRoot).name = "FeastPlanner_FoodPickerMenu";
			GUIManager instance = GUIManager.Instance;
			CreateShade(_pickerMenuRoot.transform, "FeastPlanner_FoodPickerBackdropShade", new Vector2(0f, -8f), 704f, 390f, new Color(0.035f, 0.024f, 0.016f, 0.16f));
			CreateChildLabel(_pickerMenuRoot.transform, "Choose Food", new Vector2(-243f, 190f), 220f, 34f, 22, instance.ValheimBeige, (TextAnchor)3);
			CreateButton("X", _pickerMenuRoot.transform, new Vector2(338f, 190f), 42f, 36f, CloseFoodPicker);
			Text val = CreateChildLabel(_pickerMenuRoot.transform, "Search", new Vector2(-306f, 145f), 76f, 28f, 15, instance.ValheimBeige, (TextAnchor)3);
			_pickerControls.Add(((Component)val).gameObject);
			_pickerSearchInput = CreateInputField(_pickerMenuRoot.transform, "", new Vector2(34f, 145f), 560f, 34f);
			((UnityEvent<string>)(object)_pickerSearchInput.onValueChanged).AddListener((UnityAction<string>)delegate
			{
				RefreshFoodPicker();
			});
			_pickerControls.Add(((Component)_pickerSearchInput).gameObject);
			_pickerCategoryText = CreateButton("All", _pickerMenuRoot.transform, new Vector2(-278f, 98f), 150f, 32f, TogglePickerCategoryDropdown).GetComponentInChildren<Text>();
			_pickerControls.Add(((Component)((Component)_pickerCategoryText).transform.parent).gameObject);
			_pickerBiomeText = CreateButton("Any Biome", _pickerMenuRoot.transform, new Vector2(-106f, 98f), 170f, 32f, TogglePickerBiomeDropdown).GetComponentInChildren<Text>();
			_pickerControls.Add(((Component)((Component)_pickerBiomeText).transform.parent).gameObject);
			_pickerCategoryDropdownRoot = CreatePickerCategoryDropdown(_pickerMenuRoot.transform, new Vector2(-278f, 2f), 150f);
			_pickerBiomeDropdownRoot = CreatePickerBiomeDropdown(_pickerMenuRoot.transform, new Vector2(-106f, -42f), 170f);
			for (int num = 0; num < _pickerRowTexts.Length; num++)
			{
				int index = num;
				GameObject val2 = CreateButton("", _pickerMenuRoot.transform, new Vector2(-207f, 50f - (float)num * 50f), 292f, 40f, delegate
				{
					PreviewFood(index);
				});
				_pickerRowButtons[num] = val2;
				_pickerRowTexts[num] = val2.GetComponentInChildren<Text>();
				_pickerRowIcons[num] = CreateIconSlot(val2.transform, new Vector2(-122f, 0f), 24f);
				_pickerControls.Add(val2);
			}
			_pickerDetailIcon = CreateIconSlot(_pickerMenuRoot.transform, new Vector2(156f, 78f), 62f);
			_pickerControls.Add(((Component)_pickerDetailIcon).gameObject);
			_pickerDetailTitleText = CreateChildLabel(_pickerMenuRoot.transform, "Select a food", new Vector2(156f, 22f), 332f, 34f, 20, instance.ValheimBeige, (TextAnchor)4);
			_pickerControls.Add(((Component)_pickerDetailTitleText).gameObject);
			_pickerDetailStatsText = CreateChildLabel(_pickerMenuRoot.transform, "", new Vector2(156f, -20f), 332f, 28f, 15, instance.ValheimYellow, (TextAnchor)4);
			_pickerControls.Add(((Component)_pickerDetailStatsText).gameObject);
			for (int num2 = 0; num2 < _pickerIngredientIcons.Length; num2++)
			{
				int num3 = num2 % 3;
				int num4 = num2 / 3;
				CreatePickerIngredientChip(_pickerMenuRoot.transform, num2, new Vector2(36f + (float)num3 * 120f, -86f - (float)num4 * 30f));
			}
			_addPickerFoodButton = CreateButton("Add Food", _pickerMenuRoot.transform, new Vector2(156f, -140f), 148f, 36f, AddPreviewedFood);
			_pickerControls.Add(_addPickerFoodButton);
			GameObject item = CreateButton("Prev", _pickerMenuRoot.transform, new Vector2(-278f, -190f), 104f, 32f, PreviousPickerPage);
			_pickerControls.Add(item);
			_pickerPageText = CreateChildLabel(_pickerMenuRoot.transform, "Page 1/1", new Vector2(0f, -190f), 160f, 28f, 14, instance.ValheimBeige, (TextAnchor)4);
			_pickerControls.Add(((Component)_pickerPageText).gameObject);
			GameObject item2 = CreateButton("Next", _pickerMenuRoot.transform, new Vector2(278f, -190f), 104f, 32f, NextPickerPage);
			_pickerControls.Add(item2);
			SetPickerControlsActive(active: false);
		}

		private void CreatePickerIngredientChip(Transform parent, int chipIndex, Vector2 position)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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)
			_pickerIngredientIcons[chipIndex] = CreateIconSlot(parent, new Vector2(position.x - 36f, position.y), 24f);
			_pickerIngredientTexts[chipIndex] = CreateChildLabel(parent, string.Empty, new Vector2(position.x + 24f, position.y), 86f, 24f, 12, GUIManager.Instance.ValheimBeige, (TextAnchor)3);
			_pickerControls.Add(((Component)_pickerIngredientIcons[chipIndex]).gameObject);
			_pickerControls.Add(((Component)_pickerIngredientTexts[chipIndex]).gameObject);
		}

		private void CreateFooterActions(Transform parent)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			_setActiveText = CreateButton("Set Active", parent, new Vector2(-465f, 0f), 180f, 38f, SetSelectedActive).GetComponentInChildren<Text>();
			_clearActiveText = CreateButton("Clear", parent, new Vector2(-270f, 0f), 130f, 38f, ClearSelectedActive).GetComponentInChildren<Text>();
			_deleteCustomButton = CreateButton("Delete", parent, new Vector2(-120f, 0f), 130f, 38f, DeleteSelectedCustomPlan);
			_deleteCustomText = _deleteCustomButton.GetComponentInChildren<Text>();
			_editCustomButton = CreateButton("Edit", parent, new Vector2(30f, 0f), 110f, 38f, BeginCustomEdit);
			_newCustomButton = CreateButton("New", parent, new Vector2(155f, 0f), 100f, 38f, BeginNewCustomDraft);
		}

		private GameObject CreateRegion(string name, Vector2 position, float width, float height)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GUIManager.Instance.CreateWoodpanel(_root.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), position, width, height, false);
			((Object)obj).name = name;
			CreateShade(obj.transform, name + "_Shade", Vector2.zero, width - 16f, height - 16f, PanelRegionSurface());
			return obj;
		}

		private GameObject CreateDropdownRoot(Transform parent, string name, Vector2 position, float width, int optionCount)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			float num = 18f + (float)optionCount * 30f;
			GameObject obj = GUIManager.Instance.CreateWoodpanel(parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), position, width, num, false);
			((Object)obj).name = name;
			CreateShade(obj.transform, name + "_Shade", Vector2.zero, width - 12f, num - 12f, new Color(0.03f, 0.02f, 0.01f, 0.58f));
			return obj;
		}

		private Image CreateDetailsRowShade(Transform parent, string name, Vector2 position, float width, float height)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Image val = CreateShade(parent, name, position, width - 18f, height, PanelRowSurface());
			TrackDetailsControl((Component?)(object)val);
			return val;
		}

		private Image CreateDetailsAccentShade(Transform parent, string name, Vector2 position, float width, float height, Color color)
		{
			//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)
			Image val = CreateShade(parent, name, position, width, height, color);
			TrackDetailsControl((Component?)(object)val);
			return val;
		}

		private static Vector2 DropdownOptionPosition(int index, int optionCount)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)(optionCount - 1) * 30f / 2f;
			return new Vector2(0f, num - (float)index * 30f);
		}

		private static Image CreateShade(Transform parent, string name, Vector2 position, float width, float height, Color color)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = position;
			component.sizeDelta = new Vector2(width, height);
			Image component2 = val.GetComponent<Image>();
			((Graphic)component2).color = color;
			((Graphic)component2).raycastTarget = false;
			val.transform.SetAsFirstSibling();
			return component2;
		}

		private static Image CreateIconSlot(Transform parent, Vector2 position, float size)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("FeastPlanner_IconSlot", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = position;
			component.sizeDelta = new Vector2(size, size);
			Image component2 = val.GetComponent<Image>();
			component2.type = (Type)1;
			component2.preserveAspect = true;
			((Graphic)component2).raycastTarget = false;
			SetIconSprite(component2, null);
			return component2;
		}

		private static void SetIconSprite(Image? image, Sprite? sprite)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (image != null)
			{
				image.sprite = sprite;
				((Graphic)image).color = (Color)((sprite == null) ? new Color(1f, 1f, 1f, 0f) : Color.white);
			}
		}

		private Text CreateLabel(string text, Vector2 position, float width, float height, int fontSize, Color color, TextAnchor alignment)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			Text component = GUIManager.Instance.CreateText(text, _root.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), position, GUIManager.Instance.AveriaSerifBold, fontSize, color, false, Color.black, width, height, false).GetComponent<Text>();
			component.alignment = alignment;
			SetLongContentTextOptions(component);
			return component;
		}

		private Text CreateChildLabel(Transform parent, string text, Vector2 position, float width, float height, int fontSize, Color color, TextAnchor alignment)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Text component = GUIManager.Instance.CreateText(text, parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), position, GUIManager.Instance.AveriaSerifBold, fontSize, color, false, Color.black, width, height, false).GetComponent<Text>();
			component.alignment = alignment;
			SetLongContentTextOptions(component);
			return component;
		}

		private static void SetLongContentTextOptions(Text label)
		{
			label.horizontalOverflow = (HorizontalWrapMode)1;
			label.verticalOverflow = (VerticalWrapMode)0;
		}

		private GameObject CreateButton(string text, Vector2 position, float width, float height, Action onClick)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			return CreateButton(text, _root.transform, position, width, height, onClick);
		}

		private GameObject CreateButton(string text, Transform parent, Vector2 position, float width, float height, Action onClick)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GUIManager.Instance.CreateButton(text, parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), position, width, height);
			((Object)obj).name = "FeastPlanner_" + text.Replace(" ", string.Empty) + "Button";
			((UnityEvent)obj.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
			SetButtonTint(obj, ButtonSurface());
			AddButtonFrame(obj, width, height);
			return obj;
		}

		private static void AddButtonFrame(GameObject buttonObject, float width, float height)
		{
			//IL_0027: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			Image component = buttonObject.GetComponent<Image>();
			if (component != null)
			{
				component.type = (Type)1;
			}
			CreateButtonFrameShade(buttonObject.transform, ((Object)buttonObject).name + "_StoneInset", Vector2.zero, Vector2.one, new Vector2(4f, 4f), new Vector2(-4f, -4f), ButtonInsetSurface());
			CreateButtonFrameShade(buttonObject.transform, ((Object)buttonObject).name + "_TopRule", new Vector2(0f, 1f), Vector2.one, new Vector2(7f, -6f), new Vector2(-7f, -4f), ButtonTopRuleSurface());
			CreateButtonFrameShade(buttonObject.transform, ((Object)buttonObject).name + "_BottomShadow", Vector2.zero, new Vector2(1f, 0f), new Vector2(7f, 4f), new Vector2(-7f, 7f), ButtonBottomShadowSurface());
			CreateButtonFrameShade(buttonObject.transform, ((Object)buttonObject).name + "_LeftRule", Vector2.zero, new Vector2(0f, 1f), new Vector2(4f, 6f), new Vector2(6f, -6f), ButtonSideRuleSurface());
			CreateButtonFrameShade(buttonObject.transform, ((Object)buttonObject).name + "_RightRule", new Vector2(1f, 0f), Vector2.one, new Vector2(-6f, 6f), new Vector2(-4f, -6f), ButtonSideRuleSurface());
		}

		private static Image CreateButtonFrameShade(Transform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax, Color color)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = anchorMin;
			component.anchorMax = anchorMax;
			component.offsetMin = offsetMin;
			component.offsetMax = offsetMax;
			Image component2 = val.GetComponent<Image>();
			((Graphic)component2).color = color;
			((Graphic)component2).raycastTarget = false;
			val.transform.SetAsFirstSibling();
			return component2;
		}

		private void AddFoodDetailCardClickHandler(Image? shade, int index)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			if (shade != null)
			{
				((Graphic)shade).raycastTarget = true;
				Button obj = ((Component)shade).gameObject.GetComponent<Button>() ?? ((Component)shade).gameObject.AddComponent<Button>();
				((Selectable)obj).transition = (Transition)0;
				((Selectable)obj).targetGraphic = (Graphic)(object)shade;
				((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
				{
					ToggleCustomFoodFilter(index);
				});
			}
		}

		private InputField CreateInputField(Transform parent, string text, Vector2 position, float width, float height)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("FeastPlanner_InputField", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(InputField)
			});
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = position;
			component.sizeDelta = new Vector2(width, height);
			((Graphic)val.GetComponent<Image>()).color = ButtonSurface();
			Text component2 = GUIManager.Instance.CreateText(text, val.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, GUIManager.Instance.AveriaSerifBold, 15, GUIManager.Instance.ValheimBeige, false, Color.black, width - 16f, height - 8f, false).GetComponent<Text>();
			component2.alignment = (TextAnchor)3;
			InputField component3 = val.GetComponent<InputField>();
			component3.textComponent = component2;
			component3.text = text;
			return component3;
		}

		private void ToggleCookableOnly()
		{
			if (_selectedMode != PlannerViewMode.Custom)
			{
				_cookableOnly = !_cookableOnly;
				_pendingDeleteSavedMealId = null;
				RefreshProjectionOnly();
			}
		}

		private void ToggleRoleDropdown()
		{
			if (_selectedMode == PlannerViewMode.Recommended)
			{
				bool num = _roleDropdownRoot != null && !_roleDropdownRoot.activeSelf;
				HideRecommendedDropdowns();
				if (num)
				{
					OpenDropdown(_roleDropdownRoot);
				}
			}
		}

		private void ToggleBiomeDropdown()
		{
			if (_selectedMode == PlannerViewMode.Recommended)
			{
				bool num = _biomeDropdownRoot != null && !_biomeDropdownRoot.activeSelf;
				HideRecommendedDropdowns();
				if (num)
				{
					OpenDropdown(_biomeDropdownRoot);
				}
			}
		}

		private void SelectPlannerRole(PlannerRole role)
		{
			_selectedRole = role;
			_selectedRow = null;
			_pendingDeleteSavedMealId = null;
			HideRecommendedDropdowns();
			RefreshRecommendedRows();
		}

		private void SelectTargetBiome(TargetBiome biome)
		{
			_selectedBiome = biome;
			_selectedRow = null;
			_pendingDeleteSavedMealId = null;
			HideRecommendedDropdowns();
			RefreshRecommendedRows();
		}

		private void HideRecommendedDropdowns()
		{
			GameObject? roleDropdownRoot = _roleDropdownRoot;
			if (roleDropdownRoot != null)
			{
				roleDropdownRoot.SetActive(false);
			}
			GameObject? biomeDropdownRoot = _biomeDropdownRoot;
			if (biomeDropdownRoot != null)
			{
				biomeDropdownRoot.SetActive(false);
			}
		}

		private static void OpenDropdown(GameObject? dropdown)
		{
			if (dropdown != null)
			{
				dropdown.SetActive(true);
				dropdown.transform.SetAsLastSibling();
			}
		}

		private void SelectRecommendedTab()
		{
			ExitCustomEdit();
			HideRecommendedDropdowns();
			_selectedMode = PlannerViewMode.Recommended;
			_pendingDeleteSavedMealId = null;
			_selectedCustomFoodIndex = null;
			SetPlannerMode(PlannerViewMode.Recommended);
			RefreshProjectionOnly();
		}

		private void SelectCustomTab()
		{
			if (_selectedMode != PlannerViewMode.Custom)
			{
				ExitCustomEdit();
			}
			_selectedMode = PlannerViewMode.Custom;
			HideRecommendedDropdowns();
			_pendingDeleteSavedMealId = null;
			_selectedCustomFoodIndex = null;
			SetPlannerMode(PlannerViewMode.Custom);
			RefreshProjectionOnly();
		}

		private void SetPlannerMode(PlannerViewMode mode)
		{
			_setPlannerMode(mode);
		}

		private void SelectVisibleRow(int index)
		{
			if (_selectedMode == PlannerViewMode.Custom)
			{
				SelectSavedMeal(index);
			}
			else
			{
				SelectRow(index);
			}
		}

		private void SelectRow(int index)
		{
			if (_projection != null && index >= 0 && index < _projection.Rows.Count)
			{
				_selectedRow = _projection.Rows[index];
				_pendingDeleteSavedMealId = null;
				RefreshProjectionOnly();
			}
		}

		private void SelectSavedMeal(int index)
		{
			if (!TryPromptDiscard() && _customProjection != null && index >= 0 && index < _customProjection.Rows.Count)
			{
				_selectedCustomRow = _customProjection.Rows[index];
				_pendingDeleteSavedMealId = null;
				_selectedCustomFoodIndex = null;
				_selectSavedMeal(_selectedCustomRow.Id);
				SetPlannerMode(PlannerViewMode.Custom);
				RefreshRecommendedRows();
			}
		}

		private void ToggleCustomFoodFilter(int index)
		{
			if (_selectedMode == PlannerViewMode.Custom && !_isCustomEditing && _selectedCustomRow != null && index >= 0 && index < _selectedCustomRow.Foods.Count)
			{
				_selectedCustomFoodIndex = ((_selectedCustomFoodIndex == index) ? ((int?)null) : new int?(index));
				RefreshProjectionOnly();
			}
		}

		private void SetSelectedActive()
		{
			if (_selectedMode == PlannerViewMode.Custom)
			{
				if (_selectedCustomRow != null)
				{
					_activeTargetName = _selectedCustomRow.Name;
					_pendingDeleteSavedMealId = null;
					RefreshProjectionOnly();
				}
			}
			else if (_selectedRow != null)
			{
				_activeTargetName = _selectedRow.Name;
				RefreshProjectionOnly();
			}
		}

		private void ClearSelectedActive()
		{
			if (_selectedMode == PlannerViewMode.Custom)
			{
				ClearCustomActiveTarget();
				return;
			}
			string text = _selectedRow?.Name;
			if (text != null && string.Equals(text, _activeTargetName, StringComparison.OrdinalIgnoreCase))
			{
				_activeTargetName = string.Empty;
				_pendingDeleteSavedMealId = null;
				RefreshProjectionOnly();
			}
		}

		private void ClearCustomActiveTarget()
		{
			if (!string.IsNullOrWhiteSpace(_activeTargetName))
			{
				_activeTargetName = string.Empty;
				_pendingDeleteSavedMealId = null;
				RefreshProjectionOnly();
			}
		}

		private void DeleteSelectedCustomPlan()
		{
			if (_isCustomEditing)
			{
				ConfirmDiscard();
			}
			else if (_selectedMode == PlannerViewMode.Custom && _selectedCustomRow != null)
			{
				if (!string.Equals(_pendingDeleteSavedMealId, _selectedCustomRow.Id, StringComparison.OrdinalIgnoreCase))
				{
					_pendingDeleteSavedMealId = _selectedCustomRow.Id;
					RefreshProjectionOnly();
					return;
				}
				DeleteSavedMeal();
				_pendingDeleteSavedMealId = null;
				_selectedCustomRow = null;
				RefreshRecommendedRows();
			}
		}

		private void DeleteSavedMeal()
		{
			_deleteSavedMeal();
		}

		private void BeginCustomEdit()
		{
			if (_selectedMode == PlannerViewMode.Custom)
			{
				_editDraft = ((_selectedCustomRow == null) ? CustomEditDraft.New($"Custom {(_customProjection?.Rows.Count ?? 0) + 1}") : CustomEditDraft.FromValues(_selectedCustomRow.Id, _selectedCustomRow.Name, _selectedCustomRow.Foods.Select((FoodDefinition food) => food.PrefabName)));
				_isCustomEditing = true;
				_discardPending = false;
				_editingSlotIndex = null;
				SyncDraftInputs();
				RefreshProjectionOnly();
			}
		}

		private void BeginNewCustomDraft()
		{
			if (_selectedMode != PlannerViewMode.Custom)
			{
				SelectCustomTab();
			}
			if (!TryPromptDiscard())
			{
				_editDraft = CustomEditDraft.New($"Custom {(_customProjection?.Rows.Count ?? 0) + 1}");
				_isCustomEditing = true;
				_discardPending = false;
				_editingSlotIndex = null;
				SyncDraftInputs();
				RefreshProjectionOnly();
			}
		}

		private void RenameCustomDraft(string name)
		{
			if (_editDraft != null)
			{
				_editDraft = _editDraft.WithName(name);
				_discardPending = false;
				RefreshProjectionOnly();
			}
		}

		private void OpenFoodPicker(int slotIndex)
		{
			if (_editDraft == null)
			{
				BeginCustomEdit();
			}
			_editingSlotIndex = slotIndex;
			_pickerPreviewPrefabName = _editDraft?.Slots[slotIndex];
			_pickerPageIndex = 0;
			HidePickerDropdowns();
			if (_pickerSearchInput != null)
			{
				_pickerSearchInput.text = string.Empty;
			}
			RefreshFoodPicker();
			RefreshProjectionOnly();
		}

		private void PreviewFood(int rowIndex)
		{
			if (_editDraft != null)
			{
				int? editingSlotIndex = _editingSlotIndex;
				if (editingSlotIndex.HasValue && _pickerProjection != null && rowIndex >= 0 && rowIndex < _pickerProjection.Rows.Count)
				{
					FoodPickerRow foodPickerRow = _pickerProjection.Rows[rowIndex];
					_pickerPreviewPrefabName = foodPickerRow.PrefabName;
					RefreshFoodPicker();
				}
			}
		}

		private void AddPreviewedFood()
		{
			if (_editDraft == null)
			{
				return;
			}
			int? editingSlotIndex = _editingSlotIndex;
			if (editingSlotIndex.HasValue)
			{
				FoodPickerRow foodPickerRow = _pickerProjection?.PreviewRow;
				if (foodPickerRow != null)
				{
					_editDraft = _editDraft.WithSlot(_editingSlotIndex.Value, foodPickerRow.PrefabName);
					_pickerPreviewPrefabName = foodPickerRow.PrefabName;
					_discardPending = false;
					CloseFoodPicker();
					RefreshProjectionOnly();
				}
			}
		}

		private void TogglePickerCategoryDropdown()
		{
			bool num = _pickerCategoryDropdownRoot != null && !_pickerCategoryDropdownRoot.activeSelf;
			HidePickerDropdowns();
			if (num)
			{
				OpenDropdown(_pickerCategoryDropdownRoot);
			}
		}

		private void TogglePickerBiomeDropdown()
		{
			bool num = _pickerBiomeDropdownRoot != null && !_pickerBiomeDropdownRoot.activeSelf;
			HidePickerDropdowns();
			if (num)
			{
				OpenDropdown(_pickerBiomeDropdownRoot);
			}
		}

		private void SelectPickerCategory(FoodPickerCategory category)
		{
			_pickerCategory = category;
			_pickerPageIndex = 0;
			HidePickerDropdowns();
			RefreshFoodPicker();
		}

		private void SelectPickerBiome(TargetBiome? biome)
		{
			_pickerBiomeFilter = biome;
			_pickerPageIndex = 0;
			HidePickerDropdowns();
			RefreshFoodPicker();
		}

		private void HidePickerDropdowns()
		{
			GameObject? pickerCategoryDropdownRoot = _pickerCategoryDropdownRoot;
			if (pickerCategoryDropdownRoot != null)
			{
				pickerCategoryDropdownRoot.SetActive(false);
			}
			GameObject? pickerBiomeDropdownRoot = _pickerBiomeDropdownRoot;
			if (pickerBiomeDropdownRoot != null)
			{
				pickerBiomeDropdownRoot.SetActive(false);
			}
		}

		private void PreviousPickerPage()
		{
			_pickerPageIndex = Math.Max(0, _pickerPageIndex - 1);
			RefreshFoodPicker();
		}

		private void NextPickerPage()
		{
			_pickerPageIndex++;
			RefreshFoodPicker();
		}

		private void ClearCustomDraft()
		{
			if (_editDraft != null)
			{
				_editDraft = _editDraft.ClearDraft();
				_discardPending = false;
				SyncDraftInputs();
				RefreshProjectionOnly();
			}
		}

		private void SaveCustomDraft()
		{
			if (_editDraft != null)
			{
				_saveCustomMealDraft(_editDraft.SavedMealId, _editDraft.Name, _editDraft.FoodPrefabNames, _selectedRole, _selectedBiome);
				_editDraft = _editDraft.MarkSaved(_editDraft.SavedMealId ?? string.Empty);
				_isCustomEditing = false;
				_editingSlotIndex = null;
				_discardPending = false;
				CloseFoodPicker();
				RefreshRecommendedRows();
			}
		}

		private void ConfirmDiscard()
		{
			CustomEditDraft? editDraft = _editDraft;
			if (editDraft != null && editDraft.HasUnsavedChanges && !_discardPending)
			{
				_discardPending = true;
				RefreshProjectionOnly();
				return;
			}
			_editDraft = null;
			_isCustomEditing = false;
			_editingSlotIndex = null;
			_discardPending = false;
			CloseFoodPicker();
			RefreshProjectionOnly();
		}

		private void ExitCustomEdit()
		{
			_editDraft = null;
			_isCustomEditing = false;
			_editingSlotIndex = null;
			_discardPending = false;
			CloseFoodPicker();
		}

		private void CloseFoodPicker()
		{
			_editingSlotIndex = null;
			_pickerPreviewPrefabName = null;
			HidePickerDropdowns();
			SetPickerControlsActive(active: false);
		}

		private bool TryPromptDiscard()
		{
			if (_isCustomEditing)
			{
				CustomEditDraft? editDraft = _editDraft;
				if (editDraft != null && editDraft.HasUnsavedChanges)
				{
					_discardPending = true;
					RefreshProjectionOnly();
					return true;
				}
			}
			return false;
		}

		private void RefreshRecommendedRows()
		{
			RefreshDataAndProjection();
		}

		private void RefreshDataAndProjection()
		{
			if (!RootExists() || _rowNameTexts[0] == null)
			{
				return;
			}
			try
			{
				FeastPlannerViewModel model = _buildViewModel(_selectedRole, _selectedBiome);
				ApplyModelProjection(model, syncModeFromModel: true);
			}
			catch (Exception arg)
			{
				_log.LogError((object)$"Failed to refresh Feast Planner recommended rows: {arg}");
			}
		}

		private void RefreshProjectionOnly()
		{
			if (!RootExists() || _rowNameTexts[0] == null)
			{
				return;
			}
			if (_latestModel == null)
			{
				RefreshDataAndProjection();
				return;
			}
			try
			{
				ApplyModelProjection(_latestModel, syncModeFromModel: false);
			}
			catch (Exception arg)
			{
				_log.LogError((object)$"Failed to refresh Feast Planner projected rows: {arg}");
			}
		}

		private void ApplyModelProjection(FeastPlannerViewModel model, bool syncModeFromModel)
		{
			_latestModel = model;
			_selectedRole = model.SelectedRole;
			_selectedBiome = model.SelectedBiome;
			if (syncModeFromModel)
			{
				_selectedMode = model.SelectedMode;
			}
			_currentCraftability = model.Craftability;
			_projection = RecommendedPlanProjection.From(model, _cookableOnly, _activeTargetName);
			_customProjection = CustomPlanProjection.From(model, _activeTargetName, _pendingDeleteSavedMealId);
			_selectedRow = ((_selectedRow != null && _projection.Rows.Any((RecommendedPlanRow row) => row.Name == _selectedRow.Name && row.RowLabel == _selectedRow.RowLabel)) ? _projection.Rows.First((RecommendedPlanRow row) => row.Name == _selectedRow.Name && row.RowLabel == _selectedRow.RowLabel) : _projection.Rows.FirstOrDefault());
			_selectedCustomRow = ((_selectedCustomRow != null && _customProjection.Rows.Any((CustomPlanRow row) => row.Id == _selectedCustomRow.Id)) ? _customProjection.Rows.First((CustomPlanRow row) => row.Id == _selectedCustomRow.Id) : (_customProjection.Rows.FirstOrDefault((CustomPlanRow row) => row.IsSelected) ?? _customProjection.Rows.FirstOrDefault()));
			if (_selectedCustomFoodIndex.HasValue && (_selectedCustomRow == null || _selectedCustomFoodIndex.Value >= _selectedCustomRow.Foods.Count))
			{
				_selectedCustomFoodIndex = null;
			}
			ApplyProjection();
			RefreshFoodPicker();
		}

		private void ApplyProjection()
		{
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			if (_projection == null)
			{
				return;
			}
			if (_activeTargetText != null)
			{
				_activeTargetText.text = _projection.ActiveTargetText;
			}
			if (_cookableToggleText != null)
			{
				_cookableToggleText.text = ((_selectedMode == PlannerViewMode.Custom) ? "Saved Plans" : (_cookableOnly ? "Cookable Now: On" : "Cookable Now: Off"));
			}
			ApplyListHeaderLayout();
			if (_roleControlText != null)
			{
				_roleControlText.text = "Role: " + Display(_selectedRole);
			}
			if (_biomeControlText != null)
			{
				_biomeControlText.text = "Biome: " + Display(_selectedBiome);
			}
			SetRecommendedControlsVisible(_selectedMode == PlannerViewMode.Recommended);
			ApplyTabStyles();
			if (_setActiveText != null)
			{
				string text = ((_selectedMode != PlannerViewMode.Custom) ? _selectedRow?.Name : _selectedCustomRow?.Name);
				_setActiveText.text = ((text == null) ? "Se