//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
#if LEGACY
using System.Media;
#endif // LEGACY

namespace CommonHelpers {

//**************************************************************************************************
/// <summary>
/// </summary>
public delegate bool HPlaySoundCallback(HSound sound,bool synchronously);
//**************************************************************************************************


//**************************************************************************************************
/// <summary>
/// </summary>
public delegate bool? HAbortSoundCallback();
//**************************************************************************************************


//**************************************************************************************************
/// <summary>
/// </summary>
[HThreadSafe]
public sealed partial class HSound {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static bool IsMute
{
   get { return _IsMute_; }
   set { _IsMute_ = value; }
}

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

public static HPlaySoundCallback PlaySoundCallback
{
   get { return _PlaySoundCallback_; }
   set { _PlaySoundCallback_ = value; }
}

public static HAbortSoundCallback AbortSoundCallback
{
   get { return _AbortSoundCallback_; }
   set { _AbortSoundCallback_ = value; }
}

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

public static bool IsInitialized
{
   get { return _IsInitialized_; }
}

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

public static void Initialize()
{
   lock (_StaticSyncRoot_)
      if (!_IsInitialized_)
      {
         HBeeper.Initialize();
         _IsInitialized_ = true;
      }
}

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

public static void Play([HOptional] HSound sound)
{
   Play(sound,false);
}

public static void Play([HOptional] HSound sound,bool ignoreMute)
{
   Play(sound,ignoreMute,false);
}

public static void Play([HOptional] HSound sound,bool ignoreMute,bool synchronously)
{
   if ( sound != HSounds.None && (ignoreMute || !IsMute) )
   {
      var callback = PlaySoundCallback;

      if ( callback == null || !callback( sound, synchronously ) )
         if ( sound != null )
            foreach (var layout in HSounds.DefaultBeepsLayouts)
               if ( layout.Sound == sound )
               {
                  HBeeper.Play( synchronously, layout.Beeps );
                  return;
               }
   }
}

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

public static void SyncPlay([HOptional] HSound sound)
{
   SyncPlay(sound,false);
}

public static void SyncPlay([HOptional] HSound sound,bool ignoreMute)
{
   Play(sound,ignoreMute,true);
}

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

public static bool? Abort()
{
   var callback = AbortSoundCallback;
   return callback != null ? callback() :
      HBeeper.StopActivePlayback( false );
}

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

public static void PlaySuccess    () { PlaySuccess    ( false ); }
public static void PlayNotSuccess () { PlayNotSuccess ( false ); }
public static void PlayInformation() { PlayInformation( false ); }
public static void PlayError      () { PlayError      ( false ); }
public static void PlayWarning    () { PlayWarning    ( false ); }
public static void PlayExclamation() { PlayExclamation( false ); }
public static void PlayQuestion   () { PlayQuestion   ( false ); }
public static void PlayDisabled   () { PlayDisabled   ( false ); }

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

public static void PlaySuccess    ( bool ignoreMute ) { Play( HSounds.Success    , ignoreMute ); }
public static void PlayNotSuccess ( bool ignoreMute ) { Play( HSounds.NotSuccess , ignoreMute ); }
public static void PlayInformation( bool ignoreMute ) { Play( HSounds.Information, ignoreMute ); }
public static void PlayError      ( bool ignoreMute ) { Play( HSounds.Error      , ignoreMute ); }
public static void PlayWarning    ( bool ignoreMute ) { Play( HSounds.Warning    , ignoreMute ); }
public static void PlayExclamation( bool ignoreMute ) { Play( HSounds.Exclamation, ignoreMute ); }
public static void PlayQuestion   ( bool ignoreMute ) { Play( HSounds.Question   , ignoreMute ); }
public static void PlayDisabled   ( bool ignoreMute ) { Play( HSounds.Disabled   , ignoreMute ); }

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

static HSound()
{
   CommonHelpers_Plus.Access();
}

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

static volatile bool
   _IsMute_,
   _IsInitialized_;

static volatile HPlaySoundCallback
   _PlaySoundCallback_;
static volatile HAbortSoundCallback
   _AbortSoundCallback_;

static readonly object
   _StaticSyncRoot_ = new object();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HSound
//**************************************************************************************************

} // CommonHelpers
