using Microsoft.VisualBasic.CompilerServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using RhythmBase.Adofai.Components;
using RhythmBase.Adofai.Converters;
using RhythmBase.Adofai.Events;
using RhythmBase.Converters;
using RhythmBase.Events;
using RhythmBase.Exceptions;
using RhythmBase.Settings;
using System.Collections.ObjectModel;
namespace RhythmBase.Adofai.Utils
{
///
/// Useful utils.
///
[StandardModule]
public static class Utils
{
///
/// Converts a given type to an ADEventType enumeration.
///
/// The type to convert.
/// The corresponding ADEventType enumeration.
/// Thrown when no matching EventType is found or multiple matching EventTypes are found.
public static ADEventType ADConvertToEnum(Type type)
{
if (ADETypesToEnum == null)
{
if (type.Name.StartsWith("AD"))
{
string name = type.Name[2..];
if (Enum.TryParse(name, out ADEventType result))
return result;
}
throw new IllegalEventTypeException(type, "Unable to find a matching EventType.");
}
ADEventType ADConvertToEnum;
try
{
ADConvertToEnum = ADETypesToEnum![type].Single();
}
catch
{
throw new IllegalEventTypeException(type, "Multiple matching EventTypes were found. Please check if the type is an abstract class type.", new ArgumentException("Multiple matching EventTypes were found. Please check if the type is an abstract class type.", nameof(type)));
}
return ADConvertToEnum;
}
///
/// Converts a generic type to an ADEventType enumeration.
///
/// The type to convert, which must inherit from ADBaseEvent and have a parameterless constructor.
/// The corresponding ADEventType enumeration.
public static ADEventType ConvertToADEnum() where T : ADBaseEvent, new() => ADConvertToEnum(typeof(T));
///
/// Converts a generic type to an array of ADEventType enumerations.
///
/// The type to convert, which must inherit from BaseEvent.
/// An array of corresponding ADEventType enumerations.
/// Thrown when no matching EventType is found.
public static ADEventType[] ConvertToADEnums() where T : BaseEvent
{
ADEventType[] ConvertToADEnums;
try
{
ConvertToADEnums = ADETypesToEnum[typeof(T)];
}
catch
{
throw new IllegalEventTypeException(typeof(T), "This exception is not expected. Please contact the developer to handle this exception.");
}
return ConvertToADEnums;
}
///
/// Converts a string representation of an ADEventType to a Type.
///
/// The string representation of the ADEventType.
/// The corresponding Type.
public static Type ADConvertToType(string type)
{
bool flag = Enum.TryParse(type, out ADEventType result);
Type ADConvertToType;
if (flag)
ADConvertToType = ConvertToType(result);
else
ADConvertToType = ConvertToType(ADEventType.CustomEvent);
return ADConvertToType;
}
///
/// Converts an ADEventType enumeration to a Type.
///
/// The ADEventType enumeration to convert.
/// The corresponding Type.
/// Thrown when the type is illegal.
/// Thrown when the value does not exist in the EventType enumeration.
public static Type ConvertToType(this ADEventType type)
{
Type ConvertToType;
if (ADEnumToEType == null)
ConvertToType = Type.GetType(string.Format("{0}.AD{1}", typeof(ADBaseEvent).Namespace, type))
?? throw new RhythmBaseException(string.Format("Illegal Type: {0}.", type));
else
try
{
ConvertToType = ADEnumToEType[type];
}
catch
{
throw new IllegalEventTypeException(Conversions.ToString((int)type), "This value does not exist in the EventType enumeration.");
}
return ConvertToType;
}
///
/// Gets a JsonSerializer configured with the necessary converters for the given ADLevel and settings.
///
/// The ADLevel instance.
/// The LevelReadOrWriteSettings instance.
/// A configured JsonSerializer instance.
public static JsonSerializer GetSerializer(this ADLevel adlevel, LevelReadOrWriteSettings settings)
{
JsonSerializer AllInOneSerializer = new();
JsonConverterCollection converters = AllInOneSerializer.Converters;
converters.Add(new StringEnumConverter());
converters.Add(new ColorConverter());
converters.Add(new ADTileConverter(adlevel));
converters.Add(new ADCustomTileEventConverter(adlevel, settings));
converters.Add(new ADCustomEventConverter(adlevel, settings));
converters.Add(new ADBaseTileEventConverter(adlevel, settings));
converters.Add(new ADBaseEventConverter(adlevel, settings));
return AllInOneSerializer;
}
private static readonly ReadOnlyCollection ADETypes = (from i in typeof(ADBaseEvent).Assembly.GetTypes()
where i.IsAssignableTo(typeof(ADBaseEvent))
select i).ToList().AsReadOnly();
///
/// A dictionary that records the correspondence of ADEventType to event types inheriting from ADBaseEvent.
///
public static readonly ReadOnlyDictionary ADETypesToEnum = ADETypes.ToDictionary((Type i) => i, (Type i) => (from j in ADETypes
where (j == i || j.IsAssignableTo(i)) && !j.IsAbstract
select j).Select((Type j) => ADConvertToEnum(j)).ToArray()).AsReadOnly();
///
/// A dictionary that records the correspondence of event types inheriting from ADBaseEvent to ADEventType.
///
public static readonly ReadOnlyDictionary ADEnumToEType = Enum.GetValues().ToDictionary((ADEventType i) => i, ConvertToType).AsReadOnly();
}
}