//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;

namespace CommonHelpers {

//**************************************************************************************************
public class HNLibError {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[HOptionalValue]
public HNLibErrorCat Category { get; private set; }

[HNotNull]
public string Message { get; private set; }

[HOptionalValue]
public Int32 Code { get {
   unchecked { return (Int32)UCode; } }}
[HOptionalValue]
public UInt32 UCode { get; private set; }

[HOptionalValue]
public Int32 Value { get {
   unchecked { return (Int32)UValue; } }}
[HOptionalValue]
public UInt32 UValue { get; private set; }

//--------------------------------------------------------------------------------------------------

public bool HasError => Category != 0;
public bool HasCode  => UCode    != 0;
public bool HasValue => UValue   != 0;

public bool IsGeneralError    => Category == HNLibErrorCat.General;
public bool IsArgumentError   => Category == HNLibErrorCat.Argument;
public bool IsOutOfMemoryError=> Category == HNLibErrorCat.OutOfMemory;
public bool IsSystemError     => Category == HNLibErrorCat.System;
public bool IsCOMError        => Category == HNLibErrorCat.COM;
public bool IsSpecialError    => Category == HNLibErrorCat.Special;

//--------------------------------------------------------------------------------------------------

public HNLibError([HRO] ref HNLibErrorStruct errorStruct)
{
   if ( errorStruct.MessagePtr == IntPtr.Zero )
   {
      Category = HNLibErrorCat.Special;
      Message = HLocal.TEXT(
         "Error message pointer is unexpectedly null (NLErrorStruct.MessagePtr).",
         "Указатель сообщения ошибки неожиданно пуст (NLErrorStruct.MessagePtr)." );
      return;
   }
   Category = errorStruct.Category;
   Message = HSZ.FromPointer( errorStruct.MessagePtr );
   UCode = errorStruct.Code32;
   UValue = errorStruct.Value32;
/*
   if ( errorStruct.MessageRetransQuery && IsCOMError )
      Message = HCOMError.HRToMessage( Code );
*/
}

//==================================================================================================

public Exception CreateException()
{
   return CreateException( 0 );
}
public Exception CreateException(HNLibErrorToExceptonFlags flags)
{
   if ( (flags & HNLibErrorToExceptonFlags.TreatAnyAsOperationFailed) != 0 )
      return new HOperationFailedException( Message );
   switch ( Category )
   {
   case HNLibErrorCat.Argument:
      return new ArgumentException( Message );
   case HNLibErrorCat.OutOfMemory:
      if ( (flags & HNLibErrorToExceptonFlags.OutOfMemoryAsOperationFailed) != 0 )
         break;
      return new OutOfMemoryException( Message );
   }
   return new HOperationFailedException( Message );
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HNLibError
//**************************************************************************************************

} // CommonHelpers
