using System;

namespace CommonHelpers {

//**************************************************************************************************
static class HString {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static bool Equals( [HOptional] string str_1, [HOptional] string str_2 ) =>
   Equals( str_1, str_2, false );
public static bool Equals( [HOptional] string str_1, [HOptional] string str_2, bool ignoreCase ) =>
   CompareOrdinal( str_1, str_2, ignoreCase ) == 0;

public static bool EqualsInvariant( [HOptional] string str_1, [HOptional] string str_2 ) =>
   EqualsInvariant( str_1, str_2, false );
public static bool EqualsInvariant( [HOptional] string str_1, [HOptional] string str_2,
                                    bool ignoreCase ) =>
   CompareInvariant( str_1, str_2, ignoreCase ) == 0;

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

public static int CompareOrdinal( [HOptional] string str_1, [HOptional] string str_2 ) =>
   CompareOrdinal( str_1, str_2, false );
public static int CompareOrdinal( [HOptional] string str_1,
                                  [HOptional] string str_2,
                                  bool ignoreCase ) =>
   string.Compare( str_1, str_2,
      ignoreCase ?
         StringComparison.OrdinalIgnoreCase :
         StringComparison.Ordinal );

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

public static int CompareInvariant( [HOptional] string str_1, [HOptional] string str_2 ) =>
   CompareInvariant( str_1, str_2, false );
public static int CompareInvariant( [HOptional] string str_1,
                                    [HOptional] string str_2,
                                    bool ignoreCase ) =>
   string.Compare( str_1, str_2,
      ignoreCase ?
         StringComparison.InvariantCultureIgnoreCase :
         StringComparison.InvariantCulture );

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

public static bool IsBlank([HOptional] string str)
{
   if ( str == null )
      return false;
   foreach (char ch in str)
      if ( !char.IsWhiteSpace( ch ) )
         return false;
   return true;
}

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

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
[HStrictResult]
public static char LastChar(string str)
{
   HArgChecking.VerifyNotNull( str );
   if ( str == "" )
      throw new ArgumentException( "Can not extract last character from empty string." );
   return str[ str.Length-1 ];
}
public static char? LastCharOrNull([HOptional] string str)
{
   return string.IsNullOrEmpty( str ) ? null : (char?)str[ str.Length-1 ];
}

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

public static bool StartsWithWhiteSpace([HOptional] string str)
{
   return !string.IsNullOrEmpty( str ) && char.IsWhiteSpace( str[0] );
}
public static bool EndsWithWhiteSpace([HOptional] string str)
{
   return !string.IsNullOrEmpty( str ) && char.IsWhiteSpace( LastChar( str ) );
}
public static bool HasBoundaryWhiteSpace([HOptional] string str)
{
   return StartsWithWhiteSpace( str ) || EndsWithWhiteSpace( str );
}

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

public static string NullAsEmpty([HOptional] string str)
{
   return str ?? "";
}
public static string BlankAsEmpty(string str)
{
   return IsBlank( str ) ? "" : str;
}

[HOptionalResult]
public static string EmptyAsNull([HOptional] string str)
{
   return str=="" ? null : str;
}
[HOptionalResult]
public static string BlankAsNull([HOptional] string str)
{
   return IsBlank( str ) ? null : str;
}

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

/// <exception cref="ArgumentNullException" />
public static string ConvertAsText(string multilineStr)
{
   HArgChecking.VerifyNotNull( multilineStr );
   return HTextBuilder.ConvertAsText( multilineStr ).ToString();
}
/// <exception cref="ArgumentNullException" />
//[CLSCompliant(false)]
public static string ConvertAsText(ref string multilineStr)
{
   return multilineStr = ConvertAsText( multilineStr );
}

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

/// <exception cref="ArgumentNullException" />
public static string FormatAsText(string multilineStrFmt,params object[] parameters)
{
   HArgChecking.VerifyNotNull( multilineStrFmt );
   HArgChecking.VerifyNotNulls( parameters );
   return ConvertAsText( string.Format( multilineStrFmt, parameters ) );
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HString
//**************************************************************************************************

} // CommonHelpers
