using System;
using System.Windows;
using System.Windows.Input;
using System.Collections;
using System.ComponentModel;
using InvExplorer.ServiceReference1;

namespace InvExplorer
{
    /// <summary>
    /// Represents a command that removes selected assets from the current portfolio.
    /// The assets are specified as a collection of <see cref="PortfolioItem"/> objects 
    /// in the command parameter.
    /// </summary>
    public class RemoveAssetCommand : ICommand
    {
        ViewModel _model;
        Portfolio _pf;

        /// <summary>
        /// Initializes a new instance of an <see cref="AddAssetCommand"/>.
        /// </summary>
        /// <param name="model"><see cref="ViewModel"/> that owns this command.</param>
        public RemoveAssetCommand(ViewModel model)
        {
            _model = model;
            _model.PortfoliosView.CurrentChanged += PortfoliosView_CurrentChanged;
        }
        /// <summary>
        /// Checks whether the command can be executed in the current model state,
        /// with the given parameter.
        /// </summary>
        /// <param name="parameter">Collection of <see cref="PortfolioItem"/> objects to 
        /// remove from the current portfolio.</param>
        /// <returns>True if the command can be executed with the given parameter.</returns>
        public bool CanExecute(object parameter)
        {
            // need a current portfolio
            if (_pf == null)
            {
                return false;
            }

            // count items we can remove
            var cnt = 0;
            var items = parameter as IEnumerable;
            if (items != null)
            {
                foreach (PortfolioItem item in items)
                {
                    if (_pf.Items.Contains(item))
                    {
                        cnt++;
                    }
                }
            }

            // can execute if the count is > 0
            return cnt > 0;
        }
        /// <summary>
        /// Add a new item with the given symbol to the current portfolio.
        /// </summary>
        /// <param name="parameter"><see cref="SymbolName"/> that defines the asset to add.</param>
        public void Execute(object parameter)
        {
            var items = parameter as IEnumerable;
            if (_pf != null && items != null)
            {
                // get current portfolio, position
                var pos = _pf.ItemsView.CurrentPosition;

                // remove selected items
                foreach (PortfolioItem item in items)
                {
                    _pf.Items.Remove(item);
                }

                // restore selection
                _pf.ItemsView.MoveCurrentToPosition(Math.Min(pos, _pf.Items.Count - 1));

                // command can no longer execute...
                OnCanExecuteChanged(EventArgs.Empty);
            }
        }
        /// <summary>
        /// Event that fires when the command enabled state should change.
        /// </summary>
        public event EventHandler CanExecuteChanged;
        /// <summary>
        /// Raises the <see cref="CanExecuteChanged"/> event.
        /// </summary>
        /// <param name="e"><see cref="EventArgs"/> that contains the event data.</param>
        protected virtual void OnCanExecuteChanged(EventArgs e)
        {
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, e);
        }

        // ** event handlers
        void PortfoliosView_CurrentChanged(object sender, EventArgs e)
        {
            if (_pf != null)
            {
                _pf.ItemsView.CurrentChanged -= _pfv_CurrentChanged;
            }
            _pf = _model.PortfoliosView.CurrentItem as Portfolio;
            if (_pf != null)
            {
                _pf.ItemsView.CurrentChanged += _pfv_CurrentChanged;
            }
        }
        void _pfv_CurrentChanged(object sender, EventArgs e)
        {
            OnCanExecuteChanged(EventArgs.Empty);
        }

    }
}
