using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Barotrauma;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using System.Xml;
using System.Xml.Linq;
namespace QICrabUI
{
///
/// In Fact just an observable dict
///
public partial class CUIStyle : IEnumerable>, ICloneable
{
public static CUIStyle DefaultFor(Type T) => CUITypeMetaData.Get(T).DefaultStyle;
public static CUIStyle DefaultFor() where T : CUIComponent => CUITypeMetaData.Get(typeof(T)).DefaultStyle;
IEnumerator> IEnumerable>.GetEnumerator()
=> Props.GetEnumerator();
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
=> Props.GetEnumerator();
public void Add(string key, string value)
{
Props[key] = value;
OnPropChanged?.Invoke(key, value);
}
public void Clear() => Props.Clear();
///
/// Prop name -> value
///
public Dictionary Props = new();
public event Action OnPropChanged;
public event Action OnUse;
public virtual string this[string name]
{
get => Props.ContainsKey(name) ? Props[name] : "";
set => Add(name, value);
}
public object Clone()
{
CUIStyle style = new CUIStyle();
style.Props = new Dictionary(Props);
return style;
}
public static CUIStyle Merge(CUIStyle baseStyle, CUIStyle addedStyle)
{
CUIStyle result = new CUIStyle();
if (baseStyle != null)
{
foreach (string key in baseStyle.Props.Keys)
{
result[key] = baseStyle.Props[key];
}
}
if (addedStyle != null)
{
foreach (string key in addedStyle.Props.Keys)
{
result[key] = addedStyle.Props[key];
}
}
return result;
}
public void Use(CUIStyle source)
{
Props = new Dictionary(source.Props);
OnUse?.Invoke(this);
}
public void UseString(string raw)
{
Clear();
try
{
string content = raw.Split('{', '}')[1];
if (content.Trim() == "") return;
var pairs = content.Split(',').Select(s => s.Split(':').Select(sub => sub.Trim()).ToArray());
foreach (var pair in pairs)
{
Props[pair[0]] = pair[1];
}
}
catch (Exception e) { CUI.Warning($"Style.UseString failed: {e.Message}"); }
OnUse?.Invoke(this);
}
public void UseXML(XElement element)
{
Clear();
foreach (XElement prop in element.Elements())
{
Props[prop.Name.ToString()] = prop.Value;
}
OnUse?.Invoke(this);
}
public static CUIStyle FromXML(XElement element)
{
CUIStyle style = new CUIStyle();
style.UseXML(element);
return style;
}
public override string ToString()
{
return "{ " + String.Join(", ", Props.Select(kvp => $"{kvp.Key} : {kvp.Value}")) + " }";
}
public static CUIStyle Parse(string raw)
{
CUIStyle style = new CUIStyle();
style.UseString(raw);
return style;
}
public override bool Equals(object obj)
{
if (!(obj is CUIStyle styleB)) return false;
CUIStyle styleA = this;
if (styleA is null && styleB is null) return true;
if (styleA is null || styleB is null) return false;
if (styleA.Props is null || styleB.Props is null) return false;
if (styleA.Props.Count != styleB.Props.Count) return false;
foreach (var (key, value) in styleA.Props)
{
if (!styleB.Props.ContainsKey(key)) return false;
if (styleA[key] != styleB[key]) return false;
}
return true;
}
public static CUIStyle operator +(CUIStyle styleA, CUIStyle styleB) => Merge(styleA, styleB);
public static bool operator ==(CUIStyle styleA, CUIStyle styleB)
{
if (styleA is null && styleB is null) return true;
if (styleA is null || styleB is null) return false;
if (styleA.Props is null || styleB.Props is null) return false;
if (styleA.Props.Count != styleB.Props.Count) return false;
foreach (var (key, value) in styleA.Props)
{
if (!styleB.Props.ContainsKey(key)) return false;
if (styleA[key] != styleB[key]) return false;
}
return true;
}
public static bool operator !=(CUIStyle styleA, CUIStyle styleB)
{
if (styleA is null && styleB is null) return false;
if (styleA is null || styleB is null) return true;
if (styleA.Props is null || styleB.Props is null) return true;
if (styleA.Props.Count != styleB.Props.Count) return true;
foreach (var (key, value) in styleA.Props)
{
if (!styleB.Props.ContainsKey(key)) return true;
if (styleA[key] != styleB[key]) return true;
}
return false;
}
}
}