using System; using SabreTools.Data.Extensions; namespace SabreTools.Metadata.DatItems { /// /// Base class for all items included in a set that are backed by an internal model /// public abstract class DatItem : DatItem, IEquatable>, IComparable>, ICloneable where T : Data.Models.Metadata.DatItem, new() { #region Constructors /// /// Create a default, empty object /// public DatItem() { _internal = new T(); SetName(string.Empty); Write(Data.Models.Metadata.DatItem.TypeKey, ItemType); Write(MachineKey, new Machine()); } /// /// Create an object from the internal model /// public DatItem(T item) { _internal = item; Write(Data.Models.Metadata.DatItem.TypeKey, ItemType); Write(MachineKey, new Machine()); } #endregion #region Cloning Methods /// /// Get a clone of the current internal model /// public virtual T GetInternalClone() => (_internal.Clone() as T)!; #endregion #region Comparision Methods /// public int CompareTo(DatItem? other) { // If the other item doesn't exist if (other is null) return 1; // Get the names to avoid changing values string? selfName = GetName(); string? otherName = other.GetName(); // If the names are equal if (selfName == otherName) return Equals(other) ? 0 : 1; // If `otherName` is null, Compare will return > 0 // If `selfName` is null, Compare will return < 0 return string.Compare(selfName, otherName, StringComparison.Ordinal); } /// /// Determine if an item is a duplicate using partial matching logic /// /// DatItem to use as a baseline /// True if the items are duplicates, false otherwise public virtual bool Equals(DatItem? other) { // If the other value is null if (other is null) return false; // Get the types for comparison ItemType selfType = ReadString(Data.Models.Metadata.DatItem.TypeKey).AsItemType(); ItemType otherType = other.ReadString(Data.Models.Metadata.DatItem.TypeKey).AsItemType(); // If we don't have a matched type, return false if (selfType != otherType) return false; // Compare the internal models return _internal.EqualTo(other._internal); } #endregion } }