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

#if !WASM
namespace user_rtx { using u = user_rtx;
#else
namespace user_rtx.wasm { using u = user_rtx.wasm;
#endif

/// <summary>
/// Sound simple interface (Default implementation is relied on Win32-beeper.)
/// </summary>
public static class sound {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static object SyncRoot { get; } = new object();

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

[u.volatile_access]
public static bool IsMute {
   get => _isMute;
   set => _isMute = value; }

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

[u.volatile_access]
public static u.PlaySoundFN? PlaySoundFN {
   get => _playSoundFN;
   set => _playSoundFN = value; }

[u.volatile_access]
public static u.AbortSoundFN? AbortSoundFN {
   get => _abortSoundFN;
   set => _abortSoundFN = value; }

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

public static bool Play( string soundId ) =>
   PlayX( soundId, false, false );

public static bool Play( string soundId, bool ignoreMute ) =>
   PlayX( soundId, ignoreMute, false );

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

public static bool SyncPlay( string soundId ) =>
   PlayX( soundId, false, true );

public static bool SyncPlay( string soundId, bool ignoreMute ) =>
   PlayX( soundId, ignoreMute, true );

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

public static bool PlayX( string soundId, bool ignoreMute, bool synchronously )
{
   if ( u.sound_ids.IsNoneId( soundId ) || !ignoreMute && IsMute )
      return false;
   object? playbackInfo = u.sound_ids.GetPlayback( soundId );
   var routine = PlaySoundFN;
   if ( routine != null && routine( soundId, playbackInfo, synchronously ) )
      return true;
   return ( playbackInfo is u.NamedBeepArray layout ) ?
      u.beeper.Play( synchronously, layout.Notes ) :
      false;
}

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

public static (bool? WasTerminated,Exception? Error) Abort()
{
   var routine = AbortSoundFN;
   try {
      return routine != null ?
         ( routine(), null ) :
         ( u.beeper.StopActivePlayback( false ), null );
   } catch ( Exception e ) {
      return ( false, e );
   }
}

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

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 PlayConfirmation () => PlayConfirmation  ( false );
public static void PlayAttention    () => PlayAttention     ( false );
public static void PlayDisabled     () => PlayDisabled      ( false );

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

public static void PlaySuccess( bool ignoreMute )
   => Play( u.sound_ids.Success, ignoreMute );
public static void PlayNotSuccess( bool ignoreMute )
   => Play( u.sound_ids.NotSuccess, ignoreMute );
public static void PlayInformation( bool ignoreMute )
   => Play( u.sound_ids.Information, ignoreMute );
public static void PlayError( bool ignoreMute )
   => Play( u.sound_ids.Error, ignoreMute );
public static void PlayWarning( bool ignoreMute )
   => Play( u.sound_ids.Warning, ignoreMute );
public static void PlayExclamation( bool ignoreMute )
   => Play( u.sound_ids.Exclamation, ignoreMute );
public static void PlayQuestion( bool ignoreMute )
   => Play( u.sound_ids.Question, ignoreMute );
public static void PlayConfirmation( bool ignoreMute )
   => Play( u.sound_ids.Confirmation, ignoreMute );
public static void PlayAttention( bool ignoreMute )
   => Play( u.sound_ids.Attention, ignoreMute );
public static void PlayDisabled( bool ignoreMute )
   => Play( u.sound_ids.Disabled, ignoreMute );

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

static volatile bool
   _isMute;
static volatile u.PlaySoundFN?
   _playSoundFN;
static volatile u.AbortSoundFN?
   _abortSoundFN;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // sound

} // user_rtx (.wasm)
