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

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

//**************************************************************************************************
/// <summary>
/// </summary>
public partial class HAsStringComparer: IComparer {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public bool IsOrdinal
{
   get { return _Ordinal_; }
}

public bool IsInvariant
{
   get { return _Invariant_; }
}

public bool IgnoreCase
{
   get { return _IgnoreCase_; }
}

public StringComparison? StringComparison
{
   get { return _StringComparison_; }
}

public HStringComparisonCallback StringComparisonCallback
{
   get { return _StringComparisonCallback_; }
}

public HToStringCallback ToStringCallback
{
   get { return _ToStringCallback_; }
}

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

public HAsStringComparer()
{}

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

public HAsStringComparer(bool ignoreCase)
   :this (null,ignoreCase) {}

public HAsStringComparer(StringComparison stringComparison)
   :this (null,stringComparison) {}

public HAsStringComparer([HOptional] HStringComparisonCallback stringComparisonCallback)
   :this (null,stringComparisonCallback) {}

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

public HAsStringComparer( [HOptional] HToStringCallback toStringCallback,
                          bool ignoreCase )
{
   _ToStringCallback_ = toStringCallback;
   _IgnoreCase_ = ignoreCase;
}

public HAsStringComparer( [HOptional] HToStringCallback toStringCallback,
                          StringComparison stringComparison )
{
   _ToStringCallback_ = toStringCallback;
   _StringComparison_ = stringComparison;
}

public HAsStringComparer( [HOptional] HToStringCallback toStringCallback,
                          [HOptional] HStringComparisonCallback stringComparisonCallback )
{
   _ToStringCallback_ = toStringCallback;
   _StringComparisonCallback_ = stringComparisonCallback;
}

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

public int Compare([HOptional] object o1,[HOptional] object o2)
{
   string s1=null, s2=null;

   if (o1!=null)
      s1 = ToStringCallback != null ? ToStringCallback(o1) : o1.ToString();
   if (o2!=null)
      s2 = ToStringCallback != null ? ToStringCallback(o2) : o2.ToString();

   if ( StringComparisonCallback != null )
      return StringComparisonCallback( s1, s2 );

   if (s1==null && s2==null)
      return 0;
   if (s1==null && s2!=null)
      return -1;
   if (s1!=null && s2==null)
      return 1;

   return
      StringComparison.HasValue ? string.Compare( s1, s2, StringComparison.Value ) :
      IsOrdinal ? HString.CompareOrdinal( s1, s2, IgnoreCase ) :
      IsInvariant ? HString.CompareInvariant( s1, s2, IgnoreCase ) :
      string.Compare( s1, s2 );
}

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

public static HAsStringComparer CreateOrdinal(bool ignoreCase)
{
   return CreateOrdinal(null,ignoreCase);
}

public static HAsStringComparer CreateInvariant(bool ignoreCase)
{
   return CreateInvariant(null,ignoreCase);
}

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

public static HAsStringComparer CreateOrdinal( [HOptional] HToStringCallback toStringCallback,
                                               bool ignoreCase )
{
   var instance = new HAsStringComparer( ignoreCase );
   instance._Ordinal_ = true;
   instance._ToStringCallback_ = toStringCallback;
   return instance;
}

public static HAsStringComparer CreateInvariant( [HOptional] HToStringCallback toStringCallback,
                                                 bool ignoreCase )
{
   var instance = new HAsStringComparer( ignoreCase );
   instance._Invariant_ = true;
   instance._ToStringCallback_ = toStringCallback;
   return instance;
}

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

static HAsStringComparer()
{
   CommonHelpers_Core.Access();
}

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

bool
   _Ordinal_,
   _Invariant_,
   _IgnoreCase_;

StringComparison?
   _StringComparison_;

HStringComparisonCallback
   _StringComparisonCallback_;

HToStringCallback
   _ToStringCallback_;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HAsStringComparer
//**************************************************************************************************

} // CommonHelpers (.WASM)
