using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq.Expressions;

namespace InABox.Core
{
    public interface ICoreTable
    {
        List<CoreColumn> Columns { get; }
        List<CoreRow> Rows { get; }
        Dictionary<string, IList<Action<object, object>?>> Setters { get; }
        string TableName { get; }

        void CopyTo(CoreTable table);
        void CopyTo(DataTable table);
        TValue[] ExtractValues<TSource, TValue>(Expression<Func<TSource, TValue>> column, bool distinct = true);
        TValue[] ExtractValues<TValue>(string column, bool distinct = true);
        void Filter(Func<CoreRow, bool> predicate);
        void LoadColumns(Type T);
        void LoadDictionary<T, TKey, TValue>(Dictionary<TKey, TValue> dictionary, Expression<Func<T, TKey>> key, Expression<Func<T, TValue>> value);
        void FillRow(CoreRow row, CoreRow from);
        void FillRow(CoreRow row, object obj);
        void LoadRows(IEnumerable<CoreRow> rows);
        void LoadRows(IEnumerable<object> objects);
        CoreRow NewRow(bool populate = false);
        DataTable ToDataTable(string name = "", IColumns? additionalColumns = null);
        IDictionary ToDictionary(string keycol, string displaycol, string sortcol = "");

        IEnumerable<T> ToObjects<T>() where T : BaseObject, new();
        
        Dictionary<TKey, TValue> ToDictionary<T, TKey, TValue>(Expression<Func<T, TKey>> key, Expression<Func<T, TValue>> value,
            Expression<Func<T, object>>? sort = null);

        Dictionary<TKey, string> ToDictionary<T, TKey>(Expression<Func<T, TKey>> key, Expression<Func<T, object>>[] values,
            Expression<Func<T, object>>? sort = null);
    }
}