using AutoProperties;
using Comal.Classes;
using InABox.Core;
using InABox.DynamicGrid;
using InABox.WPF;
using PRS.Shared.Events;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace PRS.Shared;
///
/// Interaction logic for EventEditorWIndow.xaml
///
public partial class EventEditor : UserControl, INotifyPropertyChanged
{
private EventType? _eventType;
public EventType? EventType
{
get => _eventType;
set
{
_eventType = value;
OnPropertyChanged();
HasType = value.HasValue && EventTypeHasEntityType(value.Value);
DoChanged();
UpdateEventData();
}
}
private Type? _entityType;
public Type? EntityType
{
get => _entityType;
set
{
_entityType = value;
OnPropertyChanged();
UpdateEventData();
}
}
private bool _hasProperties;
public bool HasProperties
{
get => _hasProperties;
set
{
_hasProperties = value;
OnPropertyChanged();
}
}
private bool _hasType;
public bool HasType
{
get => _hasType;
set
{
_hasType = value;
OnPropertyChanged();
}
}
private Type? EventDataType;
private Type? DataModelType;
private IEventEditorControl? _eventEditorControl;
private bool _changed;
public bool Changed
{
get => _changed;
set
{
_changed = value;
OnPropertyChanged();
}
}
public IEventData? Data
{
get => _eventEditorControl?.Data;
set
{
OnPropertyChanged();
if(value is not null && EventType.HasValue)
{
if(EventDataType is null || DataModelType is null)
{
var inter = value.GetType().GetSuperclassDefinition(typeof(EventData<,>))!;
EventDataType = inter.GenericTypeArguments[0];
DataModelType = inter.GenericTypeArguments[1];
if (EventTypeHasEntityType(EventType.Value))
{
EntityType = EventDataType.GenericTypeArguments[0];
}
}
var control = Activator.CreateInstance(typeof(EventEditorControl<,>).MakeGenericType(EventDataType, DataModelType), value);
_eventEditorControl = (control as IEventEditorControl)!;
_eventEditorControl.OnChanged += DoChanged;
Content.Content = control;
Content.Visibility = Visibility.Visible;
Placeholder.Visibility = Visibility.Collapsed;
}
else
{
_eventEditorControl = null;
Content.Content = null;
Content.Visibility = Visibility.Collapsed;
Placeholder.Visibility = Visibility.Visible;
}
DoChanged();
}
}
public EventEditor()
{
InitializeComponent();
EventTypeBox.ItemsSource = Enum.GetValues();
var entities = CoreUtils.Entities.Where(x => !x.IsGenericType && x.IsSubclassOf(typeof(Entity))).ToArray();
entities.SortBy(x => x.Name);
EntityTypeBox.ItemsSource = entities;
}
private void DoChanged()
{
Changed = true;
}
private bool EventTypeHasEntityType(EventType eventType)
{
switch (eventType)
{
case Comal.Classes.EventType.AfterSave:
return true;
default:
return false;
}
}
private void UpdateEventData()
{
if (EventType is null || (EventTypeHasEntityType(EventType.Value) && EntityType is null))
{
Data = null;
HasProperties = false;
return;
}
Type eventType;
Type dataModelType;
switch (EventType.Value)
{
case Comal.Classes.EventType.AfterSave:
eventType = typeof(SaveEvent<>).MakeGenericType(EntityType!);
dataModelType = typeof(SaveEventDataModel<>).MakeGenericType(EntityType!);
break;
case Comal.Classes.EventType.Scheduled:
eventType = typeof(ScheduledEvent);
dataModelType = typeof(ScheduledEventDataModel);
break;
default:
Data = null;
HasProperties = false;
return;
}
HasProperties = eventType.HasInterface(typeof(IPropertiesEvent<>));
var ev = Activator.CreateInstance(eventType);
EventDataType = eventType;
DataModelType = dataModelType;
Data = (Activator.CreateInstance(typeof(EventData<,>).MakeGenericType(eventType, dataModelType), ev) as IEventData)!;
}
private void EditButton_Click(object sender, RoutedEventArgs e)
{
if (EventDataType is null || EventDataType.GetInterfaceDefinition(typeof(IPropertiesEvent<>)) is not Type propertiesInterface) return;
var method = GetType().GetMethod(nameof(EditProperties), BindingFlags.Instance | BindingFlags.NonPublic)!
.MakeGenericMethod(propertiesInterface.GenericTypeArguments[0]);
method.Invoke(this, []);
}
private void EditProperties() where TProperties : BaseObject, new()
{
if (Data?.Event is not IPropertiesEvent propertiesEvent) return;
var props = propertiesEvent.GetProperties();
if (DynamicGridUtils.EditEntity(props))
{
propertiesEvent.SetProperties(props);
DoChanged();
}
}
public static bool Run(ref EventType evType, ref IEventData? eventData)
{
var editor = new EventEditor();
editor.EventType = evType;
if(eventData is not null)
{
editor.Data = eventData;
}
editor.Changed = false;
var dialog = new DynamicContentDialog(editor)
{
SizeToContent = SizeToContent.Height,
Title = "Edit Event"
};
dialog.Bind(DynamicContentDialog.CanSaveProperty, editor, x => x.Changed);
if(dialog.ShowDialog() == true)
{
eventData = editor.Data;
evType = editor.EventType ?? default;
return true;
}
else
{
return false;
}
}
}