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

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

/// <summary>
/// Field information (reflection)
/// </summary>
public static class field {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static object? GetStaticValue( Type type, string fieldName ) =>
   GetStaticValueUsingVisibilityFlags( type, fieldName, BindingFlags.Public );

public static void SetStaticValue( Type type, string fieldName, object value ) =>
   SetStaticValueUsingVisibilityFlags( type, fieldName, BindingFlags.Public, value );

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

public static object? GetInstanceValue( object obj, string fieldName ) =>
   GetInstanceValueUsingVisibilityFlags( obj, fieldName, BindingFlags.Public );

public static void SetInstanceValue( object obj, string fieldName, object value ) =>
   SetInstanceValueUsingVisibilityFlags( obj, fieldName, BindingFlags.Public, value );

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

public static object? GetStaticValueUsingVisibilityFlags( Type type,
                                                          string fieldName,
                                                          BindingFlags visibilityFlags ) =>
   type.InvokeMember( fieldName,
      visibilityFlags | BindingFlags.Static | BindingFlags.GetField,
      null, null, u.args.Empty );

public static void SetStaticValueUsingVisibilityFlags( Type type,
                                                       string fieldName,
                                                       BindingFlags visibilityFlags,
                                                       object value ) =>
   type.InvokeMember( fieldName,
      visibilityFlags | BindingFlags.Static | BindingFlags.SetField,
      null, null, new object[]{ value } );

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

public static object? GetInstanceValueUsingVisibilityFlags( object obj,
                                                            string fieldName,
                                                            BindingFlags visibilityFlags ) =>
   obj.GetType().InvokeMember( fieldName,
      visibilityFlags | BindingFlags.Instance | BindingFlags.GetField,
      null, null, u.args.Empty );

public static void SetInstanceValueUsingVisibilityFlags( object obj,
                                                         string fieldName,
                                                         BindingFlags visibilityFlags,
                                                         object value ) =>
   obj.GetType().InvokeMember( fieldName,
      visibilityFlags | BindingFlags.Instance | BindingFlags.SetField,
      null, null, new object[]{ value } );

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // field

} // user_rtx (.wasm)
