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

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

//**************************************************************************************************
/// <summary>
/// </summary>
public static partial class HInCodeSupportedLanguageSelector {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static HInCodeSupportedLanguage DefaultLanguage
{
   get { return _DefaultLanguage_; }
   set { _DefaultLanguage_ = value; }
}

public static HInCodeSupportedLanguage UILanguage
{
   get { return Select( CultureInfo.CurrentUICulture ); }
}

public static ConcurrentDictionary<string,string>
   UseOfBigCulture => _UseOfBigCulture_;

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

public static HInCodeSupportedLanguage Select([HOptional] CultureInfo culture)
{
   return Select( culture, false );
}
public static HInCodeSupportedLanguage Select( [HOptional] CultureInfo culture,
                                               bool ignoreBigCultureUsage )
{
   return DoSelect( culture, ignoreBigCultureUsage ) ?? DefaultLanguage;
}

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

internal static HInCodeSupportedLanguage? DoSelect( [HOptional] CultureInfo culture,
                                                    bool ignoreBigCultureUsage )
{
   if ( culture == null )
      return null;
   string neutralCultureName = HCultureInfo.ToNeutral( culture ).Name;
   HInCodeSupportedLanguage? language;
   if ( (language = GetLanguageByCultureName( neutralCultureName )).HasValue )
      return language;
   if ( ignoreBigCultureUsage )
      return null;
   bool unknownLanguageNameEncountered;
   if ( GetBigLanguageFromEnvironment( out language, out unknownLanguageNameEncountered ) )
      return language;
   if ( unknownLanguageNameEncountered )
      return null;
   string neutralCultName;
   if ( UseOfBigCulture.TryGetValue( culture.Name, out neutralCultName ) &&
        (language = GetLanguageByCultureName( neutralCultName )).HasValue )
      return language;
   if ( UseOfBigCulture.TryGetValue( neutralCultureName, out neutralCultureName ) &&
        (language = GetLanguageByCultureName( neutralCultureName )).HasValue )
      return language;
   return null;
}

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

static HInCodeSupportedLanguage? GetLanguageByCultureName([HOptional] string cultureNeutralName)
{
   switch ( cultureNeutralName )
   {
      case HNeutralCultureNames.English: return HInCodeSupportedLanguage.English;
      case HNeutralCultureNames.Russian: return HInCodeSupportedLanguage.Russian;
      //case HNeutralCultureNames.X1: return HInCodeSupportedLanguage.Lang_X1;
      //case HNeutralCultureNames.X2: return HInCodeSupportedLanguage.Lang_X2;
   }
   return null;
}

static bool GetBigLanguageFromEnvironment( out HInCodeSupportedLanguage? languare,
                                           out bool unknownLanguageNameEncountered )
{
   languare = null;
   unknownLanguageNameEncountered = false;
   string bigLanguageName = Environment.GetEnvironmentVariable( "NLS_BigLanguageName" );
   if ( bigLanguageName == null )
      return false;
   bigLanguageName = bigLanguageName.TrimEnd();
   if ( HString.Equals( bigLanguageName, "English", true ) )
      languare = HInCodeSupportedLanguage.English;
   else
   if ( HString.Equals( bigLanguageName, "Russian", true ) )
      languare = HInCodeSupportedLanguage.Russian;
/*
   else
   if ( HString.Equals( bigLanguageName, "XLanguage-1", true ) )
      languare = HInCodeSupportedLanguage.Lang_X1;
   else
   if ( HString.Equals( bigLanguageName, "XLanguage-2", true ) )
      languare = HInCodeSupportedLanguage.Lang_X2;
*/
   unknownLanguageNameEncountered = !languare.HasValue;
   return languare.HasValue;
}

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

static HInCodeSupportedLanguageSelector()
{
   CommonHelpers_Core.Access();
   UseOfBigCulture_Default();
}

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

static volatile HInCodeSupportedLanguage
   _DefaultLanguage_ = HInCodeSupportedLanguage.English;
static ConcurrentDictionary<string,string>
   _UseOfBigCulture_ = new ConcurrentDictionary<string,string>();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HInCodeSupportedLanguageSelector
//**************************************************************************************************

} // CommonHelpers (.WASM)
