using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.Json.Serialization;
#nullable enable
namespace Terminal.Gui;
///
/// Contains a dictionary of the s for a Terminal.Gui application.
///
///
///
/// A Theme is a collection of settings that are named. The default theme is named "Default".
///
///
/// The property is used to detemrine the currently active theme.
///
///
///
/// is a singleton class. It is created when the first property is accessed.
/// Accessing is the same as accessing .
///
///
/// "Themes": [
/// {
/// "Default": {
/// "ColorSchemes": [
/// {
/// "TopLevel": {
/// "Normal": {
/// "Foreground": "BrightGreen",
/// "Background": "Black"
/// },
/// "Focus": {
/// "Foreground": "White",
/// "Background": "Cyan"
///
/// },
/// "HotNormal": {
/// "Foreground": "Brown",
/// "Background": "Black"
///
/// },
/// "HotFocus": {
/// "Foreground": "Blue",
/// "Background": "Cyan"
/// },
/// "Disabled": {
/// "Foreground": "DarkGray",
/// "Background": "Black"
///
/// }
/// }
/// }
///
public class ThemeManager : IDictionary {
private static readonly ThemeManager _instance = new ThemeManager ();
static ThemeManager () { } // Make sure it's truly lazy
private ThemeManager () { } // Prevent instantiation outside
///
/// Class is a singleton...
///
public static ThemeManager Instance { get { return _instance; } }
private static string _theme = string.Empty;
///
/// The currently selected theme. This is the internal version; see .
///
[JsonInclude, SerializableConfigurationProperty (Scope = typeof (SettingsScope), OmitClassName = true), JsonPropertyName ("Theme")]
internal static string SelectedTheme {
get => _theme;
set {
var oldTheme = _theme;
_theme = value;
if (oldTheme != _theme &&
ConfigurationManager.Settings! ["Themes"]?.PropertyValue is Dictionary themes &&
themes.ContainsKey (_theme)) {
ConfigurationManager.Settings! ["Theme"].PropertyValue = _theme;
Instance.OnThemeChanged (oldTheme);
}
}
}
///
/// Gets or sets the currently selected theme. The value is persisted to the "Theme"
/// property.
///
[JsonIgnore]
public string Theme {
get => ThemeManager.SelectedTheme;
set {
ThemeManager.SelectedTheme = value;
}
}
///
/// Called when the selected theme has changed. Fires the event.
///
internal void OnThemeChanged (string theme)
{
Debug.WriteLine ($"Themes.OnThemeChanged({theme}) -> {Theme}");
ThemeChanged?.Invoke (this, new ThemeManagerEventArgs (theme));
}
///
/// Event fired he selected theme has changed.
/// application.
///
public event EventHandler? ThemeChanged;
///
/// Holds the definitions.
///
[JsonInclude, JsonConverter (typeof (DictionaryJsonConverter))]
[SerializableConfigurationProperty (Scope = typeof (SettingsScope), OmitClassName = true)]
public static Dictionary? Themes {
get => ConfigurationManager.Settings? ["Themes"]?.PropertyValue as Dictionary; // themes ?? new Dictionary ();
set {
//if (themes == null || value == null) {
// themes = value;
//} else {
// themes = (Dictionary)DeepMemberwiseCopy (value!, themes!)!;
//}
ConfigurationManager.Settings! ["Themes"].PropertyValue = value;
}
}
internal static void Reset ()
{
Debug.WriteLine ($"Themes.Reset()");
Themes?.Clear ();
SelectedTheme = string.Empty;
}
internal static void GetHardCodedDefaults ()
{
Debug.WriteLine ($"Themes.GetHardCodedDefaults()");
var theme = new ThemeScope ();
theme.RetrieveValues ();
Themes = new Dictionary (StringComparer.InvariantCultureIgnoreCase) { { "Default", theme } };
SelectedTheme = "Default";
}
#region IDictionary
#pragma warning disable 1591
public ICollection Keys => ((IDictionary)Themes!).Keys;
public ICollection Values => ((IDictionary)Themes!).Values;
public int Count => ((ICollection>)Themes!).Count;
public bool IsReadOnly => ((ICollection>)Themes!).IsReadOnly;
public ThemeScope this [string key] { get => ((IDictionary)Themes!) [key]; set => ((IDictionary)Themes!) [key] = value; }
public void Add (string key, ThemeScope value)
{
((IDictionary)Themes!).Add (key, value);
}
public bool ContainsKey (string key)
{
return ((IDictionary)Themes!).ContainsKey (key);
}
public bool Remove (string key)
{
return ((IDictionary)Themes!).Remove (key);
}
public bool TryGetValue (string key, out ThemeScope value)
{
return ((IDictionary)Themes!).TryGetValue (key, out value!);
}
public void Add (KeyValuePair item)
{
((ICollection>)Themes!).Add (item);
}
public void Clear ()
{
((ICollection>)Themes!).Clear ();
}
public bool Contains (KeyValuePair item)
{
return ((ICollection>)Themes!).Contains (item);
}
public void CopyTo (KeyValuePair [] array, int arrayIndex)
{
((ICollection>)Themes!).CopyTo (array, arrayIndex);
}
public bool Remove (KeyValuePair item)
{
return ((ICollection>)Themes!).Remove (item);
}
public IEnumerator> GetEnumerator ()
{
return ((IEnumerable>)Themes!).GetEnumerator ();
}
IEnumerator IEnumerable.GetEnumerator ()
{
return ((IEnumerable)Themes!).GetEnumerator ();
}
#pragma warning restore 1591
#endregion
}