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

#if !WASM
namespace CommonHelpers {
#else
namespace CommonHelpers.WASM {
#endif

//**************************************************************************************************
partial class HValueParser {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static bool TryParse<T>(string src,out T dst,out HParseValueException e) where T: struct
   { return TryParse(src,(object[])null,out dst,out e); }
public static bool TryParse<T>( string src, T def,
                                out T dst, out HParseValueException e ) where T: struct
   { return TryParse(src,(object[])null,def,out dst,out e); }

public static bool TryParse<T>( string src, IFormatProvider provider,
                                out T dst, out HParseValueException e ) where T: struct
   { return TryParse(src,new object[]{provider},out dst,out e); }
public static bool TryParse<T>( string src, IFormatProvider provider, T def,
                                out T dst, out HParseValueException e ) where T: struct
   { return TryParse(src,new object[]{provider},def,out dst,out e); }

public static bool TryParse<T>( string src, [HOptional] object[] additionalParams,
                                out T dst, out HParseValueException e ) where T: struct
   { return TryParseEx(src,additionalParams,null,out dst,out e); }

public static bool TryParse<T>( string src, [HOptional] object[] additionalParams, T def,
                                out T dst, out HParseValueException e ) where T: struct
   { return TryParseEx(src,additionalParams,(T?)def,out dst,out e); }

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

public static bool TryParseInvariant<T>( string src,
                                         out T dst, out HParseValueException e ) where T: struct
   { return TryParse(src,new object[]{(IFormatProvider)null},out dst,out e); }
public static bool TryParseInvariant<T>( string src, T def,
                                         out T dst, out HParseValueException e ) where T: struct
   { return TryParse(src,new object[]{(IFormatProvider)null},def,out dst,out e); }

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

public static bool TryParseWithProviderEx<T>( string src, IFormatProvider provider,
                                              T? def, out T dst,
                                              out HParseValueException e ) where T: struct
{
   return TryParseEx( src, new object[]{ provider }, def, out dst, out e );
}

public static bool TryParseWithParamsEx<T>( string src, [HOptional] object[] additionalParams,
                                            T? def, out T dst,
                                            out HParseValueException e ) where T: struct
{
   return TryParseEx( src, additionalParams, def, out dst, out e );
}

public static bool TryParseInvariantEx<T>( string src, T? def,
                                           out T dst, out HParseValueException e ) where T: struct
{
   return TryParseEx( src, new object[]{ (IFormatProvider)null }, def, out dst, out e );
}

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

internal static bool TryParseEx<T>( string src, [HOptional] object[] additionalParams,
                                    T? def, out T dst, out HParseValueException e )
   where T: struct
{
   return TryParseEx
   (
      src, "Parse",
      HArray.Concatenate(
         new object[]{ src },
         additionalParams ?? new object[0] ),
      def, out dst, out e
   );
}

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

internal static bool TryParseEx<T>( string src, string parseMethodName, object[] parameters, T? def,
                                    out T dst, out HParseValueException e ) where T: struct
{
   Type type = typeof(T);

   HGenericTypeChecking.VerifyStdValueType( type );
   HArgChecking.VerifyNotNull( src );

   src = src.Trim();

   if (src=="")
      if (def!=null)
      {
         dst=def.Value; e=null; return true;
      }
      else
      {
         dst = default(T);
         e = new HParseValueException( "Value string is empty." );
         return false;
      }

   try
   {
      dst = (T)HMethodInfo.InvokeStaticMethod( type, parseMethodName, parameters );
   }
   catch (TargetInvocationException x)
   {
      var ie=x.InnerException;
      if (ie==null)
         throw;
      if (!(ie is FormatException || ie is OverflowException))
         throw ie;
      dst = default(T);
      e = new HParseValueException( ie.Message );
      return false;
   }
   e = null;
   return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HValueParser
//**************************************************************************************************

} // CommonHelpers (.WASM)
