using InABox.WPF;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace InABox.Wpf;

/// <remarks>
/// <b>Warning:</b> this doesn't work for nullable <typeparamref name="TIn"/>. Use the non-generic <see cref="FuncConverter"/> instead.
/// </remarks>
public class FuncConverter<TIn, TOut>(Func<TIn, TOut> convert, Func<TOut, TIn>? convertBack = null) : IValueConverter<TIn, TOut>
{
    public Func<TIn, TOut> ConvertFunc { get; set; } = convert;

    public Func<TOut, TIn>? ConvertBackFunc { get; set; } = convertBack;

    public object? Convert(object? value, Type targetType, object parameter, CultureInfo culture)
    {
        if(value is TIn tIn)
        {
            return ConvertFunc(tIn);
        }
        return null;
    }

    public object? ConvertBack(object? value, Type targetType, object parameter, CultureInfo culture)
    {
        if(value is TOut tOut && ConvertBackFunc is not null)
        {
            return ConvertBackFunc.Invoke(tOut);
        }
        return null;
    }
}

public class FuncConverter(Func<object?, object?> convert, Func<object?, object?>? convertBack = null) : IValueConverter
{
    public Func<object?, object?> ConvertFunc { get; set; } = convert;

    public Func<object?, object?>? ConvertBackFunc { get; set; } = convertBack;

    public object? Convert(object? value, Type targetType, object parameter, CultureInfo culture)
    {
        return ConvertFunc(value);
    }

    public object? ConvertBack(object? value, Type targetType, object parameter, CultureInfo culture)
    {
        if(ConvertBackFunc is not null)
        {
            return ConvertBackFunc.Invoke(value);
        }
        return null;
    }
}
