#define scrolling
//#define newgrid

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using InABox.Core;
using Syncfusion.Data;

namespace InABox.DynamicGrid
{

    public enum DynamicGridButtonPosition
    {
        Left,
        Right
    }
    
    
    public interface IDynamicGrid
    {
        Thickness Margin { get; set; }

        DynamicGridColumns MasterColumns { get; }
        DynamicGridColumns VisibleColumns { get; }

        CoreTable Data { get; set; }
        CoreRow[] SelectedRows { get; set; }

        double RowHeight { get; set; }
        double HeaderHeight { get; set; }

        double FontSize { get; set; }
        void Refresh(bool columns, bool data);

        void InitialiseEditorForm(IDynamicEditorForm editor, object[] items, Func<Type, CoreTable>? pageDataHandler = null, bool preloadPages = false);
        bool EditItems(object[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false);

        //bool DirectEdit(CoreTable data);

        event OnFilterRecord OnFilterRecord;
        event OnCreateItem OnCreateItem;

        event OnDoubleClick? OnDoubleClick;

        delegate void ReconfigureEvent(FluentList<DynamicGridOption> options);
        event ReconfigureEvent? OnReconfigure;

        public abstract void Reconfigure();

        /// <summary>
        /// Add <paramref name="onReconfigure"/> to <see cref="OnReconfigure"/>, and then call <see cref="Reconfigure"/>.
        /// </summary>
        /// <remarks>
        /// Probably should only be called once per grid, otherwise there will be multiple event handlers bound.<br/>
        /// If you want to reconfigure without specifiying
        /// a new reconfigure event, use <see cref="Reconfigure"/>.
        /// </remarks>
        /// <param name="onReconfigure"></param>
        public void Reconfigure(ReconfigureEvent onReconfigure);

        public bool HasOption(DynamicGridOption option);

        void AddVisualFilter(string column, string value, FilterType filtertype = FilterType.Contains);

        Button AddButton(string? caption, BitmapImage? image, string? tooltip, Func<Button, CoreRow[], bool> action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left);

        Button AddButton(string? caption, BitmapImage? image, Func<Button, CoreRow[], bool> action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left);

        void UpdateButton(Button button, BitmapImage? image, string? text, string? tooltip = null);

        event OnDefineFilter OnDefineFilter;

        event OnPrintData OnPrintData;
        
        event OnCustomiseColumns OnCustomiseColumns;

        event BeforeRefreshEventHandler BeforeRefresh;
        
        event AfterRefreshEventHandler AfterRefresh;
        
        event EntitySaveEvent? OnAfterSave;
        event EntitySaveEvent? OnBeforeSave;

        int DesiredWidth();

        void ConfigureColumns(DynamicGridColumns columns /*, bool dolookups */);

        void AddHiddenColumn(string column);

        void UpdateRow<TType>(CoreRow row, string column, TType value, bool refresh = true);

        void UpdateRow<T, TType>(CoreRow row, Expression<Func<T, TType>> column, TType value, bool refresh = true);
    }
}