using System;

namespace KitsuneCafe.UI.MVVM
{
  public interface ICommand
  {
    bool CanExecute();
    void Execute();

    bool TryExecute()
    {
      if (CanExecute())
      {
        Execute();
        return true;
      }
      return false;
    }
  }

  public interface ICommand<T>
  {
    bool CanExecute(T value);
    void Execute(T value);

    bool TryExecute(T value)
    {
      if (CanExecute(value))
      {
        Execute(value);
        return true;
      }

      return false;
    }
  }

  public class RelayCommand : ICommand
  {
    public Func<bool> canExecute;
    public Action execute;

    public RelayCommand(Func<bool> canExecute, Action execute)
    {
      this.canExecute = canExecute;
      this.execute = execute;
    }

    public bool CanExecute()
    {
      return canExecute();
    }

    public void Execute()
    {
      execute();
    }
  }

  public class RelayCommand<T> : ICommand<T>
  {
    public Predicate<T> canExecute;
    public Action<T> execute;

    public RelayCommand(Predicate<T> canExecute, Action<T> execute)
    {
      this.canExecute = canExecute;
      this.execute = execute;
    }

    public bool CanExecute(T value)
    {
      return canExecute(value);
    }

    public void Execute(T value)
    {
      execute(value);
    }
  }
}
