using InABox.Core.Notifications; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace InABox.Core { public interface IEntityFormUtils { public abstract bool CanEditForm(IDigitalFormInstance form, Entity entity); public abstract Entity NewEntity(DigitalForm form); public abstract void OnSave(IDigitalFormInstance form, Entity entity); } public abstract class EntityFormUtils : IEntityFormUtils where TForm : EntityForm where TEntity : Entity, new() where TEntityLink : EntityLink, new() { public abstract bool CanEditForm(TForm form, TEntity entity); public abstract TEntity NewEntity(DigitalForm form); public abstract void OnSave(TForm form, TEntity entity); void IEntityFormUtils.OnSave(IDigitalFormInstance form, Entity entity) => OnSave((TForm)form, (TEntity)entity); bool IEntityFormUtils.CanEditForm(IDigitalFormInstance form, Entity entity) => CanEditForm((form as TForm)!, (entity as TEntity)!); Entity IEntityFormUtils.NewEntity(DigitalForm form) => NewEntity(form); } public class DelegateEntityFormUtils : EntityFormUtils where TForm : EntityForm where TEntity : Entity, new() where TEntityLink : EntityLink, new() { public delegate bool CanEditEvent(TForm form, TEntity entity); public delegate TEntity NewEntityEvent(DigitalForm form); public delegate void OnSaveEvent(TForm form, TEntity entity); public CanEditEvent OnCanEdit; public NewEntityEvent? OnNewEntity; public OnSaveEvent? SaveEvent; public DelegateEntityFormUtils(CanEditEvent canEditForm, NewEntityEvent? onNewEntity = null, OnSaveEvent? onSave = null) { OnCanEdit = canEditForm; OnNewEntity = onNewEntity; SaveEvent = onSave; } public override bool CanEditForm(TForm form, TEntity entity) => OnCanEdit(form, entity); public override TEntity NewEntity(DigitalForm form) => OnNewEntity?.Invoke(form) ?? new TEntity(); public override void OnSave(TForm form, TEntity entity) => SaveEvent?.Invoke(form, entity); } public static class DFUtils { private static List? _fieldTypes; public static List GetFieldTypes() { _fieldTypes ??= CoreUtils.TypeList( AppDomain.CurrentDomain.GetAssemblies(), x => x.IsClass && !x.IsAbstract && !x.IsGenericType && x.GetInterfaces().Any(x => x == typeof(IDFLayoutFormField))).ToList(); return _fieldTypes; } public static Type? GetFieldType(string typeName) { var type = GetFieldTypes().Where(x => x.FullName == typeName).FirstOrDefault(); if(type != null) return type; if(Enum.TryParse(typeName, out DigitalFormVariableType variableType)) { // For the old types switch (variableType) { case DigitalFormVariableType.String: return typeof(DFLayoutStringField); case DigitalFormVariableType.Boolean: return typeof(DFLayoutBooleanField); case DigitalFormVariableType.Integer: return typeof(DFLayoutIntegerField); case DigitalFormVariableType.Double: return typeof(DFLayoutDoubleField); case DigitalFormVariableType.Date: return typeof(DFLayoutDateField); case DigitalFormVariableType.Time: return typeof(DFLayoutTimeField); case DigitalFormVariableType.Choice: return typeof(DFLayoutOptionField); case DigitalFormVariableType.Lookup: return typeof(DFLayoutLookupField); case DigitalFormVariableType.SignaturePad: return typeof(DFLayoutSignaturePad); case DigitalFormVariableType.EmbeddedImage: return typeof(DFLayoutEmbeddedImage); case DigitalFormVariableType.MultiImage: return typeof(DFLayoutMultiImage); } } return null; } private static Dictionary _formUtils = new Dictionary(); public static void AddFormUtils( DelegateEntityFormUtils.CanEditEvent editFormFunc, DelegateEntityFormUtils.NewEntityEvent? newEntityFunc = null, DelegateEntityFormUtils.OnSaveEvent? beforeSaveFunc = null) where TForm : EntityForm where TEntity : Entity, new() where TEntityLink : EntityLink, new() { _formUtils.Add(typeof(TForm), new DelegateEntityFormUtils(editFormFunc, newEntityFunc, beforeSaveFunc)); } public static void AddFormUtils(EntityFormUtils formUtils) where TForm : EntityForm where TEntity : Entity, new() where TEntityLink : EntityLink, new() { _formUtils.Add(typeof(TForm), formUtils); } public static bool CanEditForm(Type TForm, IDigitalFormInstance Form, Entity Entity) { if(_formUtils.TryGetValue(TForm, out var utils)) { return utils.CanEditForm(Form, Entity); } return false; } public static bool CanEditForm(TForm Form, TEntity Entity) where TForm : EntityForm where TEntity : Entity, new() where TEntityLink : EntityLink, new() { return CanEditForm(typeof(TForm), Form, Entity); } public static Entity NewEntity(Type TForm, Type TEntity, DigitalForm form) { if (_formUtils.TryGetValue(TForm, out var utils)) { return utils.NewEntity(form); } return (Activator.CreateInstance(TEntity) as Entity)!; } public static TEntity NewEntity(DigitalForm form) where TForm : EntityForm where TEntity : Entity, new() where TEntityLink : EntityLink, new() { return (TEntity)NewEntity(typeof(TForm), typeof(TEntity), form); } public static void OnSave(Type TForm, IDigitalFormInstance form, Entity entity) { if (_formUtils.TryGetValue(TForm, out var utils)) { utils.OnSave(form, entity); } } public static void OnSave(TForm form, TEntity entity) where TForm : EntityForm where TEntity : Entity, new() where TEntityLink : EntityLink, new() { OnSave(typeof(TForm), form, entity); } } }