Unit
using ForgeUnitsCLR;
using System;
using System.Collections.Generic;
namespace DynamoUnits
{
    public class Unit
    {
        internal readonly Unit forgeUnit;
        public string Name => forgeUnit.getName();
        public string TypeId => forgeUnit.getTypeId();
        public IEnumerable<Unit> ConvertibleUnits {
            get {
                Dictionary<string, Unit> convertibleUnits = Utilities.ForgeUnitsEngine.getConvertibleUnits(TypeId);
                return Utilities.ConvertForgeUnitDictionaryToCollection(convertibleUnits);
            }
        }
        public IEnumerable<Quantity> QuantitiesContainingUnit {
            get {
                Dictionary<string, Quantity> quantitiesContainingUnit = Utilities.ForgeUnitsEngine.getQuantitiesContainingUnit(TypeId);
                return Utilities.CovertForgeQuantityDictionaryToCollection(quantitiesContainingUnit);
            }
        }
        internal Unit(Unit unit)
        {
            if (unit == null)
                throw new ArgumentNullException();
            forgeUnit = unit;
        }
        public static Unit ByTypeID(string typeId)
        {
            try {
                return new Unit(Utilities.ForgeUnitsEngine.getUnit(typeId));
            } catch (Exception) {
                if (Utilities.TryParseTypeId(typeId, out string typeName, out Version _)) {
                    Dictionary<string, Version> allLatestRegisteredUnitVersions = Utilities.GetAllLatestRegisteredUnitVersions();
                    if (allLatestRegisteredUnitVersions.TryGetValue(typeName, out Version value))
                        return new Unit(Utilities.ForgeUnitsEngine.getUnit(typeName + "-" + value.ToString()));
                }
                throw;
            }
        }
        public static bool AreUnitsConvertible(Unit fromUnit, Unit toUnit)
        {
            return Utilities.ForgeUnitsEngine.areUnitsConvertible(fromUnit.TypeId, toUnit.TypeId);
        }
        public override string ToString()
        {
            return "Unit(Name = " + Name + ")";
        }
        public override int GetHashCode()
        {
            return (Name ?? string.Empty).GetHashCode() ^ (TypeId ?? string.Empty).GetHashCode();
        }
        public override bool Equals(object obj)
        {
            return EqualsImpl(obj as Unit);
        }
        internal bool EqualsImpl(Unit u)
        {
            if ((object)u == null)
                return false;
            if ((object)this == u)
                return true;
            if (GetType() != u.GetType())
                return false;
            if (Name == u.Name)
                return TypeId == u.TypeId;
            return false;
        }
        public static bool operator ==(Unit lhs, Unit rhs)
        {
            if ((object)lhs == null) {
                if ((object)rhs == null)
                    return true;
                return false;
            }
            return lhs.EqualsImpl(rhs);
        }
        public static bool operator !=(Unit lhs, Unit rhs)
        {
            return !(lhs == rhs);
        }
    }
}