using ServerManagerTool.Common.Interfaces; using System; using System.Collections.Generic; using System.Linq; namespace ServerManagerTool.Common.Model { public abstract class IniValueList : SortableObservableCollection, IIniValuesCollection { private bool _isEnabled; protected IniValueList(string aggregateValueName, Func> resetFunc, Func equivalencyFunc, Func sortKeySelectorFunc, Func toIniValue, Func fromIniValue) { this.ToIniValue = toIniValue; this.FromIniValue = fromIniValue; this.ResetFunc = resetFunc; this.EquivalencyFunc = equivalencyFunc; this.SortKeySelectorFunc = sortKeySelectorFunc; this.IniCollectionKey = aggregateValueName; this.Reset(); this.IsEnabled = false; } public Func ToIniValue { get; } public Func FromIniValue { get; } protected Func> ResetFunc { get; } public Func EquivalencyFunc { get; private set; } protected Func SortKeySelectorFunc { get; } public bool IsEnabled { get { return this._isEnabled; } set { this._isEnabled = value; OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs(nameof(IsEnabled))); } } public abstract bool IsArray { get; } public string IniCollectionKey { get; } public void AddRange(IEnumerable values) { foreach (var value in values) { base.Add(value); } } public virtual void FromIniValues(IEnumerable values) { this.Clear(); if (this.IsArray) { var list = new List(); if (this.ResetFunc != null) list.AddRange(this.ResetFunc()); foreach(var v in values) { var indexStart = v.IndexOf('['); var indexEnd = v.IndexOf(']'); if(indexStart >= indexEnd) { // Invalid format continue; } int index; if(!int.TryParse(v.Substring(indexStart + 1, indexEnd - indexStart - 1), out index)) { // Invalid index continue; } if(index >= list.Count) { // Unexpected size continue; } list[index] = this.FromIniValue(v.Substring(v.IndexOf('=') + 1).Trim()); this.IsEnabled = true; } this.AddRange(list); } else { this.AddRange(values.Select(v => v.Substring(v.IndexOf('=') + 1)).Select(this.FromIniValue)); this.IsEnabled = (this.Count != 0); // Add any default values which were missing if (this.ResetFunc != null) { this.AddRange(this.ResetFunc().Where(r => !this.Any(v => this.EquivalencyFunc(v, r)))); this.Sort(this.SortKeySelectorFunc); } } } public virtual IEnumerable ToIniValues() { var values = new List(); if (this.IsArray) { for(var i = 0; i < this.Count; i++) { if (string.IsNullOrWhiteSpace(IniCollectionKey)) values.Add(this.ToIniValue(this[i])); else values.Add($"{this.IniCollectionKey}[{i}]={this.ToIniValue(this[i])}"); } } else { if (string.IsNullOrWhiteSpace(IniCollectionKey)) values.AddRange(this.Select(d => this.ToIniValue(d))); else values.AddRange(this.Select(d => $"{this.IniCollectionKey}={this.ToIniValue(d)}")); } return values; } public void Reset() { this.Clear(); if (this.ResetFunc != null) this.AddRange(this.ResetFunc()); } } }