/*===============================================================================
Copyright (C) 2025 PhantomsXR Ltd. All Rights Reserved.
This file is part of the Phantom.XRMOD.Localization.Runtime.
The XR-MOD cannot be copied, distributed, or made available to
third-parties for commercial purposes without written permission of PhantomsXR Ltd.
Contact nswell@phantomsxr.com for licensing requests.
===============================================================================*/
using System;
using System.Collections.Generic;
using Phantom.XRMOD.ActionNotification.Runtime;
using Phantom.XRMOD.XRMODUtilites.Runtime;
using UnityEngine;
namespace Phantom.XRMOD.Localization.Runtime
{
///
/// Manages localization data and language settings for the application.
/// This class follows a singleton pattern to ensure a single instance throughout the application lifecycle.
///
public class LocalizationManagerV2
{
private static LocalizationManagerV2 _LOCALIZATION_MANAGER_V2;
///
/// Gets the singleton instance of the LocalizationManagerV2.
///
/// The singleton instance of LocalizationManagerV2.
public static LocalizationManagerV2 Instance => _LOCALIZATION_MANAGER_V2 ??= new LocalizationManagerV2();
///
/// Gets or sets the current language of the application.
///
public SystemLanguage CurrentLanguage { get; private set; }
///
/// Event triggered when the current language changes.
/// Subscribers can update their UI or content based on the new language.
///
public static event Action OnLanguageChanged;
///
/// Gets the name of the current project being localized.
///
public string ProjectName { get; private set; }
///
/// Gets the current XRMOD platform.
///
public XRMODPlatform Platform { get; private set; }
///
/// Gets the dictionary containing localization databases, keyed by project name and scope.
///
public Dictionary Database { get; private set; } = new();
private LocalizationManagerV2()
{
CurrentLanguage = Application.systemLanguage;
ActionNotificationCenter.DefaultCenter.AddObserver(ReceivedChangeLanguageRequest, nameof(SetLanguage));
}
private void ReceivedChangeLanguageRequest(BaseNotificationData _obj)
{
if (string.IsNullOrEmpty(_obj.BaseData)) return;
if (Enum.TryParse(_obj.BaseData, out var tmp_CurrentLanguage))
{
SetLanguage(tmp_CurrentLanguage);
}
}
///
/// Initializes the localization manager with a specific project, scope, database, language, and platform.
///
/// The name of the project.
/// The scope of the localization (e.g., InExperiences, Global).
/// The localization database to use for this scope.
/// The initial language to set.
/// The XRMOD platform.
public void Initialize(string _project, LocalizationScope _scope, LocalizationDatabase _database,
SystemLanguage _language, XRMODPlatform _platform)
{
if (_scope == LocalizationScope.InExperiences)
{
ProjectName = _project;
Database.TryAdd($"{_project}.{_scope}", _database);
}
else
{
Database.TryAdd($"{_scope}.{_scope}", _database);
}
Platform = _platform;
SetLanguage(_language);
}
///
/// Initializes the localization manager with a specific project, scope, and database.
/// The initial language is set to the system's current language, and the platform is detected automatically.
///
/// The name of the project.
/// The scope of the localization (e.g., InExperiences, Global).
/// The localization database to use for this scope.
public void Initialize(string _project, LocalizationScope _scope, LocalizationDatabase _database)
{
if (_scope == LocalizationScope.InExperiences)
{
ProjectName = _project;
Database.TryAdd($"{_project}.{_scope}", _database);
}
else
{
Database.TryAdd($"{_scope}.{_scope}", _database);
}
Platform = RuntimePlatformHelper.GetXRMODRuntimePlatformType();
}
///
/// Sets the current language of the application.
/// If the new language is different from the current one, the OnLanguageChanged event is invoked.
///
/// The new SystemLanguage to set.
public void SetLanguage(SystemLanguage _newLang)
{
if (_newLang == CurrentLanguage) return;
CurrentLanguage = _newLang;
OnLanguageChanged?.Invoke(_newLang);
}
///
/// Retrieves a localized template for a given key and scope.
///
/// The key to look up in the localization database.
/// The scope of the localization (e.g., InExperiences, Global).
/// A LocalizedTemplate instance if the database and key are found, otherwise null.
public LocalizedTemplate GetLocalizedTemplate(string _key, LocalizationScope _scope)
{
return GetLocalizationDatabase(_scope, out var tmp_Database)
? new LocalizedTemplate(tmp_Database, _key, CurrentLanguage, _scope, Platform)
: null;
}
///
/// Releases a localization database from memory based on project name and scope.
///
/// The name of the project associated with the database.
/// The scope of the localization database to release.
/// True if the database was successfully removed, false otherwise.
public bool Release(string _projectName, LocalizationScope _scope)
{
return Database.Remove($"{_projectName}.{_scope}");
}
///
/// Attempts to retrieve a localization database based on its scope.
///
/// The scope of the localization database to retrieve.
/// When this method returns, contains the LocalizationDatabase associated with the specified scope, if found; otherwise, null.
/// True if the LocalizationDatabase is found; otherwise, false.
internal bool GetLocalizationDatabase(LocalizationScope _scope, out LocalizationDatabase _database)
{
return _scope == LocalizationScope.InExperiences
? Database.TryGetValue($"{ProjectName}.{_scope}", out _database)
: Database.TryGetValue($"{_scope}.{_scope}", out _database);
}
}
}