Decompiled source of SongOrganizer v1.5.4

plugins/SongOrganizer.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BaboonAPI.Hooks.Tracks;
using BaboonAPI.Internal.BaseGame;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.FSharp.Collections;
using Microsoft.FSharp.Core;
using Newtonsoft.Json;
using SongOrganizer.Data;
using SongOrganizer.UI;
using SongOrganizer.Utils;
using TMPro;
using TootTallyDiffCalcLibs;
using TrombLoader.CustomTracks;
using TrombLoader.Helpers;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Localization.Components;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("SongOrganizer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Trombone Champ: Searching, Filtering, and Sorting")]
[assembly: AssemblyFileVersion("1.5.4.0")]
[assembly: AssemblyInformationalVersion("1.5.4")]
[assembly: AssemblyProduct("SongOrganizer")]
[assembly: AssemblyTitle("SongOrganizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.4.0")]
[module: UnverifiableCode]
namespace SongOrganizer
{
	[BepInPlugin("SongOrganizer", "SongOrganizer", "1.5.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static Plugin Instance;

		public static ManualLogSource Log;

		public static Options Options;

		public static RefreshLevelSelect RefreshLevelSelect;

		public static Toggle Toggle;

		public static Button Button;

		public static TMP_InputField InputFieldPrefab;

		public static TMP_InputField SearchInput;

		public static List<Button> FavoriteButtons = new List<Button>();

		public static ConcurrentDictionary<string, Track> TrackDict = new ConcurrentDictionary<string, Track>();

		public static ConcurrentDictionary<string, float> StarDict = new ConcurrentDictionary<string, float>();

		public static ConcurrentBag<string> RatedTrackrefs = new ConcurrentBag<string>();

		public static List<TootTallyWebClient.SearchTrackResult> RatedTracksPaged = new List<TootTallyWebClient.SearchTrackResult>();

		public const int TRACK_SCORE_LENGTH = 5;

		public const int MAX_STARS = 11;

		public const int MAX_PARALLELISM = 8;

		public static readonly string RatedTracksPath = Paths.ConfigPath + "/rated.json";

		private const string FILTER_SECTION = "Filter";

		private const string SORT_SECTION = "Sort";

		private const string INDEX_SECTION = "Index";

		private const string SEARCH_SECTION = "Search";

		private void Awake()
		{
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Options = new Options
			{
				ShowDefault = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowDefault", false, (ConfigDescription)null),
				ShowCustom = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowCustom", false, (ConfigDescription)null),
				ShowUnplayed = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowUnplayed", false, (ConfigDescription)null),
				ShowPlayed = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowPlayed", false, (ConfigDescription)null),
				ShowNotSRank = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowNotSRank", false, (ConfigDescription)null),
				ShowSRank = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowSRank", false, (ConfigDescription)null),
				ShowUnrated = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowUnrated", false, (ConfigDescription)null),
				ShowRated = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowRated", false, (ConfigDescription)null),
				ShowOnlyFavorites = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowOnlyFavorites", false, (ConfigDescription)null),
				Favorites = ((BaseUnityPlugin)this).Config.Bind<string>("Filter", "Favorites", "", (ConfigDescription)null),
				SortMode = ((BaseUnityPlugin)this).Config.Bind<string>("Sort", "SortMode", "default", (ConfigDescription)null),
				LastIndex = ((BaseUnityPlugin)this).Config.Bind<int>("Index", "LastIndex", 0, (ConfigDescription)null),
				SearchValue = ((BaseUnityPlugin)this).Config.Bind<string>("Search", "SearchValue", "", (ConfigDescription)null),
				MinStar = ((BaseUnityPlugin)this).Config.Bind<float>("Search", "MinStar", 0f, (ConfigDescription)null),
				MaxStar = ((BaseUnityPlugin)this).Config.Bind<float>("Search", "MaxStar", 11f, (ConfigDescription)null)
			};
			Options.SetFavorites();
			TrackCalculation.CalculateStars();
			DateTime start = DateTime.Now;
			((MonoBehaviour)this).StartCoroutine((IEnumerator)TootTallyWebClient.GetRatedTracksRequest(1, 100, delegate(TootTallyWebClient.SearchResponse result)
			{
				((MonoBehaviour)this).StartCoroutine((IEnumerator)GetMoreRatedTracks(start, result));
			}));
			SceneManager.sceneUnloaded += UnloadModule;
			new Harmony("SongOrganizer").PatchAll();
		}

		public IEnumerator<Coroutine> GetMoreRatedTracks(DateTime start, TootTallyWebClient.SearchResponse result)
		{
			List<Coroutine> coroutines = new List<Coroutine>();
			int end = result.count / 100 + 1;
			for (int i = 2; i <= end; i++)
			{
				coroutines.Add(((MonoBehaviour)this).StartCoroutine((IEnumerator)TootTallyWebClient.GetRatedTracksRequest(i, 100)));
			}
			foreach (Coroutine item in coroutines)
			{
				yield return item;
			}
			TootTallyWebClient.SearchResponse combinedResponse = new TootTallyWebClient.SearchResponse
			{
				count = RatedTracksPaged.Count,
				results = RatedTracksPaged
			};
			File.WriteAllText(contents: JsonConvert.SerializeObject((object)combinedResponse), path: RatedTracksPath);
			Log.LogDebug((object)$"Queried {RatedTracksPaged.Count} rated tracks elapsed: {DateTime.Now - start}");
		}

		public static void UnloadModule(Scene scene)
		{
			UnloadModule();
		}

		public static void UnloadModule()
		{
			if (RefreshLevelSelect != null)
			{
				TracksLoadedEvent.EVENT.Unregister((Listener)(object)RefreshLevelSelect);
				RefreshLevelSelect = null;
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "SongOrganizer";

		public const string PLUGIN_NAME = "SongOrganizer";

		public const string PLUGIN_VERSION = "1.5.4";
	}
}
namespace SongOrganizer.Utils
{
	public static class FilterQueryParser
	{
		public static bool ShowTrack(Track track)
		{
			return ShowTrack(Plugin.Options.ShowCustom.Value, Plugin.Options.ShowDefault.Value, track.custom) && ShowTrack(Plugin.Options.ShowPlayed.Value, Plugin.Options.ShowUnplayed.Value, track.letterScore != "-") && ShowTrack(Plugin.Options.ShowSRank.Value, Plugin.Options.ShowNotSRank.Value, track.letterScore == "S") && ShowTrack(Plugin.Options.ShowRated.Value, Plugin.Options.ShowUnrated.Value, track.rated) && ShowTrack(Plugin.Options.MinStar.Value, Plugin.Options.MaxStar.Value, track.stars) && FilterFavorites(Plugin.Options.ShowOnlyFavorites.Value, ((SingleTrackData)track).trackref) && ShowTrack(Plugin.Options.SearchValue.Value, track);
		}

		private static bool ShowTrack(bool optionToggle, bool oppositeOptionToggle, bool option)
		{
			return optionToggle == oppositeOptionToggle || optionToggle == option;
		}

		private static bool ShowTrack(float minStar, float maxStar, float stars)
		{
			return (maxStar >= 11f && stars != stars) || (stars > minStar && (maxStar >= 11f || stars <= maxStar));
		}

		private static bool FilterFavorites(bool onlyFavorites, string trackRef)
		{
			return !onlyFavorites || (onlyFavorites && Plugin.Options.ContainsFavorite(trackRef));
		}

		private static bool ShowTrack(string query, Track track)
		{
			if (Utility.IsNullOrWhiteSpace(query))
			{
				return true;
			}
			string value = query.ToLower().Trim().Replace(".", "");
			return ((SingleTrackData)track).trackname_long.ToLower().Replace(".", "").Contains(value) || ((SingleTrackData)track).trackname_short.ToLower().Replace(".", "").Contains(value) || ((SingleTrackData)track).artist.ToLower().Replace(".", "").Contains(value) || ((SingleTrackData)track).genre.ToLower().Replace(".", "").Contains(value) || ((SingleTrackData)track).desc.ToLower().Replace(".", "").Contains(value);
		}
	}
	public class RefreshLevelSelect : Listener
	{
		private LevelSelectController __instance;

		private static List<TootTallyWebClient.SearchTrackResult> ratedTracks;

		private static ILookup<string, TootTallyWebClient.SearchTrackResult> ratedTrackFileHashes;

		private static ILookup<string, TootTallyWebClient.SearchTrackResult> ratedTrackNoteHashes;

		private static HashSet<string> ratedTrackRefs;

		private static ConcurrentBag<string> foundNoteHashes;

		public RefreshLevelSelect(LevelSelectController instance)
		{
			__instance = instance;
		}

		public void OnTracksLoaded(FSharpList<TromboneTrack> tracks)
		{
			AddTracks(__instance.alltrackslist);
			FilterTracks(__instance);
		}

		private void AddTracks(List<SingleTrackData> singleTrackDatas)
		{
			DateTime now = DateTime.Now;
			Plugin.Log.LogDebug((object)$"Loading tracks: {singleTrackDatas.Count} total, {Plugin.StarDict.Count} star calcs");
			CalculateRatedTracks(singleTrackDatas);
			Plugin.TrackDict.Clear();
			singleTrackDatas.ForEach(delegate(SingleTrackData track)
			{
				bool flag = TrackLookup.lookup(track.trackref) is BaseGameTrack;
				track.difficulty = ((track.difficulty > 10) ? 10 : track.difficulty);
				track.difficulty = ((track.difficulty >= 0) ? track.difficulty : 0);
				Track track2 = new Track(track)
				{
					custom = !flag,
					rated = Plugin.RatedTrackrefs.Contains(track.trackref),
					stars = track.difficulty
				};
				if (Plugin.StarDict.ContainsKey(track.trackref))
				{
					track2.stars = Plugin.StarDict[track.trackref];
				}
				FSharpOption<SavedTrackScore> val = TrackLookup.lookupScore(track.trackref);
				track2.letterScore = ((val != null) ? val.Value.highestRank : "-");
				track2.scores = ((val != null) ? ((IEnumerable<int>)val.Value.highScores).ToArray() : new int[5]);
				track2.isFavorite = Plugin.Options.ContainsFavorite(track.trackref);
				Plugin.TrackDict.TryAdd(track.trackref, track2);
			});
			List<TootTallyWebClient.SearchTrackResult> list = ratedTracks.Where((TootTallyWebClient.SearchTrackResult track) => !foundNoteHashes.Contains(track.note_hash) && !track.is_official).ToList();
			Plugin.Log.LogDebug((object)$"{list.Count} / {Plugin.RatedTrackrefs.Count} rated tracks missing. Loading tracks elapsed: {DateTime.Now - now}");
		}

		private static void CalculateRatedTracks(List<SingleTrackData> singleTrackDatas)
		{
			if (Plugin.RatedTrackrefs.Count > 0)
			{
				return;
			}
			try
			{
				string text = File.ReadAllText(Plugin.RatedTracksPath);
				TootTallyWebClient.SearchResponse searchResponse = JsonConvert.DeserializeObject<TootTallyWebClient.SearchResponse>(text);
				ratedTracks = searchResponse.results.Where((TootTallyWebClient.SearchTrackResult i) => i.is_rated).ToList();
				foundNoteHashes = new ConcurrentBag<string>();
				ratedTrackFileHashes = ratedTracks.ToLookup((TootTallyWebClient.SearchTrackResult i) => i.file_hash);
				ratedTrackNoteHashes = ratedTracks.ToLookup((TootTallyWebClient.SearchTrackResult i) => i.note_hash);
				ratedTrackRefs = new HashSet<string>(ratedTracks.Select((TootTallyWebClient.SearchTrackResult i) => i.track_ref));
				Plugin.RatedTrackrefs = new ConcurrentBag<string>((from track in singleTrackDatas.AsParallel().WithDegreeOfParallelism(8)
					select track.trackref into trackref
					where IsRated(trackref)
					select trackref).ToList());
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Error calculating rated tracks\n" + ex.Message));
			}
		}

		private static bool IsRated(string trackref)
		{
			if (trackref == null)
			{
				return false;
			}
			if (TrackLookup.lookup(trackref) is BaseGameTrack)
			{
				return ratedTrackRefs.Contains(trackref);
			}
			TromboneTrack val = TrackLookup.lookup(trackref);
			if (!(val is CustomTrack))
			{
				return false;
			}
			CustomTrack val2 = (CustomTrack)(object)((val is CustomTrack) ? val : null);
			string path = Path.Combine(val2.folderPath, Globals.defaultChartName);
			string text = File.ReadAllText(path);
			if (ratedTrackRefs.Contains(trackref))
			{
				string key = TrackCalculation.CalcHash(text);
				if (ratedTrackFileHashes.Contains(key))
				{
					foundNoteHashes.Add(ratedTrackFileHashes[key].FirstOrDefault().note_hash);
					return true;
				}
			}
			string str = TrackCalculation.BuildNoteString(text);
			string text2 = TrackCalculation.CalcHash(str);
			if (ratedTrackNoteHashes.Contains(text2))
			{
				foundNoteHashes.Add(text2);
				return true;
			}
			return false;
		}

		public static void FilterTracks(LevelSelectController __instance)
		{
			List<string[]> list = new List<string[]>();
			List<Track> list2 = new List<Track>();
			int num = 0;
			foreach (Track value in Plugin.TrackDict.Values)
			{
				if (FilterQueryParser.ShowTrack(value))
				{
					((SingleTrackData)value).trackindex = num;
					list.Add(new string[10]
					{
						((SingleTrackData)value).trackname_long,
						((SingleTrackData)value).trackname_short,
						((SingleTrackData)value).trackref,
						((SingleTrackData)value).year,
						((SingleTrackData)value).artist,
						((SingleTrackData)value).genre,
						((SingleTrackData)value).desc,
						((SingleTrackData)value).difficulty.ToString(),
						((SingleTrackData)value).length.ToString(),
						((SingleTrackData)value).tempo.ToString()
					});
					list2.Add(value);
					num++;
				}
			}
			if (list.Count > 0)
			{
				GlobalVariables.data_tracktitles = list.ToArray();
				__instance.alltrackslist.Clear();
				__instance.alltrackslist.AddRange((IEnumerable<SingleTrackData>)list2);
			}
			if (GlobalVariables.levelselect_index >= GlobalVariables.data_tracktitles.Length)
			{
				GlobalVariables.levelselect_index = 0;
			}
			Plugin.Log.LogDebug((object)$"Filter result: {__instance.alltrackslist.Count} found of {Plugin.TrackDict.Count}");
			__instance.sortTracks(Plugin.Options.SortMode.Value.ToLower(), false);
		}
	}
	public class TootTallyWebClient
	{
		[Serializable]
		public class SearchResponse
		{
			public int count;

			public List<SearchTrackResult> results;
		}

		[Serializable]
		public class SearchTrackResult
		{
			public string track_ref;

			public string short_name;

			public string note_hash;

			public string file_hash;

			public decimal difficulty;

			public string download;

			public string mirror;

			public bool is_official;

			public bool is_rated;
		}

		public const string API_URL = "https://toottally.com";

		public const string RATED_ENDPOINT = "/api/search/?rated=1&fields=track_ref,short_name,note_hash,file_hash,difficulty,download,mirror,is_official,is_rated";

		public const int PAGE_SIZE = 100;

		public static IEnumerator<UnityWebRequestAsyncOperation> GetRatedTracksRequest(int page, int pageSize, Action<SearchResponse> callback = null)
		{
			string apiLink = string.Format("{0}{1}&page_size={2}&page={3}", "https://toottally.com", "/api/search/?rated=1&fields=track_ref,short_name,note_hash,file_hash,difficulty,download,mirror,is_official,is_rated", pageSize, page);
			UnityWebRequest webRequest = UnityWebRequest.Get(apiLink);
			yield return webRequest.SendWebRequest();
			if (!webRequest.isNetworkError && !webRequest.isHttpError)
			{
				string data = webRequest.downloadHandler.GetText();
				SearchResponse result = JsonConvert.DeserializeObject<SearchResponse>(data);
				Plugin.RatedTracksPaged.AddRange(result.results);
				callback?.Invoke(result);
			}
			else
			{
				Plugin.Log.LogError((object)("ERROR: " + webRequest.error));
			}
		}
	}
	public class TrackCalculation
	{
		public static void CalculateStars()
		{
			DateTime start = DateTime.Now;
			Plugin.Log.LogDebug((object)$"Starting star calculations {DateTime.Now}");
			Task.Run(delegate
			{
				(from i in Directory.GetFiles(Globals.GetCustomSongsPath(), "song.tmb", SearchOption.AllDirectories).Concat(Directory.GetFiles(Paths.PluginPath, "song.tmb", SearchOption.AllDirectories))
					select Path.GetDirectoryName(i)).AsParallel().WithDegreeOfParallelism(8).ForAll<string>(delegate(string songFolder)
				{
					CalculateCustomStars(songFolder);
				});
				Plugin.Log.LogDebug((object)$"Custom star calculation elapsed: {DateTime.Now - start}");
			});
			Task.Run(delegate
			{
				string trackassetDir = Application.streamingAssetsPath + "/trackassets/";
				(from i in Directory.GetDirectories(trackassetDir)
					select i.Substring(trackassetDir.Length) into i
					where i != "freeplay"
					select i).AsParallel().WithDegreeOfParallelism(8).ForAll(delegate(string trackref)
				{
					CalculateBaseStars(trackref);
				});
				Plugin.Log.LogDebug((object)$"Base star calculation elapsed: {DateTime.Now - start}");
			});
		}

		private static void CalculateBaseStars(string trackref)
		{
			//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)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Chart chart = ChartReader.ReadBaseGame(trackref);
			try
			{
				ProcessChart(chart);
			}
			finally
			{
				((IDisposable)(Chart)(ref chart)).Dispose();
			}
		}

		private static void CalculateCustomStars(string songFolder)
		{
			//IL_001d: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(songFolder, Globals.defaultChartName);
			if (!File.Exists(text))
			{
				return;
			}
			Chart chart = ChartReader.ReadCustomChart(text);
			try
			{
				ProcessChart(chart);
			}
			finally
			{
				((IDisposable)(Chart)(ref chart)).Dispose();
			}
		}

		public static string BuildNoteString(string tmb)
		{
			int num = tmb.IndexOf('[', tmb.IndexOf("notes\""));
			StringBuilder stringBuilder = new StringBuilder();
			int num2 = 0;
			for (int i = num; i < tmb.Length; i++)
			{
				if (num2 >= 2)
				{
					break;
				}
				if (!char.IsWhiteSpace(tmb[i]))
				{
					stringBuilder.Append(tmb[i]);
					if (tmb[i] == '[')
					{
						num2 = 0;
					}
					else if (tmb[i] == ']')
					{
						num2++;
					}
					else if (tmb[i] == ',')
					{
						stringBuilder.Append(' ');
					}
				}
			}
			return stringBuilder.ToString();
		}

		private static void ProcessChart(Chart chart)
		{
			//IL_000e: 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_0015: Unknown result type (might be due to invalid IL or missing references)
			((Chart)(ref chart)).ProcessLite();
			Plugin.StarDict[chart.trackRef] = chart.performances.starRatingDict[0];
		}

		public static string CalcHash(string str)
		{
			byte[] bytes = Encoding.UTF8.GetBytes(str);
			using SHA256 sHA = SHA256.Create();
			byte[] array = sHA.ComputeHash(bytes);
			StringBuilder stringBuilder = new StringBuilder();
			byte[] array2 = array;
			foreach (byte b in array2)
			{
				stringBuilder.Append(b.ToString("x2"));
			}
			return stringBuilder.ToString();
		}
	}
}
namespace SongOrganizer.UI
{
	public class DoubleSlider : MonoBehaviour
	{
		private Slider minSlider;

		private Slider maxSlider;

		private const string HANDLE_PATH = "Handle Slide Area/Handle";

		private const string FILL_AREA_PATH = "Fill Area";

		private const string FILL_PATH = "Fill Area/Fill";

		private const string BACKGROUND_PATH = "Background";

		public void Setup(LevelSelectController __instance, Transform transform, Vector2 position)
		{
			//IL_0005: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			maxSlider = CreateSlider(__instance, transform, position, Plugin.Options.MaxStar, ChangeMaxSlider);
			((Graphic)((Component)((Component)maxSlider).transform.Find("Fill Area/Fill")).GetComponent<Image>()).color = OptionalTheme.colors.scrollSpeedSlider.fill;
			((Graphic)((Component)((Component)maxSlider).transform.Find("Background")).GetComponent<Image>()).color = OptionalTheme.colors.scrollSpeedSlider.background;
			((Object)maxSlider).name = "StarSliderMax";
			minSlider = CreateSlider(__instance, transform, position, Plugin.Options.MinStar, ChangeMinSlider);
			((Object)minSlider).name = "StarSliderMin";
			((Component)((Component)minSlider).transform.Find("Fill Area")).gameObject.SetActive(false);
			((Component)((Component)minSlider).transform.Find("Background")).gameObject.SetActive(false);
			EmptyMinSlider();
		}

		private void ChangeMinSlider(float value)
		{
			if (maxSlider.value <= value)
			{
				maxSlider.value = value + 1f;
			}
		}

		private void ChangeMaxSlider(float value)
		{
			if (minSlider.value >= value)
			{
				minSlider.value = value - 1f;
			}
		}

		public Slider CreateSlider(LevelSelectController __instance, Transform transform, Vector2 position, ConfigEntry<float> entry, Action<float> action)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			Slider val = Object.Instantiate<Slider>(__instance.gamespeedslider, transform);
			Transform val2 = ((Component)val).transform.Find("Handle Slide Area/Handle");
			Text starSliderLabel = Object.Instantiate<Text>(__instance.label_speed_slider, ((Component)val2).transform);
			((Component)starSliderLabel).GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
			((Object)starSliderLabel).name = "StarSliderLabel";
			((Graphic)starSliderLabel).color = OptionalTheme.colors.scrollSpeedSlider.text;
			SetLabel(starSliderLabel, entry.Value);
			((Component)val).GetComponent<RectTransform>().anchoredPosition = position;
			val.wholeNumbers = true;
			val.minValue = 0f;
			val.maxValue = 11f;
			val.value = entry.Value;
			((Graphic)((Component)val2).gameObject.GetComponent<Image>()).color = OptionalTheme.colors.scrollSpeedSlider.handle;
			((UnityEvent<float>)(object)val.onValueChanged).AddListener((UnityAction<float>)delegate(float value)
			{
				entry.Value = value;
				SetLabel(starSliderLabel, value);
				EmptyMinSlider();
				RefreshLevelSelect.FilterTracks(__instance);
				action(value);
			});
			return val;
		}

		private void SetLabel(Text label, float value)
		{
			label.text = ((value == 11f) ? "∞" : value.ToString());
		}

		private void EmptyMinSlider()
		{
			//IL_0038: 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)
			RectTransform component = ((Component)((Component)maxSlider).transform.Find("Fill Area/Fill")).gameObject.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(Plugin.Options.MinStar.Value / 11f, component.anchorMin.y);
		}
	}
	public class Favorites : MonoBehaviour
	{
		private static readonly int[] indices = new int[7] { 0, 1, 2, 3, -3, -2, -1 };

		private static readonly ColorBlock off;

		private static readonly ColorBlock on;

		public static void Setup(LevelSelectController __instance)
		{
			GameObject val = GameObject.Find("MainCanvas/FullScreenPanel/GameButtonsPanel");
			for (int i = 0; i < 7; i++)
			{
				Plugin.FavoriteButtons.Add(FavoriteButton(i, val.transform, __instance));
			}
			ShowFavorites(__instance);
		}

		public static void Setup(PointSceneController __instance)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			Button favButton = Object.Instantiate<Button>(Plugin.Button, GameObject.Find("Canvas").transform);
			((Object)favButton).name = "favbutton";
			((Component)favButton).GetComponentInChildren<Text>().text = "";
			RectTransform component = ((Component)favButton).GetComponent<RectTransform>();
			component.anchoredPosition = new Vector2(component.anchoredPosition.x + 5f, component.anchoredPosition.y);
			((Selectable)favButton).colors = (Plugin.Options.ContainsFavorite(GlobalVariables.chosen_track) ? on : off);
			((UnityEvent)favButton.onClick).AddListener((UnityAction)delegate
			{
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				if (Plugin.Options.ContainsFavorite(GlobalVariables.chosen_track))
				{
					Plugin.Options.RemoveFavorite(GlobalVariables.chosen_track);
					((Selectable)favButton).colors = off;
				}
				else
				{
					Plugin.Options.AddFavorite(GlobalVariables.chosen_track);
					((Selectable)favButton).colors = on;
				}
			});
			((Component)favButton).transform.SetAsLastSibling();
			Image component2 = ((Component)favButton).GetComponent<Image>();
			component2.sprite = GetSprite(Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location) + "/Assets/white-heart.png");
			((Graphic)component2).rectTransform.sizeDelta = new Vector2(36f, 36f);
		}

		private static Button FavoriteButton(int i, Transform parent, LevelSelectController __instance)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			Button val = Object.Instantiate<Button>(Plugin.Button, parent);
			((Object)val).name = $"favbutton{i}";
			((Component)val).GetComponentInChildren<Text>().text = "";
			Transform val2 = parent.Find($"Button{i}");
			RectTransform component = ((Component)val2).GetComponent<RectTransform>();
			((Component)val).GetComponent<RectTransform>().anchoredPosition = new Vector2(component.anchoredPosition.x - 246f, component.anchoredPosition.y - 228f);
			((Selectable)val).colors = off;
			((UnityEvent)val.onClick).AddListener((UnityAction)delegate
			{
				int index = GetIndex(i, __instance);
				SingleTrackData val3 = __instance.alltrackslist[index];
				if (Plugin.Options.ContainsFavorite(val3.trackref))
				{
					Plugin.Options.RemoveFavorite(val3.trackref);
				}
				else
				{
					Plugin.Options.AddFavorite(val3.trackref);
				}
				ShowFavorites(__instance);
			});
			Image component2 = ((Component)val).GetComponent<Image>();
			component2.sprite = GetSprite(Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location) + "/Assets/white-heart.png");
			((Graphic)component2).rectTransform.sizeDelta = new Vector2(18f, 18f);
			((Transform)((Graphic)component2).rectTransform).rotation = new Quaternion(0f, 0f, -0.05f, 1f);
			return val;
		}

		public static void ShowFavorites(LevelSelectController __instance)
		{
			//IL_004b: 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)
			int num = 0;
			foreach (Button favoriteButton in Plugin.FavoriteButtons)
			{
				int index = GetIndex(num, __instance);
				bool flag = Plugin.Options.ContainsFavorite(__instance.alltrackslist[index].trackref);
				((Selectable)favoriteButton).colors = (flag ? on : off);
				num++;
			}
		}

		private static int GetIndex(int index, LevelSelectController __instance)
		{
			index = __instance.songindex + indices[index];
			int count = __instance.alltrackslist.Count;
			if (count <= 1)
			{
				return 0;
			}
			if (index < count && index >= 0)
			{
				return index;
			}
			if (index >= count)
			{
				return (index - count) % count;
			}
			return (index % count + count) % count;
		}

		private static Sprite GetSprite(string path)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = File.ReadAllBytes(path);
			Texture2D val = new Texture2D(0, 0);
			ImageConversion.LoadImage(val, array);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), Vector2.zero, 300f);
		}

		static Favorites()
		{
			//IL_0018: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			ColorBlock val = default(ColorBlock);
			((ColorBlock)(ref val)).normalColor = Color.white;
			((ColorBlock)(ref val)).highlightedColor = new Color(0.8f, 0.8f, 0.8f);
			((ColorBlock)(ref val)).pressedColor = new Color(0.8f, 0.8f, 0.8f);
			((ColorBlock)(ref val)).colorMultiplier = 1f;
			off = val;
			val = default(ColorBlock);
			((ColorBlock)(ref val)).normalColor = new Color(0.95f, 0.22f, 0.35f);
			((ColorBlock)(ref val)).highlightedColor = new Color(0.74f, 0.15f, 0.25f);
			((ColorBlock)(ref val)).pressedColor = new Color(0.74f, 0.15f, 0.25f);
			((ColorBlock)(ref val)).colorMultiplier = 1f;
			on = val;
		}
	}
	public static class OptionalTheme
	{
		public class SongOrganizerColors
		{
			public ScrollSpeedSliderColors scrollSpeedSlider = new ScrollSpeedSliderColors();

			public PlayButtonColors playButton = new PlayButtonColors();

			public LeaderboardColors leaderboard = new LeaderboardColors();

			public ReplayButtonColors replayButton = new ReplayButtonColors();

			public Color songName = Color.white;
		}

		public class ScrollSpeedSliderColors
		{
			public Color handle = new Color(1f, 1f, 0f);

			public Color text = Color.black;

			public Color background = Color.black;

			public Color fill = new Color(0.95f, 0.22f, 0.35f);
		}

		public class PlayButtonColors
		{
			public Color text = new Color(0.021f, 0.292f, 0.302f);

			public Color background = new Color(0.149f, 1f, 1f);

			public Color shadow = new Color(0.094f, 0.682f, 0.706f);
		}

		public class LeaderboardColors
		{
			public Color text = Color.white;

			public Color textOutline = new Color(0f, 0f, 0f, 0.5f);
		}

		public class ReplayButtonColors
		{
			public Color text = Color.white;

			public ColorBlock colors;

			public ReplayButtonColors()
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: 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_0041: 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_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				ColorBlock val = default(ColorBlock);
				((ColorBlock)(ref val)).normalColor = new Color(0.95f, 0.22f, 0.35f);
				((ColorBlock)(ref val)).highlightedColor = new Color(0.77f, 0.18f, 0.29f);
				((ColorBlock)(ref val)).pressedColor = new Color(1f, 1f, 0f);
				colors = val;
				base..ctor();
			}
		}

		public static SongOrganizerColors colors;

		public static void Setup()
		{
			colors = getTootTallyThemeColors();
			((ColorBlock)(ref colors.replayButton.colors)).colorMultiplier = 1f;
			colors.playButton.background.a = 1f;
			colors.playButton.shadow.a = 0.8f;
		}

		private static SongOrganizerColors getTootTallyThemeColors()
		{
			//IL_008c: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: 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_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: 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_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: 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)
			try
			{
				Type type = Type.GetType("TootTallyCore.Theme, TootTallyCore");
				if (type == null)
				{
					return new SongOrganizerColors();
				}
				FieldInfo field = type.GetField("colors", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
				object value = field.GetValue(field);
				SongOrganizerColors songOrganizerColors = new SongOrganizerColors();
				songOrganizerColors.scrollSpeedSlider = new ScrollSpeedSliderColors
				{
					handle = (Color)(((??)Get<Color?>(value, new string[2] { "scrollSpeedSlider", "handle" })) ?? new Color(1f, 1f, 0f)),
					text = (Color)(((??)Get<Color?>(value, new string[2] { "scrollSpeedSlider", "text" })) ?? Color.black),
					background = (Color)(((??)Get<Color?>(value, new string[2] { "scrollSpeedSlider", "background" })) ?? new Color(1f, 1f, 0f)),
					fill = (Color)(((??)Get<Color?>(value, new string[2] { "scrollSpeedSlider", "fill" })) ?? new Color(1f, 1f, 0f))
				};
				songOrganizerColors.playButton = new PlayButtonColors
				{
					background = (Color)(((??)Get<Color?>(value, new string[2] { "playButton", "background" })) ?? new Color(0.149f, 1f, 1f)),
					text = (Color)(((??)Get<Color?>(value, new string[2] { "playButton", "text" })) ?? new Color(0.021f, 0.292f, 0.302f)),
					shadow = (Color)(((??)Get<Color?>(value, new string[2] { "playButton", "shadow" })) ?? new Color(0.094f, 0.682f, 0.706f))
				};
				songOrganizerColors.leaderboard = new LeaderboardColors
				{
					text = (Color)(((??)Get<Color?>(value, new string[2] { "leaderboard", "text" })) ?? Color.white),
					textOutline = (Color)(((??)Get<Color?>(value, new string[2] { "leaderboard", "textOutline" })) ?? new Color(0f, 0f, 0f, 0.5f))
				};
				ReplayButtonColors replayButtonColors = new ReplayButtonColors
				{
					text = (Color)(((??)Get<Color?>(value, new string[2] { "replayButton", "text" })) ?? Color.white)
				};
				ColorBlock? val = Get<ColorBlock?>(value, new string[2] { "replayButton", "colors" });
				ColorBlock val3;
				if (!val.HasValue)
				{
					ColorBlock val2 = default(ColorBlock);
					((ColorBlock)(ref val2)).normalColor = new Color(0.95f, 0.22f, 0.35f);
					((ColorBlock)(ref val2)).highlightedColor = new Color(0.77f, 0.18f, 0.29f);
					((ColorBlock)(ref val2)).pressedColor = new Color(1f, 1f, 0f);
					val3 = val2;
				}
				else
				{
					val3 = val.GetValueOrDefault();
				}
				replayButtonColors.colors = val3;
				songOrganizerColors.replayButton = replayButtonColors;
				songOrganizerColors.songName = (Color)(((??)Get<Color?>(value, new string[2] { "title", "songName" })) ?? Color.white);
				return songOrganizerColors;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)"Exception trying to get theme colors. Reporting TootTallyCore as not found.");
				Plugin.Log.LogError((object)ex.Message);
				Plugin.Log.LogError((object)ex.StackTrace);
				return new SongOrganizerColors();
			}
		}

		private static T Get<T>(object colors, params string[] fields)
		{
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			FieldInfo field = colors.GetType().GetField(fields[0], bindingAttr);
			object value = field.GetValue(colors);
			if (value == null)
			{
				return default(T);
			}
			FieldInfo field2 = value.GetType().GetField(fields[1], bindingAttr);
			object value2 = field2.GetValue(value);
			return (T)value2;
		}
	}
	public class SortDropdown : MonoBehaviour
	{
		public static void Setup(LevelSelectController __instance)
		{
			//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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00cd: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: 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_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			Button component = __instance.sortbutton.GetComponent<Button>();
			Color background = OptionalTheme.colors.playButton.background;
			ColorBlock colors = default(ColorBlock);
			((ColorBlock)(ref colors)).normalColor = background;
			((ColorBlock)(ref colors)).highlightedColor = new Color(background.r + 0.3f, background.g + 0.3f, background.b + 0.3f);
			((ColorBlock)(ref colors)).pressedColor = new Color(background.r + 0.6f, background.g + 0.6f, background.b + 0.6f);
			((ColorBlock)(ref colors)).colorMultiplier = 1f;
			((Selectable)component).colors = colors;
			((Graphic)__instance.sortlabel).color = OptionalTheme.colors.playButton.text;
			((Graphic)((Component)((Component)component).transform.Find("arrow")).GetComponent<Image>()).color = ((Graphic)__instance.sortlabel).color;
			((Graphic)GameObject.Find("MainCanvas/FullScreenPanel/sort_button/btn-shadow").GetComponent<Image>()).color = OptionalTheme.colors.playButton.shadow;
			GameObject val = GameObject.Find("MainCanvas/FullScreenPanel/sort-dropdown");
			val.transform.SetAsLastSibling();
			((Graphic)val.GetComponent<Image>()).color = OptionalTheme.colors.playButton.shadow;
			GameObject val2 = GameObject.Find("MainCanvas/FullScreenPanel/sort-dropdown/face");
			((Graphic)val2.GetComponent<Image>()).color = background;
			Text[] componentsInChildren = val2.GetComponentsInChildren<Text>();
			foreach (Text val3 in componentsInChildren)
			{
				((Graphic)val3).color = ((Graphic)__instance.sortlabel).color;
			}
			RectTransform component2 = __instance.sortdrop.GetComponent<RectTransform>();
			RectTransform component3 = val2.GetComponent<RectTransform>();
			CreateSortOption(__instance, val2, "artist", -75f);
			CreateSortOption(__instance, val2, "long name", -105f);
			int num = 460;
			component3.sizeDelta = new Vector2(180f, (float)num);
			component2.sizeDelta = new Vector2(180f, (float)num);
			Button[] componentsInChildren2 = val2.GetComponentsInChildren<Button>();
			foreach (Button val4 in componentsInChildren2)
			{
				RectTransform component4 = ((Component)val4).GetComponent<RectTransform>();
				component4.anchoredPosition = new Vector2(component4.anchoredPosition.x, component4.anchoredPosition.y + 105f);
			}
			int num2 = -180;
			foreach (FilterOption value in Enum.GetValues(typeof(FilterOption)))
			{
				Toggle val5 = CreateFilterOption(val2, value, new Vector2(242f, (float)(num2 -= 30)));
				ConfigEntry<bool> configEntry = GetConfigEntry(value);
				if (configEntry != null)
				{
					val5.isOn = configEntry.Value;
					((UnityEvent<bool>)(object)val5.onValueChanged).AddListener((UnityAction<bool>)delegate(bool b)
					{
						configEntry.Value = b;
						RefreshLevelSelect.FilterTracks(__instance);
					});
				}
			}
			Button[] componentsInChildren3 = val2.GetComponentsInChildren<Button>();
			foreach (Button val6 in componentsInChildren3)
			{
				RectTransform component5 = ((Component)val6).GetComponent<RectTransform>();
				component5.anchoredPosition = new Vector2(component5.anchoredPosition.x, component5.anchoredPosition.y + 60f);
			}
		}

		private static ConfigEntry<bool> GetConfigEntry(FilterOption filterOption)
		{
			if (1 == 0)
			{
			}
			ConfigEntry<bool> result = (ConfigEntry<bool>)(filterOption switch
			{
				FilterOption.DEFAULT => Plugin.Options.ShowDefault, 
				FilterOption.CUSTOM => Plugin.Options.ShowCustom, 
				FilterOption.PLAYED => Plugin.Options.ShowPlayed, 
				FilterOption.UNPLAYED => Plugin.Options.ShowUnplayed, 
				FilterOption.NOT_S_RANK => Plugin.Options.ShowNotSRank, 
				FilterOption.S_RANK => Plugin.Options.ShowSRank, 
				FilterOption.UNRATED => Plugin.Options.ShowUnrated, 
				FilterOption.RATED => Plugin.Options.ShowRated, 
				FilterOption.ONLY_FAVORITES => Plugin.Options.ShowOnlyFavorites, 
				_ => null, 
			});
			if (1 == 0)
			{
			}
			return result;
		}

		private static void CreateSortOption(LevelSelectController __instance, GameObject face, string sortOption, float y)
		{
			//IL_005e: 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_00ac: Expected O, but got Unknown
			GameObject val = GameObject.Find("MainCanvas/FullScreenPanel/sort-dropdown/face/btn_sort_length");
			Button val2 = Object.Instantiate<Button>(val.GetComponent<Button>(), ((Component)face.transform).transform);
			Object.Destroy((Object)(object)((Component)val2).GetComponentInChildren<LocalizeStringEvent>());
			((Object)val2).name = sortOption;
			RectTransform component = ((Component)val2).GetComponent<RectTransform>();
			component.anchoredPosition = new Vector2(0f, y);
			Text componentInChildren = ((Component)val2).GetComponentInChildren<Text>();
			componentInChildren.text = sortOption;
			Button component2 = ((Component)val2).GetComponent<Button>();
			((UnityEventBase)component2.onClick).RemoveAllListeners();
			((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
			{
				__instance.sortTracks(sortOption, true);
			});
		}

		private static Toggle CreateFilterOption(GameObject face, FilterOption filter, Vector2 position)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_00b0: 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_00ff: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			Toggle val = Object.Instantiate<Toggle>(Plugin.Toggle, ((Component)face.transform).transform);
			string text = (((Object)val).name = Enums.GetDescription(filter));
			RectTransform component = ((Component)val).GetComponent<RectTransform>();
			component.anchoredPosition = position;
			component.sizeDelta = new Vector2(180f, 30f);
			Text componentInChildren = ((Component)val).GetComponentInChildren<Text>();
			componentInChildren.text = text + " tracks";
			componentInChildren.fontSize = 13;
			((Graphic)componentInChildren).color = OptionalTheme.colors.playButton.text;
			Image component2 = ((Component)((Component)val).transform.Find("Background")).GetComponent<Image>();
			((Graphic)component2).rectTransform.sizeDelta = new Vector2(0f, 0f);
			Image component3 = ((Component)((Component)val).transform.Find("Background/Checkmark")).GetComponent<Image>();
			((Graphic)component3).rectTransform.anchoredPosition = new Vector2(-70f, 20f);
			((Graphic)component3).rectTransform.sizeDelta = new Vector2(20f, 20f);
			Text componentInChildren2 = ((Component)val).GetComponentInChildren<Text>();
			((Graphic)componentInChildren2).rectTransform.sizeDelta = new Vector2(180f, ((Graphic)componentInChildren2).rectTransform.sizeDelta.y);
			return val;
		}
	}
	public static class UnityPaths
	{
		public const string FULLSCREENPANEL = "MainCanvas/FullScreenPanel";

		public const string SORT_BUTTON_SHADOW_PATH = "MainCanvas/FullScreenPanel/sort_button/btn-shadow";

		public const string SORT_DROPDOWN_PATH = "MainCanvas/FullScreenPanel/sort-dropdown";

		public const string SORT_DROPDOWN_FACE_PATH = "MainCanvas/FullScreenPanel/sort-dropdown/face";

		public const string SORT_LENGTH_BUTTON_PATH = "MainCanvas/FullScreenPanel/sort-dropdown/face/btn_sort_length";

		public const string GAME_BUTTONS_PANEL = "MainCanvas/FullScreenPanel/GameButtonsPanel";
	}
}
namespace SongOrganizer.Patches
{
	[HarmonyPatch(typeof(HomeController), "Start")]
	public class HomeControllerStartPatch : MonoBehaviour
	{
		private static void Postfix(HomeController __instance)
		{
			Plugin.Toggle = Object.Instantiate<Toggle>(__instance.set_tog_vsync);
			Object.DontDestroyOnLoad((Object)(object)Plugin.Toggle);
			Button component = ((Component)__instance.fullsettingspanel.transform.Find("Settings/GRAPHICS/btn_opengraphicspanel")).gameObject.GetComponent<Button>();
			Plugin.Button = Object.Instantiate<Button>(component);
			((UnityEventBase)Plugin.Button.onClick).RemoveAllListeners();
			Object.DontDestroyOnLoad((Object)(object)Plugin.Button);
			SetInputFieldPrefab();
		}

		private static void SetInputFieldPrefab()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: 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_01c5: Unknown result type (might be due to invalid IL or missing references)
			float num = 250f;
			GameObject val = new GameObject("InputFieldHolderSongOrganizer");
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchoredPosition = Vector2.zero;
			val2.sizeDelta = new Vector2(num, 50f);
			GameObject val3 = Object.Instantiate<GameObject>(val, val.transform);
			GameObject val4 = Object.Instantiate<GameObject>(val3, val.transform);
			((Object)val3).name = "Image";
			((Object)val4).name = "Text";
			Plugin.InputFieldPrefab = val.AddComponent<TMP_InputField>();
			Vector2 anchorMax = (val2.anchorMin = Vector2.zero);
			val2.anchorMax = anchorMax;
			((Selectable)Plugin.InputFieldPrefab).image = val3.AddComponent<Image>();
			RectTransform component = val3.GetComponent<RectTransform>();
			Vector2 val5 = (component.pivot = Vector2.zero);
			anchorMax = (component.anchorMax = val5);
			component.anchorMin = anchorMax;
			component.anchoredPosition = new Vector2(0f, 2f);
			component.sizeDelta = new Vector2(num, 2f);
			RectTransform component2 = val4.GetComponent<RectTransform>();
			Vector2 val7 = (component2.anchorMin = Vector2.zero);
			val5 = (component2.anchoredPosition = val7);
			anchorMax = (component2.anchorMax = val5);
			component2.pivot = anchorMax;
			component2.sizeDelta = new Vector2(num, 50f);
			Plugin.InputFieldPrefab.textComponent = CreateSingleText(val4.transform, "TextLabel", "", Color.white);
			Plugin.InputFieldPrefab.textComponent.rectTransform.pivot = new Vector2(0f, 0.7f);
			Plugin.InputFieldPrefab.textComponent.alignment = (TextAlignmentOptions)513;
			Plugin.InputFieldPrefab.textComponent.margin = new Vector4(2f, 0f, 0f, 0f);
			Plugin.InputFieldPrefab.textComponent.enableWordWrapping = true;
			Plugin.InputFieldPrefab.textViewport = Plugin.InputFieldPrefab.textComponent.rectTransform;
			Object.DontDestroyOnLoad((Object)(object)Plugin.InputFieldPrefab);
		}

		public static TMP_Text CreateSingleText(Transform canvasTransform, string name, string text, Color color)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			return CreateSingleText(canvasTransform, name, text, new Vector2(0f, 1f), ((Component)canvasTransform).GetComponent<RectTransform>().sizeDelta, color);
		}

		public static TMP_Text CreateSingleText(Transform canvasTransform, string name, string text, Vector2 pivot, Vector2 size, Color color)
		{
			//IL_016a: 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_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = GameObject.Find("MainCanvas").gameObject;
			GameObject gameObject2 = ((Component)gameObject.transform.Find("AdvancedInfoPanel/primary-content/intro/copy")).gameObject;
			GameObject val = Object.Instantiate<GameObject>(gameObject2);
			((Object)val).name = "ComfortaaTextPrefab";
			val.SetActive(true);
			Object.DestroyImmediate((Object)(object)val.GetComponent<Text>());
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val2).fontSize = 13f;
			((TMP_Text)val2).text = "DefaultText";
			((TMP_Text)val2).font = TMP_FontAsset.CreateFontAsset(gameObject2.GetComponent<Text>().font);
			Stopwatch stopwatch = Stopwatch.StartNew();
			((TMP_Text)val2).font.fallbackFontAssetTable = (from path in Directory.GetFiles(Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location) + "/Fonts")
				select TMP_FontAsset.CreateFontAsset(new Font(path))).ToList();
			Plugin.Log.LogInfo((object)$"Loaded {((TMP_Text)val2).font.fallbackFontAssetTable.Count} fallback fonts in {stopwatch.Elapsed.TotalSeconds}s");
			((TMP_Text)val2).fontMaterial.SetFloat(ShaderUtilities.ID_FaceDilate, 0.25f);
			((TMP_Text)val2).fontMaterial.EnableKeyword(ShaderUtilities.Keyword_Outline);
			((TMP_Text)val2).fontMaterial.SetFloat(ShaderUtilities.ID_OutlineWidth, 0.25f);
			((TMP_Text)val2).fontMaterial.SetColor(ShaderUtilities.ID_OutlineColor, Color.black);
			((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
			((Component)val2).GetComponent<RectTransform>().sizeDelta = val.GetComponent<RectTransform>().sizeDelta;
			((Component)val2).GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
			((TMP_Text)val2).richText = true;
			((TMP_Text)val2).enableWordWrapping = false;
			Object.DontDestroyOnLoad((Object)(object)val2);
			TMP_Text val3 = (TMP_Text)(object)Object.Instantiate<TextMeshProUGUI>(val2, canvasTransform);
			((Object)val3).name = name;
			val3.text = text;
			((Graphic)val3).color = color;
			((Component)val3).gameObject.GetComponent<RectTransform>().pivot = pivot;
			((Component)val3).gameObject.GetComponent<RectTransform>().sizeDelta = size;
			val3.enableWordWrapping = true;
			((Component)val3).gameObject.SetActive(true);
			return val3;
		}
	}
	[HarmonyPatch(typeof(LevelSelectController), "sortTracks")]
	public class LevelSelectControllerSortTracksPatch : MonoBehaviour
	{
		private static bool Prefix(LevelSelectController __instance, string sortcriteria, bool anim)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Options.SortMode.Value = sortcriteria;
			GlobalVariables.sortmode = sortcriteria;
			__instance.sortlabel.text = "Sort: " + sortcriteria;
			if (anim)
			{
				__instance.clipPlayer.cancelCrossfades();
				__instance.doSfx(__instance.sfx_click);
				__instance.closeSortDropdown();
				__instance.btnspanel.transform.localScale = new Vector3(0.001f, 1f, 1f);
				LeanTween.scaleX(__instance.btnspanel, 1f, 0.2f).setEaseOutQuart();
			}
			if (sortcriteria == "default")
			{
				__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => t1.sort_order.CompareTo(t2.sort_order));
			}
			else if (sortcriteria == "difficulty" && __instance.alltrackslist.TrueForAll((SingleTrackData track) => track is Track))
			{
				__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => ((Track)(object)t1).stars.CompareTo(((Track)(object)t2).stars));
			}
			else
			{
				switch (sortcriteria)
				{
				case "difficulty":
					__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => t1.difficulty.CompareTo(t2.difficulty));
					break;
				case "alpha":
					__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => (t1.trackname_short == null) ? (-1) : t1.trackname_short.Trim().CompareTo(t2.trackname_short.Trim()));
					break;
				case "long name":
					__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => (t1.trackname_long == null) ? (-1) : t1.trackname_long.Trim().CompareTo(t2.trackname_long.Trim()));
					break;
				case "length":
					__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => t1.length.CompareTo(t2.length));
					break;
				case "artist":
					__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => (t1.artist == null) ? (-1) : t1.artist.Trim().CompareTo(t2.artist.Trim()));
					break;
				}
			}
			__instance.songindex = ((!anim) ? GlobalVariables.levelselect_index : 0);
			__instance.populateSongNames(true);
			return false;
		}
	}
	[HarmonyPatch(typeof(LevelSelectController), "updateGraph")]
	public class LevelSelectControllerUpdateGraphPatch : MonoBehaviour
	{
		private static bool Prefix(LevelSelectController __instance)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 5; i++)
			{
				__instance.graphline.SetPosition(i, __instance.getGraphVector(i, (float)Mathf.FloorToInt(Random.value * 100f)));
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(LevelSelectController), "populateSongNames")]
	public class LevelSelectControllerPopulateSongNamesPatch : MonoBehaviour
	{
		private static void Prefix(ref int ___songindex)
		{
			GlobalVariables.levelselect_index = ___songindex;
			Plugin.Options.LastIndex.Value = ___songindex;
		}

		private static void Postfix(LevelSelectController __instance)
		{
			Favorites.ShowFavorites(__instance);
		}
	}
	[HarmonyPatch(typeof(LevelSelectController), "searchForSongName")]
	public class LevelSelectControllerSearchFirstLetterPatch : MonoBehaviour
	{
		private static bool Prefix(string startingletter)
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(LevelSelectController), "Update")]
	public class LevelSelectControllerUpdatePatch : MonoBehaviour
	{
		private static void Postfix(LevelSelectController __instance, ref int ___songindex, ref List<SingleTrackData> ___alltrackslist)
		{
			if ((Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) && Input.GetKeyDown((KeyCode)102))
			{
				((Selectable)Plugin.SearchInput).Select();
			}
			else
			{
				if (Plugin.SearchInput.isFocused || !Input.anyKeyDown || Input.inputString.Length <= 0)
				{
					return;
				}
				char c = Input.inputString.ToLower()[0];
				int num = 1;
				int num2 = ___songindex + 1;
				while (num2 < ___alltrackslist.Count)
				{
					if (___alltrackslist[num2].trackname_short.ToLower().Trim()[0] == c)
					{
						__instance.advanceSongs(num, true);
						return;
					}
					num2++;
					num++;
				}
				int num3 = 0;
				while (num3 < ___songindex)
				{
					if (___alltrackslist[num3].trackname_short.ToLower().Trim()[0] == c)
					{
						__instance.advanceSongs(num, true);
						break;
					}
					num3++;
					num++;
				}
			}
		}
	}
	[HarmonyPatch(typeof(LevelSelectController), "clickBack")]
	public class LevelSelectControllerBackPatch : MonoBehaviour
	{
		private static void Postfix()
		{
			Plugin.UnloadModule();
		}
	}
	[HarmonyPatch(typeof(LevelSelectController), "clickPlay")]
	public class LevelSelectControllerPlayPatch : MonoBehaviour
	{
		private static void Postfix()
		{
			Plugin.UnloadModule();
		}
	}
	[HarmonyPatch(typeof(LevelSelectController), "Start")]
	public class LevelSelectControllerStartPatch : MonoBehaviour
	{
		private static void Prefix()
		{
			GlobalVariables.sortmode = Plugin.Options.SortMode.Value;
			GlobalVariables.levelselect_index = Plugin.Options.LastIndex.Value;
			if (GlobalVariables.levelselect_index >= GlobalVariables.data_tracktitles.Length)
			{
				GlobalVariables.levelselect_index = 0;
			}
			Plugin.FavoriteButtons.Clear();
		}

		private static void Postfix(LevelSelectController __instance)
		{
			OptionalTheme.Setup();
			if (Plugin.RefreshLevelSelect == null)
			{
				Plugin.RefreshLevelSelect = new RefreshLevelSelect(__instance);
				TracksLoadedEvent.EVENT.Register((Listener)(object)Plugin.RefreshLevelSelect);
				Plugin.RefreshLevelSelect.OnTracksLoaded(null);
			}
			SortDropdown.Setup(__instance);
			AddSearchBar(__instance);
			AddStarSlider(__instance);
			Favorites.Setup(__instance);
		}

		private static void AddStarSlider(LevelSelectController __instance)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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)
			GameObject val = GameObject.Find("MainCanvas/FullScreenPanel");
			Text val2 = Object.Instantiate<Text>(__instance.label_speed_slider, val.transform);
			((Object)val2).name = "StarSliderDescription";
			val2.text = "Difficulty range:";
			((Graphic)val2).color = OptionalTheme.colors.songName;
			((Component)val2).GetComponent<RectTransform>().anchoredPosition = new Vector2(-207f, 175f);
			DoubleSlider doubleSlider = new DoubleSlider();
			doubleSlider.Setup(__instance, val.transform, new Vector2(-115f, 176f));
		}

		private static void AddSearchBar(LevelSelectController __instance)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_0186: Expected O, but got Unknown
			GameObject val = GameObject.Find("MainCanvas/FullScreenPanel");
			__instance.scenetitle.SetActive(false);
			Color text2 = OptionalTheme.colors.leaderboard.text;
			Color textOutline = OptionalTheme.colors.leaderboard.textOutline;
			Plugin.SearchInput = Object.Instantiate<TMP_InputField>(Plugin.InputFieldPrefab, val.transform);
			((Object)Plugin.SearchInput).name = "SearchInput";
			((Component)Plugin.SearchInput).GetComponent<RectTransform>().anchoredPosition = new Vector2(190f, 420f);
			((Component)Plugin.SearchInput).GetComponent<RectTransform>().sizeDelta = new Vector2(80f, 14f);
			((Graphic)((Selectable)Plugin.SearchInput).image).color = text2;
			((Graphic)Plugin.SearchInput.textComponent).color = text2;
			Plugin.SearchInput.textComponent.fontMaterial.SetColor(ShaderUtilities.ID_OutlineColor, textOutline);
			Plugin.SearchInput.text = Plugin.Options.SearchValue.Value;
			((UnityEvent<string>)(object)Plugin.SearchInput.onEndEdit).AddListener((UnityAction<string>)delegate(string text)
			{
				Plugin.SearchInput.text = text;
			});
			((UnityEvent<string>)(object)Plugin.SearchInput.onValueChanged).AddListener((UnityAction<string>)delegate(string text)
			{
				Plugin.Options.SearchValue.Value = text;
				RefreshLevelSelect.FilterTracks(__instance);
			});
			Button val2 = AddDeleteButton(Plugin.SearchInput.textComponent);
			((Object)val2).name = "clear search";
			((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
			{
				string selectedTrackref = __instance.alltrackslist[__instance.songindex].trackref;
				Plugin.SearchInput.text = "";
				Plugin.SearchInput.textComponent.text = "";
				Plugin.Options.SearchValue.Value = "";
				RefreshLevelSelect.FilterTracks(__instance);
				GlobalVariables.levelselect_index = __instance.alltrackslist.FindIndex((SingleTrackData track) => track.trackref == selectedTrackref);
				GlobalVariables.levelselect_index = ((GlobalVariables.levelselect_index != -1) ? GlobalVariables.levelselect_index : 0);
				__instance.sortTracks(GlobalVariables.sortmode, false);
			});
		}

		private static Button AddDeleteButton(TMP_Text scoreText)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = ((Component)scoreText).GetComponent<RectTransform>();
			Button val = Object.Instantiate<Button>(Plugin.Button, (Transform)(object)component);
			RectTransform component2 = ((Component)val).GetComponent<RectTransform>();
			((UnityEventBase)val.onClick).RemoveAllListeners();
			component2.sizeDelta = new Vector2(15f, 15f);
			Vector3 position = ((Transform)component).position;
			((Transform)component2).position = new Vector3(position.x, position.y - 0.1f, position.z);
			((Selectable)val).colors = OptionalTheme.colors.replayButton.colors;
			Text componentInChildren = ((Component)val).GetComponentInChildren<Text>();
			componentInChildren.text = "X";
			componentInChildren.fontSize = 12;
			((Graphic)componentInChildren).color = OptionalTheme.colors.replayButton.text;
			return val;
		}
	}
	[HarmonyPatch(typeof(PointSceneController), "Start")]
	public class PointSceneControllerPatch
	{
		private static void Postfix(PointSceneController __instance)
		{
			Favorites.Setup(__instance);
		}
	}
}
namespace SongOrganizer.Data
{
	public class Enums
	{
		public static string GetDescription(Enum value)
		{
			FieldInfo field = value.GetType().GetField(value.ToString());
			return (field.GetCustomAttributes(typeof(DescriptionAttribute), inherit: false) is DescriptionAttribute[] source && source.Any()) ? source.First().Description : value.ToString();
		}
	}
	public enum FilterOption
	{
		DEFAULT,
		CUSTOM,
		UNPLAYED,
		PLAYED,
		[Description("Non S Rank")]
		NOT_S_RANK,
		[Description("S Rank")]
		S_RANK,
		UNRATED,
		RATED,
		[Description("Only Fav")]
		ONLY_FAVORITES
	}
	public class Options
	{
		public const char DELIMETER = '|';

		public ConfigEntry<bool> ShowDefault { get; set; }

		public ConfigEntry<bool> ShowCustom { get; set; }

		public ConfigEntry<bool> ShowUnplayed { get; set; }

		public ConfigEntry<bool> ShowPlayed { get; set; }

		public ConfigEntry<bool> ShowNotSRank { get; set; }

		public ConfigEntry<bool> ShowSRank { get; set; }

		public ConfigEntry<bool> ShowUnrated { get; set; }

		public ConfigEntry<bool> ShowRated { get; set; }

		public ConfigEntry<bool> ShowOnlyFavorites { get; set; }

		public ConfigEntry<string> Favorites { get; set; }

		public ConfigEntry<string> SortMode { get; set; }

		public ConfigEntry<int> LastIndex { get; set; }

		public ConfigEntry<string> SearchValue { get; set; }

		public ConfigEntry<float> MinStar { get; set; }

		public ConfigEntry<float> MaxStar { get; set; }

		private SortedSet<string> FavoriteTrackrefs { get; set; }

		public void SetFavorites()
		{
			FavoriteTrackrefs = new SortedSet<string>();
			if (!Utility.IsNullOrWhiteSpace(Favorites.Value))
			{
				FavoriteTrackrefs = new SortedSet<string>(Favorites.Value.Split(new char[1] { '|' }));
			}
		}

		public bool ContainsFavorite(string trackref)
		{
			return FavoriteTrackrefs.Contains(trackref);
		}

		public void AddFavorite(string trackref)
		{
			FavoriteTrackrefs.Add(trackref);
			Favorites.Value = string.Join("|", FavoriteTrackrefs);
		}

		public void RemoveFavorite(string trackref)
		{
			FavoriteTrackrefs.Remove(trackref);
			Favorites.Value = string.Join("|", FavoriteTrackrefs);
		}
	}
	public class Track : SingleTrackData
	{
		public float stars;

		public bool custom { get; set; }

		public bool rated { get; set; }

		public string letterScore { get; set; }

		public int[] scores { get; set; }

		public bool isFavorite { get; set; }

		public Track()
		{
		}

		public Track(SingleTrackData other)
		{
			base.trackname_long = other.trackname_long;
			base.trackname_short = other.trackname_short;
			base.year = other.year;
			base.artist = other.artist;
			base.desc = other.desc;
			base.genre = other.genre;
			base.difficulty = other.difficulty;
			base.tempo = other.tempo;
			base.length = other.length;
			base.sort_order = other.sort_order;
			base.trackindex = other.trackindex;
			base.trackref = other.trackref;
		}
	}
}