using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using InABox.Clients;
using InABox.Configuration;
using InABox.Core;
using InABox.WPF;
using Expression = System.Linq.Expressions.Expression;
namespace InABox.DynamicGrid;
public interface IDynamicDataGrid : IDynamicGrid
{
///
/// The tag the the DynamicGridColumns are stored against. If set to ,
/// the name of is used as a default.
///
string? ColumnsTag { get; set; }
}
public class DynamicDataGrid : DynamicGrid, IDynamicDataGrid where TEntity : Entity, IRemotable, IPersistent, new()
{
private Button MergeBtn = null!; //Late-initialised
protected DynamicGridCustomColumnsComponent ColumnsComponent;
public DynamicGridFilterButtonComponent FilterComponent;
public DynamicDataGrid() : base()
{
var fields = DatabaseSchema.Properties(typeof(TEntity));
foreach (var field in fields)
if (!MasterColumns.Any(x => x.ColumnName == field.Name))
MasterColumns.Add(new DynamicGridColumn { ColumnName = field.Name });
var cols = LookupFactory.DefineColumns();
// Minimum Columns for Lookup values
foreach (var col in cols)
HiddenColumns.Add(CoreUtils.CreateLambdaExpression(col.Property));
// Minimum Columns for Successful Saving
// This should be cross-checked with the relevant Store<>
// so that clients will (usually) provide sufficient columns for saving
foreach (var col in LookupFactory.RequiredColumns())
HiddenColumns.Add(CoreUtils.CreateLambdaExpression(col.Property));
//HiddenColumns.Add(x => x.ID);
if (typeof(TEntity).GetInterfaces().Contains(typeof(IIssues)))
{
HiddenColumns.Add(x => (x as IIssues)!.Issues);
var coltype = typeof(DynamicIssuesColumn<>).MakeGenericType(typeof(TEntity));
ActionColumns.Add((Activator.CreateInstance(coltype, this) as DynamicActionColumn)!);
}
}
protected override void Init()
{
FilterComponent = new(this,
new GlobalConfiguration(GetTag()),
new UserConfiguration(GetTag()));
FilterComponent.OnFilterRefresh += () => Refresh(false, true);
ColumnsComponent = new DynamicGridCustomColumnsComponent(this, GetTag());
var dataComponent = new DynamicGridClientDataComponent(this);
dataComponent.OnReload += DataComponent_OnReload;
DataComponent = dataComponent;
MergeBtn = AddButton("Merge", Wpf.Resources.merge.AsBitmapImage(Color.White), DoMerge);
}
public override void SelectItems(CoreRow[]? rows)
{
base.SelectItems(rows);
MergeBtn.Visibility = Options.MultiSelect && typeof(TEntity).IsAssignableTo(typeof(IMergeable)) && Security.CanMerge()
&& rows != null && rows.Length > 1
? Visibility.Visible
: Visibility.Collapsed;
}
private void DataComponent_OnReload(object sender, Filters criteria, Columns columns, ref SortOrder? sortby)
{
criteria.Add(FilterComponent.GetFilter());
}
protected override void OptionsChanged()
{
base.OptionsChanged();
FilterComponent.ShowFilterList = Options.FilterRows && !Options.HideDatabaseFilters;
if (MergeBtn != null)
MergeBtn.Visibility = Visibility.Collapsed;
}
protected override void DoReconfigure(DynamicGridOptions options)
{
if (Security.CanEdit())
{
options.AddRows = true;
options.EditRows = true;
}
if (Security.CanDelete())
options.DeleteRows = true;
if (Security.CanImport() && typeof(TEntity).HasInterface())
options.ImportData = true;
if (Security.CanExport() && typeof(TEntity).HasInterface())
options.ExportData = true;
if (Security.CanMerge())
options.MultiSelect = true;
}
protected override void BeforeLoad(IDynamicEditorForm form, TEntity[] items)
{
form.ReadOnly = form.ReadOnly || !Security.CanEdit();
base.BeforeLoad(form, items);
}
private string? _columnsTag;
public string? ColumnsTag
{
get => _columnsTag;
set
{
_columnsTag = value;
ColumnsComponent.Tag = GetTag();
}
}
protected override DynamicGridColumns LoadColumns()
{
return ColumnsComponent.LoadColumns();
}
protected override void SaveColumns(DynamicGridColumns columns)
{
ColumnsComponent.SaveColumns(columns);
}
protected override void LoadColumnsMenu(ContextMenu menu)
{
base.LoadColumnsMenu(menu);
ColumnsComponent.LoadColumnsMenu(menu);
}
private string GetTag()
{
var tag = typeof(TEntity).Name;
if (!string.IsNullOrWhiteSpace(ColumnsTag))
tag = string.Format("{0}.{1}", tag, ColumnsTag);
return tag;
}
protected override DynamicGridSettings LoadSettings()
{
var tag = GetTag();
var user = Task.Run(() => new UserConfiguration(tag).Load());
user.Wait();
//var global = Task.Run(() => new GlobalConfiguration(tag).Load());
//global.Wait();
//Task.WaitAll(user, global);
//var columns = user.Result.Any() ? user.Result : global.Result;
return user.Result;
}
protected override void SaveSettings(DynamicGridSettings settings)
{
var tag = GetTag();
new UserConfiguration(tag).Save(settings);
}
#region Duplicate
protected override IEnumerable LoadDuplicatorItems(CoreRow[] rows)
{
return rows.Select(x => x.ToObject());
}
#endregion
#region Merge
private bool DoMerge(Button arg1, CoreRow[] arg2)
{
if (arg2 == null || arg2.Length <= 1)
return false;
var target = arg2.Last().ToObject();
return DynamicGridUtils.MergeEntities(
target,
arg2.ToObjects().Where(x => x.ID != target.ID).ToArray());
}
#endregion
}