using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Threading.Tasks;
using MarketData;
using MarketData.Utils;
using MarketData.MarketDataModel;
using MarketData.Generator;
using MarketData.DataAccess;
using TradeBlotter.DataAccess;
using TradeBlotter.Command;
using TradeBlotter.Model;
using Microsoft.Research.DynamicDataDisplay.DataSources;
using System.Threading;
using System.Windows;

namespace TradeBlotter.ViewModels
{
  public class WatchListViewModel : WorkspaceViewModel
  {
    private const String DISPLAY_NAME = "WatchList";
    private List<String> watchLists;
    private String selectedWatchList;
    private ObservableCollection<CompanyProfile> companyProfileCollection = null;
    private bool busyIndicator = false;
    private RelayCommand refreshCommand;
    private RelayCommand stochasticsCommand;
    private RelayCommand relativeStrengthCommand;
    private RelayCommand macdCommand;
    private RelayCommand bollingerBandCommand;
    private RelayCommand priceHistoryCommand;
    private RelayCommand stickerValuationCommand;
    private RelayCommand dcfValuationCommand;
    private RelayCommand dividendHistoryCommand;
    private RelayCommand analystRatingsCommand;
    private RelayCommand displayHeadlinesCommand;
    private RelayCommand displaySECFilingsCommand;
    private RelayCommand movingAverageCommand;
    private RelayCommand displayHistoricalCommand;
    private RelayCommand removeFromWatchListCommand;
    private CompanyProfile selectedItem;

    public WatchListViewModel(bool loadedFromParams=false)
    {                                                                    
      base.DisplayName = DISPLAY_NAME;
      watchLists = WatchListDA.GetWatchLists();
      selectedWatchList = watchLists.Find(x => x.Equals("Valuations"));
      selectedItem=null;
      PropertyChanged += OnViewModelPropertyChanged;
      base.OnPropertyChanged("SelectedWatchList");
    }
// ******************************************************************************************** P E R S I S T E N C E ********************************************************************************************
    public override bool CanPersist()
    {
      return false;
    }
    public override SaveParameters GetSaveParameters()
    {
      return null;
    }
    public override void SetSaveParameters(SaveParameters saveParameters)
    {
    }
// ******************************************************************************************************************************************************
    public bool BusyIndicator
    {
      get { return busyIndicator; }
      set
      {
        busyIndicator = value;
        base.OnPropertyChanged("BusyIndicator");
      }
    }
    public ObservableCollection<MenuItem> MenuItems
    {
      get
      {
        ObservableCollection<MenuItem> collection = new ObservableCollection<MenuItem>();
        collection.Add(new MenuItem() { Text = "Display Bollinger Band", MenuItemClickedCommand = DisplayBollingerBand, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display Sticker Valuation", MenuItemClickedCommand = DisplayStickerValuation, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display Dividend History", MenuItemClickedCommand = DisplayDividendHistory, StaysOpenOnClick = false });
  			collection.Add(new MenuItem() { Text = "Display Historical", MenuItemClickedCommand = DisplayHistorical, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display Analyst Ratings", MenuItemClickedCommand = DisplayAnalystRatings, StaysOpenOnClick = false });
  			collection.Add(new MenuItem() { Text = "Display Headlines", MenuItemClickedCommand = DisplayHeadlines, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display Stochastics", MenuItemClickedCommand = DisplayStochastics, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display Relative Strength", MenuItemClickedCommand=DisplayRelativeStrength, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display MACD", MenuItemClickedCommand = DisplayMACD, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display Moving Average", MenuItemClickedCommand = DisplayMovingAverage, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display Price History", MenuItemClickedCommand = DisplayPriceHistory, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display DCF Valuation", MenuItemClickedCommand = DisplayDCFValuation, StaysOpenOnClick = false });
  			collection.Add(new MenuItem() { Text = "Display SEC Filings", MenuItemClickedCommand = DisplaySECFilings, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Remove from Watchlist", MenuItemClickedCommand = RemoveFromWatchList, StaysOpenOnClick = false });
        return collection;
      }
    }
    private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs)
    {
      if (eventArgs.PropertyName.Equals("SelectedWatchList"))
      {
        HandleSelectedWatchList();
      }
    }
    private void HandleSelectedWatchList()
    {
      try
      {
        BusyIndicator = true;
        Task workerTask = Task.Factory.StartNew(() =>
        {
          companyProfileCollection=new ObservableCollection<CompanyProfile>(CompositeDA.GetCompanyProfiles(selectedWatchList).ToList());
        });
        workerTask.ContinueWith((continuation) =>
        {
          BusyIndicator = false;
          base.OnPropertyChanged("AllItems");
          base.OnPropertyChanged("DisplayName");
          base.OnPropertyChanged("Title");
        });
      }
      finally
      {
      }
    }
    public ObservableCollection<CompanyProfile> AllItems
    {
      get { return companyProfileCollection; }
    }
    public override String DisplayName
    {
      get
      {
        if (null != selectedWatchList)return "WatchList (" + selectedWatchList + ") "+(null==AllItems?"":(AllItems.Count.ToString()+" Items"));
        else return "WatchLists";      
      }
    }
    public override String Title
    {
      get 
      {
        String title="";
        if (null != selectedWatchList)title = "WatchList (" + selectedWatchList + ") "+(null==AllItems?"":(AllItems.Count.ToString()+" Items"));
        else title= "WatchList";
        return title;
      }
    }
    private void Refresh()
    {
      companyProfileCollection=new ObservableCollection<CompanyProfile>(CompositeDA.GetCompanyProfiles(selectedWatchList).ToList());
      base.OnPropertyChanged("AllItems");
      base.OnPropertyChanged("DisplayName");
      base.OnPropertyChanged("Title");
    }
    private bool CanReset
    {
      get { return true; }
    }
    public ICommand RefreshCommand
    {
      get
      {
        if (refreshCommand == null)
        {
          refreshCommand = new RelayCommand(param => this.Refresh(), param => {return true;});
        }
        return refreshCommand;
      }
    }
    public List<String> WatchListNames
    {
      get
      {
        return watchLists;
      }
      set { ;}
    }
    public String SelectedWatchList
    {
      get { return selectedWatchList; }
      set { selectedWatchList = value; base.OnPropertyChanged("SelectedWatchList"); }
    }
    public ICommand DisplayHistorical
    {
      get
      {
        if (displayHistoricalCommand == null)
        {
          displayHistoricalCommand = new RelayCommand(param => 
          {
            SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.HistoricalViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All}");
            saveParams.Referer=this;
            WorkspaceInstantiator.Invoke(saveParams);
          }, param => { return null != selectedItem && null != selectedItem.Symbol; });
        }
        return displayHistoricalCommand;
      }
    }
    public ICommand DisplaySECFilings
    {
      get
      {
        if (null == displaySECFilingsCommand)
        {
          displaySECFilingsCommand = new RelayCommand(param =>
          {
            SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.SECFilingViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,Valuations");
            saveParams.Referer=this;
            WorkspaceInstantiator.Invoke(saveParams);
          }, param => { return null != selectedItem && null!=selectedItem.Symbol; });
        }
        return displaySECFilingsCommand;
      }
    }
    public ICommand DisplayAnalystRatings
    {
      get
      {
        if (analystRatingsCommand == null)
        {
          analystRatingsCommand = new RelayCommand(param => this.DisplayAnalystRatingsCommand(), param => { return null != selectedItem && null != selectedItem.Symbol; });
        }
        return analystRatingsCommand;
      }
    }
    public ICommand DisplayHeadlines
    {
      get
      {
        if (null == displayHeadlinesCommand)
        {
          displayHeadlinesCommand = new RelayCommand(param =>
          {
            SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.HeadlinesViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,Valuations");
            saveParams.Referer=this;
            WorkspaceInstantiator.Invoke(saveParams);
          }, param => { return null != selectedItem && null!=selectedItem.Symbol; });
        }
        return displayHeadlinesCommand;
      }
    }
    public ICommand DisplayMACD
    {
      get
      {
        if (macdCommand == null)
        {
          macdCommand = new RelayCommand(param => this.DisplayMACDCommand(), param => { return null != selectedItem && null != selectedItem.Symbol; });
        }
        return macdCommand;
      }
    }
    public ICommand DisplayMovingAverage
    {
      get
      {
        if (movingAverageCommand == null)
        {
          movingAverageCommand = new RelayCommand(param => this.DisplayMovingAverageCommand(), param => { return null != selectedItem && null != selectedItem.Symbol; });
        }
        return movingAverageCommand;
      }
    }
    public ICommand DisplayStochastics
    {
      get
      {
        if (stochasticsCommand == null)
        {
          stochasticsCommand = new RelayCommand(param => this.DisplayStochasticsCommand(), param => { return null != selectedItem && null != selectedItem.Symbol; });
        }
        return stochasticsCommand;
      }
    }
    public ICommand DisplayRelativeStrength
    {
      get
      {
        if (relativeStrengthCommand == null)
        {
          relativeStrengthCommand = new RelayCommand(param => this.DisplayRelativeStrengthCommand(), 
            param => { return null != selectedItem && null!=selectedItem.Symbol; });
        }
        return relativeStrengthCommand;
      }
    }
    public void DisplayAnalystRatingsCommand()
    {
      SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.AnalystRatingsViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All}");
      saveParams.Referer=this;
      WorkspaceInstantiator.Invoke(saveParams);
    }
    public void DisplayStochasticsCommand()
    {
      SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.StochasticsViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180");
      saveParams.Referer=this;
      WorkspaceInstantiator.Invoke(saveParams);
    }
    public void DisplayRelativeStrengthCommand()
    {
      SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.RSIViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,60,SelectedRSIDayCount,14");
      saveParams.Referer=this;
      WorkspaceInstantiator.Invoke(saveParams);
    }
    public void DisplayMACDCommand()
    {
      SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.MACDViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180");
      saveParams.Referer=this;
      WorkspaceInstantiator.Invoke(saveParams);
    }
    public void DisplayMovingAverageCommand()
    {
      SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.MovingAverageViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,200");
      saveParams.Referer=this;
      WorkspaceInstantiator.Invoke(saveParams);
    }
    public ICommand DisplayStickerValuation
    {
      get
      {
        if (null == stickerValuationCommand)
        {
          stickerValuationCommand = new RelayCommand(param =>
          {
            SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.StickerPriceViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All}");
            saveParams.Referer=this;
            WorkspaceInstantiator.Invoke(saveParams);
          }, param => { return null != selectedItem && null!=selectedItem.Symbol; });
        }
        return stickerValuationCommand;
      }
    }
    public ICommand DisplayDCFValuation
    {
      get
      {
        if (null == dcfValuationCommand)
        {
          dcfValuationCommand = new RelayCommand(param =>
          {
            SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.DCFValuationViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All}");
            saveParams.Referer=this;
            WorkspaceInstantiator.Invoke(saveParams);
          }, param => { return null != selectedItem && null!=selectedItem.Symbol; });
        }
        return dcfValuationCommand;
      }
    }
    public ICommand DisplayPriceHistory
    {
      get
      {
        if (priceHistoryCommand == null)
        {
          priceHistoryCommand = new RelayCommand(param => this.DisplayPriceHistoryCommand(), param => { return null != selectedItem && null != selectedItem.Symbol; });
        }
        return priceHistoryCommand;
      }
    }
    public ICommand DisplayDividendHistory
    {
      get
      {
        if (dividendHistoryCommand == null)
        {
          dividendHistoryCommand = new RelayCommand(param => 
          {
            SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.DividendHistoryViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All}");
            saveParams.Referer=this;
            WorkspaceInstantiator.Invoke(saveParams);
          }, param => { return null != selectedItem && null != selectedItem.Symbol; });
        }
        return dividendHistoryCommand;
      }
    }
    public void DisplayPriceHistoryCommand()
    {
      SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.PricingViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180");
      saveParams.Referer=this;
      WorkspaceInstantiator.Invoke(saveParams);
    }
    public ICommand DisplayBollingerBand
    {
      get
      {
        if (bollingerBandCommand == null)
        {
          bollingerBandCommand = new RelayCommand(param => this.DisplayBollingerBandCommand(), param => { return null != selectedItem && null != selectedItem.Symbol; });
        }
        return bollingerBandCommand;
      }
    }
    public ICommand RemoveFromWatchList
    {
      get
      {
        if (removeFromWatchListCommand == null)
        {
          removeFromWatchListCommand = new RelayCommand(param => this.RemoveFromWatchListCommand(), 
            param => 
            {
              if(null==selectedItem || null==selectedItem.Symbol)return false;
              if (!WatchListDA.IsInWatchList(selectedItem.Symbol, selectedWatchList)) return false;
              PortfolioTrades portfolioTrades=PortfolioDA.GetOpenTradesSymbol(selectedItem.Symbol);
              if(null!=portfolioTrades&&0!=portfolioTrades.Count)return false;
              return true;
            });
        }
        return removeFromWatchListCommand;
      }
    }
    public void DisplayBollingerBandCommand()
    {
      SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.BollingerBandViewModel,SelectedSymbol," + selectedItem.Symbol + ",SelectedWatchList,{All},SelectedDayCount,180");
      saveParams.Referer=this;
      WorkspaceInstantiator.Invoke(saveParams);
    }
    public void RemoveFromWatchListCommand()
    {
      if (!WatchListDA.IsInWatchList(selectedItem.Symbol, selectedWatchList))
      {
        System.Windows.MessageBox.Show(String.Format("selected symbol {0} is not in watchlist {1}",selectedItem.Symbol,selectedWatchList),"Info", MessageBoxButton.OK,  MessageBoxImage.Information);
        return;
      }
      if (!WatchListDA.RemoveFromWatchList(selectedItem.Symbol, selectedWatchList))
      {
        System.Windows.MessageBox.Show(String.Format("Error removing {0} from watchlist {1}",selectedItem.Symbol,selectedWatchList),"Warning", MessageBoxButton.OK,  MessageBoxImage.Warning);
      }
      else
      {
        base.OnPropertyChanged("SelectedWatchList");
      }
    }


    public String Description
    {
      get
      {
        if(null== selectedItem || null==selectedItem.Symbol)return "No row selected.";
        CompanyProfile companyProfile=CompanyProfileDA.GetCompanyProfile(selectedItem.Symbol);
        if(null==companyProfile || null==companyProfile.Description)return "No description found.";
        return companyProfile.Description;
      }
    }    
    public CompanyProfile SelectedItem
    {
      get
      {
        return selectedItem;
      }
      set
      {
        selectedItem = value;
      }
    }
  }
}

