using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; namespace Claunia.Localization.Core { /// /// Represents the localization /// public class Localization { readonly Dictionary> indexes; readonly ObservableCollection messages; readonly ObservableCollection translators; public Localization() { Creation = DateTime.UtcNow; LastWritten = DateTime.UtcNow; Project = new Project(); Project.ProjectModified += OnModified; translators = new ObservableCollection(); Translators = new ReadOnlyObservableCollection(translators); translators.CollectionChanged += OnModified; messages = new ObservableCollection(); Messages = new ReadOnlyObservableCollection(messages); messages.CollectionChanged += OnModified; indexes = new Dictionary>(); } /// Date this localization has been created public DateTime Creation { get; } /// Date this localization has been modified public DateTime LastWritten { get; private set; } /// Project this localization belongs to public Project Project { get; } /// List of translators that have worked in this localization public ReadOnlyObservableCollection Translators { get; } /// /// List of messages present in this localization /// public ReadOnlyObservableCollection Messages { get; } void OnModified(object sender, EventArgs args) { LastWritten = DateTime.UtcNow; } /// /// Adds a new translator to the localization /// /// Translator full name, english-form, in ASCII /// Translator e-mail /// Translator full name, in native form /// The new translator public Translator NewTranslator(string name, string email, string nativeName = null) { int id = translators.Count > 0 ? translators.Max(t => t.Id) + 1 : 1; Translator translator = new Translator(id) {Name = name, Email = email}; translator.Modified += OnModified; translators.Add(translator); return translator; } /// /// Removes a translator from the localization /// /// Translator to remove /// true if the translator has been removed successfully, false otherwise public bool RemoveTranslator(Translator translator) => !(translator is null) && translators.Remove(translator); /// /// Removes a translator from the localization /// /// ID of the translator to remove /// true if the translator has been removed successfully, false otherwise public bool RemoveTranslator(int id) { Translator translator = translators.FirstOrDefault(t => t.Id == id); return !(translator is null) && translators.Remove(translator); } public Message NewMessage() { Message message = new Message(); message.Modified += OnModified; messages.Add(message); return message; } public bool RemoveMessage(Message message) => !(message is null) && messages.Remove(message); public bool RemoveMessage(string id) { Message message = messages.FirstOrDefault(t => t.Id == id); return !(message is null) && messages.Remove(message); } public Dictionary GetIndex(string locale) { // TODO: Plurals if(indexes.TryGetValue(locale, out Dictionary existingIndex)) return existingIndex; Dictionary index = new Dictionary(); foreach(Message message in messages) { LocalizedString translated = message.Translations.FirstOrDefault(l => l.Locale == locale); if(translated is null) { // TODO: Requested "es" but only "es_ES" exists int underscore = locale.IndexOf('_'); if(underscore > 0) translated = message.Translations.FirstOrDefault(l => l.Locale == locale.Substring(underscore)); } index.Add(message.Id, translated is null ? message.Source.Singular : translated.Singular); } indexes.Add(locale, index); return index; } } }