using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;
using StarterNG.Application;
using StarterNG.Classes;
using StarterNG.Infrastructure;
using StarterNG.Services;
namespace StarterNG;
public partial class App : Avalonia.Application
{
///
/// The translation table, as a static source for the XAML bindings. Code
/// should take
/// through its constructor rather than reading this.
///
public static LocalizationService Loc => AppServices.Current.Localization;
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
AppServices.Current.SettingsStore.Load();
KeyboardConfig.Instance.Load();
CultureInfo ci = CultureInfo.InstalledUICulture ;
var langName = AppServices.Current.Settings.LanguageWasSet
? AppServices.Current.Settings.Language
: ci.Name switch
{
"pl-PL" => "Polski",
_ => "English"
};
AppServices.Current.Settings.Language = langName;
// What eu07.ini asked for, before the starter picks a language it can
// actually display.
string requestedCode = AppServices.Current.Settings.LanguageCode;
ApplyLanguage(langName);
// The starter ships no translation for this code, so its own interface
// falls back - but the simulator has one and keeps it. Overwriting the key
// here would silently move eu07.exe to English on the next save.
if (!string.IsNullOrWhiteSpace(requestedCode) &&
!string.Equals(requestedCode, Loc.CurrentLangCode, StringComparison.OrdinalIgnoreCase))
AppServices.Current.Settings.LanguageCode = requestedCode;
}
public static void ApplyLanguage(string langNameOrCode)
{
var resolvedName = Loc.Load(langNameOrCode);
// The service is the authority on which language actually loaded: the code
// goes to eu07.ini for the simulator, the name to the picker.
AppServices.Current.Settings.Language = resolvedName;
AppServices.Current.Settings.LanguageCode = Loc.CurrentLangCode;
ApplyCulture(Loc.CurrentLangCode);
}
private static void ApplyCulture(string langCode)
{
CultureInfo culture;
try
{
culture = langCode switch
{
"" or "en" => CultureInfo.InvariantCulture,
"cz" => CultureInfo.GetCultureInfo("cs"),
_ => CultureInfo.GetCultureInfo(langCode)
};
}
catch (CultureNotFoundException)
{
culture = CultureInfo.InvariantCulture;
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
desktop.ShutdownRequested += (_, _) =>
{
try { AppServices.Current.SettingsStore.CaptureAndSave(); }
catch (Exception ex) { Diagnostics.Log("Settings save", ex); }
AppServices.Current.MissingVehicleLog.Dump();
try
{
if (KeyboardConfig.Instance.Dirty)
KeyboardConfig.Instance.Save();
}
catch (Exception ex) { Diagnostics.Log("Keyboard config save", ex); }
Diagnostics.Flush();
};
SplashWindow? splash = null;
bool mainReady = false;
var sw = System.Diagnostics.Stopwatch.StartNew();
Task.Run(async () =>
{
var progress = new Progress(status =>
{
Dispatcher.UIThread.Post(() =>
{
if (mainReady)
return;
if (sw.ElapsedMilliseconds > 300 && splash == null)
{
splash = new SplashWindow();
desktop.MainWindow = splash;
splash.Show();
}
splash?.Report(status);
});
});
AppServices.Current.Library.Load(progress);
}).ContinueWith(load =>
{
Dispatcher.UIThread.Post(async () =>
{
MainWindow main;
try
{
main = new MainWindow();
}
catch (Exception ex)
{
Diagnostics.Log("Main window", ex);
Diagnostics.Flush();
Console.Error.WriteLine(ex);
mainReady = true;
splash?.Close();
desktop.Shutdown(1);
return;
}
mainReady = true;
desktop.MainWindow = main;
main.Show();
splash?.Close();
splash = null;
if (load.IsFaulted && load.Exception is { } error)
{
var inner = error.GetBaseException();
Diagnostics.Log("Game data load", inner);
await Diagnostics.ReportAsync(
$"{Loc["FaultLoadData"]}{Environment.NewLine}{Environment.NewLine}{Loc["FaultDetail"]} {inner.Message}");
}
var check = Diagnostics.InstallationCheck();
var faults = check.Run();
if (faults.Count > 0)
{
await Diagnostics.ReportAsync(
string.Join(Environment.NewLine, faults) + Environment.NewLine + Environment.NewLine +
Loc["FaultBadInstall"]);
}
if (check.ExecutableMissing())
await main.OfferExecutablePickAsync();
});
});
}
base.OnFrameworkInitializationCompleted();
}
}