using System;
using System.Windows.Input;

namespace MVVMProject.Core
{
    public class DelegateCommand : ICommand
    {
        private bool _canExecute;
        private readonly Action _commandAction;
        private readonly Action<object> _commandActionWithParameter;
        public event EventHandler CanExecuteChanged;

        protected DelegateCommand()
        {
            _canExecute = true;
        }

        public DelegateCommand(Action<object> commandAction)
            : this(commandAction, true)
        {
        }

        public DelegateCommand(Action commandAction)
            : this(commandAction, true)
        {
        }

        public DelegateCommand(Action<object> commandAction, bool canExecute)
        {
            if (commandAction == null)
            {
                throw new ArgumentNullException("commandAction");
            }
            _commandActionWithParameter = commandAction;
            _canExecute = canExecute;
        }

        public DelegateCommand(Action commandAction, bool canExecute)
        {
            if (commandAction == null)
            {
                throw new ArgumentNullException("commandAction");
            }
            _commandAction = commandAction;
            _canExecute = canExecute;
        }

        protected virtual void Execute(object parameter)
        {
            if (_commandAction != null)
            {
                _commandAction();
            }
            else if (_commandActionWithParameter != null)
            {
                _commandActionWithParameter(parameter);
            }
        }

        bool ICommand.CanExecute(object parameter)
        {
            return _canExecute;
        }

        void ICommand.Execute(object parameter)
        {
            Execute(parameter);
        }

        public void UpdateStatus(bool canExecute)
        {
            if (_canExecute != canExecute)
            {
                _canExecute = canExecute;
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, EventArgs.Empty);
                }
            }
        }
    }
}