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

namespace CommonHelpers {

//**************************************************************************************************
/// <summary>
/// </summary>
public partial class HDisposableHandle: HDisposable {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public HDisposableHandle(IntPtr handle)
   :this ( handle, false )
{}

public HDisposableHandle( IntPtr handle,
                          bool isOfInvalidHandleValueCategory )
   :this ( handle, isOfInvalidHandleValueCategory, null )
{}

public HDisposableHandle( IntPtr handle,
                          [HOptional] HCloseHandleCallback closeHandleCallback )
   :this ( handle, false, closeHandleCallback )
{}

public HDisposableHandle( IntPtr handle,
                          bool isOfInvalidHandleValueCategory,
                          [HOptional] HCloseHandleCallback closeHandleCallback )
{
   HHandle.SimpleVerification(
      handle, isOfInvalidHandleValueCategory );

   _Handle_                         = handle;
   _IsOfInvalidHandleValueCategory_ = isOfInvalidHandleValueCategory;
   _CloseHandleCallback_            = closeHandleCallback;

   ValidateDisposable();
}

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

public static implicit operator IntPtr( HDisposableHandle dh )
{
   HArgChecking.VerifyNotNull( dh );
   return dh.IsInvalid ?
      HHandle.GetNullOrInvalidValue( dh._IsOfInvalidHandleValueCategory_ ) :
      dh._Handle_;
}

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

public IntPtr Value
{
   get
   {
      VerifyValidDisposable();
      return _Handle_;
   }
}

public bool IsOfInvalidHandleValueCategory
{
   get
   {
      VerifyValidDisposable();
      return _IsOfInvalidHandleValueCategory_;
   }
}

public HCloseHandleCallback CloseHandleCallback
{
   get
   {
      VerifyValidDisposable();
      return _CloseHandleCallback_;
   }
}

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

public bool IsInvalid
{
   get
   {
      return HHandle.IsInvalid( Value, IsOfInvalidHandleValueCategory );
   }
}

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

public bool Invalidate()
{
   if ( IsInvalid ) return false;
   _Handle_ = HHandle.GetNullOrInvalidValue( IsOfInvalidHandleValueCategory );
   return true;
}

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

protected override void OnDispose(bool synchronous)
{
   HHandle.ResetAndClose( ref _Handle_,
      _IsOfInvalidHandleValueCategory_,
      _CloseHandleCallback_ );
}

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

static HDisposableHandle()
{
   CommonHelpers_PAccess.Access();
}

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

IntPtr
   _Handle_;
bool
   _IsOfInvalidHandleValueCategory_;
HCloseHandleCallback
   _CloseHandleCallback_;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HDisposableHandle
//**************************************************************************************************

} // CommonHelpers
