using System;
using System.Globalization;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
///
/// An LCID is a 4-byte value. The value supplied in an LCID is a standard numeric substitution for the international [RFC5646] string.
///
///
///
///
///
///
///
///
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("winnls.h")]
public partial struct LCID : IComparable, IComparable, IConvertible, IEquatable, IEquatable
{
/// Sort order identifiers.
public enum SORT : byte
{
/// sorting default
SORT_DEFAULT = 0x0,
/// Invariant (Mathematical Symbols)
SORT_INVARIANT_MATH = 0x1,
/// Japanese XJIS order
SORT_JAPANESE_XJIS = 0x0,
/// Japanese Unicode order (no longer supported)
SORT_JAPANESE_UNICODE = 0x1,
/// Japanese radical/stroke order
SORT_JAPANESE_RADICALSTROKE = 0x4,
/// Chinese BIG5 order
SORT_CHINESE_BIG5 = 0x0,
/// PRC Chinese Phonetic order
SORT_CHINESE_PRCP = 0x0,
/// Chinese Unicode order (no longer supported)
SORT_CHINESE_UNICODE = 0x1,
/// PRC Chinese Stroke Count order
SORT_CHINESE_PRC = 0x2,
/// Traditional Chinese Bopomofo order
SORT_CHINESE_BOPOMOFO = 0x3,
/// Traditional Chinese radical/stroke order.
SORT_CHINESE_RADICALSTROKE = 0x4,
/// Korean KSC order
SORT_KOREAN_KSC = 0x0,
/// Korean Unicode order (no longer supported)
SORT_KOREAN_UNICODE = 0x1,
/// German Phone Book order
SORT_GERMAN_PHONE_BOOK = 0x1,
/// Hungarian Default order
SORT_HUNGARIAN_DEFAULT = 0x0,
/// Hungarian Technical order
SORT_HUNGARIAN_TECHNICAL = 0x1,
/// Georgian Traditional order
SORT_GEORGIAN_TRADITIONAL = 0x0,
/// Georgian Modern order
SORT_GEORGIAN_MODERN = 0x1,
}
internal uint _value;
private const int langMask = 0x0FFFF;
private const uint sortMask = 0xF0000;
private const int sortShift = 16;
/// Initializes a new instance of the structure.
/// The raw LCID value.
public LCID(uint rawValue) => _value = rawValue;
/// Initializes a new instance of the structure.
///
/// Language identifier. This parameter is a combination of a primary language identifier and a sublanguage identifier.
///
/// Sort order identifier.
public LCID(LANGID lgid, SORT srtid) => _value = (((uint)(ushort)srtid) << sortShift) | lgid;
/// Retrieves a language identifier from a locale identifier.
public LANGID LANGID => (LANGID)_value;
/// Retrieves a sort order identifier from a locale identifier.
public SORT SORTID => (SORT)(((_value) >> sortShift) & 0xf);
/// Gets the value.
/// The value.
public uint Value { get => _value; private set => _value = value; }
/// Compares the current object with another object of the same type.
/// An object to compare with this object.
///
/// A value that indicates the relative order of the objects being compared. The return value has the following
/// meanings: Value Meaning Less than zero This object is less than the parameter.Zero This object is equal
/// to . Greater than zero This object is greater than .
///
public int CompareTo(LCID other) => _value.CompareTo(other._value);
///
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current
/// instance precedes, follows, or occurs in the same position in the sort order as the other object.
///
/// An object to compare with this instance.
///
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less
/// than zero This instance precedes in the sort order. Zero This instance occurs in the same position in the
/// sort order as . Greater than zero This instance follows in the sort order.
///
public int CompareTo(object obj) => obj is IConvertible c ? _value.CompareTo(c.ToUInt32(null)) :
throw new ArgumentException(@"Object cannot be converted to a UInt32 value for comparison.", nameof(obj));
/// Determines whether the specified , is equal to this instance.
/// The to compare with this instance.
/// true if the specified is equal to this instance; otherwise, false.
public override bool Equals(object obj) => obj is IConvertible c && _value.Equals(c.ToUInt32(null));
/// Indicates whether the current object is equal to another object of the same type.
/// An object to compare with this object.
/// true if the current object is equal to the parameter; otherwise, false.
public bool Equals(LCID other) => other._value == _value;
/// Indicates whether the current object is equal to another object of the same type.
/// An object to compare with this object.
/// true if the current object is equal to the parameter; otherwise, false.
public bool Equals(uint other) => other == _value;
/// Returns a hash code for this instance.
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
public override int GetHashCode() => _value.GetHashCode();
///
public TypeCode GetTypeCode() => Value.GetTypeCode();
/// Returns a that represents this instance.
/// A that represents this instance.
public override string ToString() => ToString(CultureInfo.InvariantCulture);
///
public string ToString(IFormatProvider provider) => string.Format(provider, "0x{0:X8}", _value);
/// Implements the operator ==.
/// The first .
/// The second .
/// The result of the operator.
public static bool operator ==(LCID hrLeft, LCID hrRight) => hrLeft._value == hrRight._value;
/// Implements the operator ==.
/// The first .
/// The second .
/// The result of the operator.
public static bool operator ==(LCID hrLeft, uint hrRight) => hrLeft._value == hrRight;
/// Implements the operator !=.
/// The first .
/// The second .
/// The result of the operator.
public static bool operator !=(LCID hrLeft, LCID hrRight) => !(hrLeft == hrRight);
/// Implements the operator !=.
/// The first .
/// The second .
/// The result of the operator.
public static bool operator !=(LCID hrLeft, uint hrRight) => !(hrLeft == hrRight);
/// Performs an implicit conversion from to .
/// The value.
/// The result of the conversion.
public static implicit operator LCID(uint value) => new(value);
/// Performs an explicit conversion from to .
/// The value.
/// The result of the conversion.
public static explicit operator uint(LCID value) => value._value;
/// The default locale for the operating system. The value of this constant is 0x0800.
public static LCID LOCALE_SYSTEM_DEFAULT = new(LANGID.LANG_SYSTEM_DEFAULT, SORT.SORT_DEFAULT);
/// The default locale for the user or process. The value of this constant is 0x0400.
public static LCID LOCALE_USER_DEFAULT = new(LANGID.LANG_USER_DEFAULT, SORT.SORT_DEFAULT);
///
/// Windows Vista and later: The default custom locale. When an NLS function must return a locale identifier for a supplemental
/// locale for the current user, the function returns this value instead of LOCALE_USER_DEFAULT. The value of LOCALE_CUSTOM_DEFAULT
/// is 0x0C00.
///
public static LCID LOCALE_CUSTOM_DEFAULT => new(new LANGID(LANGID.LANG.LANG_NEUTRAL, LANGID.SUBLANG.SUBLANG_CUSTOM_DEFAULT), SORT.SORT_DEFAULT);
///
/// Windows Vista and later: An unspecified custom locale, used to identify all supplemental locales except the locale for the
/// current user. Supplemental locales cannot be distinguished from one another by their locale identifiers, but can be
/// distinguished by their locale names. Certain NLS functions can return this constant to indicate that they cannot provide a
/// useful identifier for a particular locale. The value of LOCALE_CUSTOM_UNSPECIFIED is 0x1000.
///
public static LCID LOCALE_CUSTOM_UNSPECIFIED => new(new LANGID(LANGID.LANG.LANG_NEUTRAL, LANGID.SUBLANG.SUBLANG_CUSTOM_UNSPECIFIED), SORT.SORT_DEFAULT);
///
/// Windows Vista and later: The default custom locale for MUI. The user preferred UI languages and the system preferred UI
/// languages can include at most a single language that is implemented by a Language Interface Pack (LIP) and for which the
/// language identifier corresponds to a supplemental locale. If there is such a language in a list, the constant is used to refer
/// to that language in certain contexts. The value of LOCALE_CUSTOM_UI_DEFAULT is 0x1400.
///
public static LCID LOCALE_CUSTOM_UI_DEFAULT => new(new LANGID(LANGID.LANG.LANG_NEUTRAL, LANGID.SUBLANG.SUBLANG_UI_CUSTOM_DEFAULT), SORT.SORT_DEFAULT);
///
/// The neutral locale. This constant is generally not used when calling NLS APIs. Instead, use either LOCALE_SYSTEM_DEFAULT or
/// LOCALE_USER_DEFAULT. The value of LOCALE_NEUTRAL is 0x0000.
///
public static LCID LOCALE_NEUTRAL => new(new LANGID(LANGID.LANG.LANG_NEUTRAL, LANGID.SUBLANG.SUBLANG_NEUTRAL), SORT.SORT_DEFAULT);
///
/// Windows XP: The locale used for operating system-level functions that require consistent and locale-independent results. For
/// example, the invariant locale is used when an application compares character strings using the CompareString function and
/// expects a consistent result regardless of the user locale. The settings of the invariant locale are similar to those for English
/// (United States) but should not be used to display formatted data. Typically, an application does not use LOCALE_INVARIANT
/// because it expects the results of an action to depend on the rules governing each individual locale. The value of
/// LOCALE_INVARIANT IS 0x007f.
///
public static LCID LOCALE_INVARIANT => new(new LANGID(LANGID.LANG.LANG_INVARIANT, LANGID.SUBLANG.SUBLANG_NEUTRAL), SORT.SORT_DEFAULT);
///
bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
///
byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)Value).ToByte(provider);
///
char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)Value).ToChar(provider);
///
DateTime IConvertible.ToDateTime(IFormatProvider provider) => ((IConvertible)Value).ToDateTime(provider);
///
decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)Value).ToDecimal(provider);
///
double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)Value).ToDouble(provider);
///
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)Value).ToInt16(provider);
///
int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)Value).ToInt32(provider);
///
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)Value).ToInt64(provider);
///
sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)Value).ToSByte(provider);
///
float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)Value).ToSingle(provider);
///
object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
///
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)Value).ToUInt16(provider);
///
uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)Value).ToUInt32(provider);
///
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)Value).ToUInt64(provider);
}
}