using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml.Linq; using TechnologyAssembler.Core.Assets; namespace HashCalculator.GUI { public class AssetEntry : IEquatable, IComparable { public string Type { get; } public string Name { get; } public string NameString { get; } public IEnumerable DisplayLabels { get; } public uint InstanceId => SageHash.CalculateLowercaseHash(Name); public string InstanceIdString => $"{InstanceId:x8} ({InstanceId,10})"; public string LocalizedNames { get { if (!Translator.HasProvider) { return string.Empty; } if (!DisplayLabels.Any()) { return "N/A"; } return DisplayLabels.Select(Translator.Translate).Aggregate((x, y) => $"{x} {y}"); } } public static AssetEntry? TryParse(XElement element) { if (element == null) { return null; } if (element.Name.Namespace != ModXml.EalaAsset) { TracerListener.WriteLine($"Unknown namespace: {element.Name.Namespace}"); } try { return new AssetEntry(element); } catch (Exception e) { TracerListener.WriteLine($"Failed to parse element: {e}"); } return null; } public AssetEntry(XElement element) { if (element == null) { throw new ArgumentNullException(nameof(element)); } if (element.Name.Namespace != ModXml.EalaAsset) { throw new NotSupportedException(); } Type = element.Name.LocalName; var id = element.Attribute("id")?.Value; Name = id ?? throw new NotSupportedException(); NameString = $"{Type}:{Name}"; var labels = from name in element.Elements(ModXml.EalaAsset + "DisplayName") select name.Value; var transformLabels = from name in element.Elements(ModXml.EalaAsset + "DisplayNameTransformed") select name.Value; DisplayLabels = labels.Concat(transformLabels).ToArray(); } public AssetEntry(Asset asset) { if (asset is null) { throw new ArgumentNullException(nameof(asset)); } Type = asset.TypeName; Name = asset.InstanceName; NameString = $"{Type}:{Name}"; DisplayLabels = Array.Empty(); if (InstanceId != asset.InstanceId || SageHash.CalculateBinaryHash(Type) != asset.TypeId) { throw new InvalidDataException(); } } public bool Equals(AssetEntry? entry) { return this == entry; } // override object.Equals public override bool Equals(object? obj) { // // See the full list of guidelines at // http://go.microsoft.com/fwlink/?LinkID=85237 // and also the guidance for operator== at // http://go.microsoft.com/fwlink/?LinkId=85238 // if (!(obj is AssetEntry entry)) { return false; } return this == entry; } public static bool operator ==(AssetEntry? a, AssetEntry? b) { if (a is null || b is null) { return a is null == b is null; } if (ReferenceEquals(a, b)) { return true; } return a.Type == b.Type && a.InstanceId == b.InstanceId; } public static bool operator !=(AssetEntry? a, AssetEntry? b) { return !(a == b); } // override object.GetHashCode public override int GetHashCode() { return HashCode.Combine(Type, InstanceId); } public int CompareTo(AssetEntry? other) { if (other is null) { throw new ArgumentNullException(nameof(other)); } return string.CompareOrdinal(NameString, other.NameString); } public static bool operator <(AssetEntry? left, AssetEntry? right) { return left is null ? right is object : left.CompareTo(right) < 0; } public static bool operator <=(AssetEntry? left, AssetEntry? right) { return left is null || left.CompareTo(right) <= 0; } public static bool operator >(AssetEntry? left, AssetEntry? right) { return left is object && left.CompareTo(right) > 0; } public static bool operator >=(AssetEntry? left, AssetEntry? right) { return left is null ? right is null : left.CompareTo(right) >= 0; } } }