using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using ImGuiNET; using skyscraper5.Skyscraper; using skyscraper5.Skyscraper.Scraper.Storage; using skyscraper8.Skyscraper.Scraper.Storage; namespace SDL2Demo.Forms { internal class ConfigureDataStorageWindow : IRenderable { public Ini Ini { get; } public ReadOnlyCollection> StorageFactories { get; } private Dictionary FactoryNames; private Dictionary TempGuids; private StorageConnectionManager connectionManager; public ConfigureDataStorageWindow(Ini ini, ReadOnlyCollection> storageFactories) { Ini = ini; StorageFactories = storageFactories; IsOpen = true; storageId = ini.ReadValue("startup", "dataStorage", 0); settings = new List(); FactoryNames = new Dictionary(); connectionManager = StorageConnectionManager.GetInstance(); TempGuids = new Dictionary(); foreach (KeyValuePair keyValuePair in storageFactories) { FactoryNames.Add(keyValuePair.Key, connectionManager.GetName(keyValuePair.Value)); TempGuids.Add(keyValuePair.Key, Guid.NewGuid()); PropertyInfo[] propertyInfos = keyValuePair.Value.GetType().GetProperties(); foreach (PropertyInfo propertyInfo in propertyInfos) { Setting s = new Setting(); s.IniKey = keyValuePair.Key; s.SettingName = propertyInfo.Name; s.SettingControlUuid = Guid.NewGuid().ToString(); switch (propertyInfo.PropertyType.Name) { case nameof(String): s.SettingMode = 1; s.StringValue = ini.ReadValue(String.Format("dataStorage{0}", s.IniKey), s.SettingName, ""); break; case nameof(Boolean): s.SettingMode = 2; s.BooleanValue = ini.ReadValue(String.Format("dataStorage{0}", s.IniKey), s.SettingName, false); break; case nameof(UInt16): s.SettingMode = 3; s.UshortValue = (ushort)ini.ReadValue(String.Format("dataStorage{0}", s.IniKey), s.SettingName, ushort.MinValue); break; default: throw new NotImplementedException(propertyInfo.PropertyType.Name); } settings.Add(s); } } } public class Setting { public long IniKey; public string SettingName; public int SettingMode; public string StringValue; public bool BooleanValue; public int UshortValue; public string SettingControlUuid; public float FloatValue; public int IntegerValue; public bool Validate() { switch (SettingMode) { case 1: return !string.IsNullOrEmpty(StringValue) && !string.IsNullOrWhiteSpace(StringValue); case 2: return true; case 3: return UshortValue >= ushort.MinValue && UshortValue <= ushort.MaxValue; case 4: return float.IsFinite(FloatValue); default: throw new NotImplementedException(String.Format("Setting mode {0}", SettingMode)); } } } public bool IsOpen; private bool HasChanges; private int storageId; private List settings; public bool RequireRestart; private void Save() { Ini.WriteValue("startup", "dataStorage", storageId); foreach (Setting setting in settings) { switch (setting.SettingMode) { case 1: Ini.WriteValue(String.Format("dataStorage{0}", setting.IniKey), setting.SettingName, setting.StringValue); break; case 2: Ini.WriteValue(String.Format("dataStorage{0}", setting.IniKey), setting.SettingName, setting.BooleanValue); break; case 3: Ini.WriteValue(String.Format("dataStorage{0}", setting.IniKey), setting.SettingName, setting.UshortValue); break; default: throw new NotImplementedException(String.Format("Setting mode {0}", setting.SettingMode)); } } Ini.Export(new FileInfo("skyscraper5.ini")); if (HasChanges) RequireRestart = true; HasChanges = false; } private bool CanApply() { foreach (Setting setting in settings.Where(x => x.IniKey == storageId)) { if (!setting.Validate()) { return false; } } return true; } public void Render() { ImGuiWindowFlags flags = ImGuiWindowFlags.None; if (HasChanges) flags |= ImGuiWindowFlags.UnsavedDocument; ImGui.Begin("Configure ScraperStorage", ref IsOpen, flags); foreach (KeyValuePair keyValuePair in StorageFactories) { if (ImGui.RadioButton(FactoryNames[keyValuePair.Key], ref storageId, keyValuePair.Key)) { HasChanges = true; } ImGui.BeginTable(TempGuids[keyValuePair.Key].ToString(), 2); foreach (Setting setting in settings.Where(x => x.IniKey == keyValuePair.Key)) { ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); ImGui.Text(setting.SettingName); ImGui.TableSetColumnIndex(1); ImGui.PushID(setting.SettingControlUuid); switch (setting.SettingMode) { case 1: if (ImGui.InputText("", ref setting.StringValue, 255)) HasChanges = true; break; case 2: if (ImGui.Checkbox("", ref setting.BooleanValue)) HasChanges = true; break; case 3: if (setting.UshortValue < ushort.MinValue) setting.UshortValue = ushort.MinValue; if (setting.UshortValue > ushort.MaxValue) setting.UshortValue = ushort.MaxValue; if (ImGui.InputInt("", ref setting.UshortValue)) HasChanges = true; break; default: throw new NotImplementedException(String.Format("Setting mode {0}", setting.SettingMode)); } } ImGui.PopID(); ImGui.EndTable(); } bool canApply = CanApply(); ImGui.BeginDisabled(!canApply); if (ImGui.Button("OK")) { Save(); IsOpen = false; } ImGui.EndDisabled(); ImGui.SameLine(); if (ImGui.Button("Cancel")) { IsOpen = false; } ImGui.SameLine(); ImGui.BeginDisabled(!canApply); if (ImGui.Button("Apply")) { Save(); } ImGui.EndDisabled(); ImGui.End(); } } }