using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Threading.Tasks;
using System.Threading;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Media;
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;

namespace TradeBlotter.ViewModels
{
  public class EarningsAnnouncementViewModel : WorkspaceViewModel
  {
    private RelayCommand analystRatingsCommand=null;
    private RelayCommand stochasticsCommand=null;
    private RelayCommand relativeStrengthCommand=null;
    private RelayCommand macdCommand=null;
    private RelayCommand bollingerBandCommand=null;
    private RelayCommand valuationCommand=null;
    private RelayCommand priceHistoryCommand=null;
    private RelayCommand displayStickerValuationCommand=null;
    private RelayCommand displayDCFValuationCommand=null;
    private RelayCommand refreshCommand=null;
    private RelayCommand dividendHistoryCommand=null;
    private RelayCommand displayHistoricalCommand=null;
    private RelayCommand displayHeadlinesCommand=null;
    private EarningsAnnouncementModel selectedItem;
    private bool busyIndicator = false;
    private String busyContent = "Loading Earnings Announcements...";
    private int daysOut=30;
    private ObservableCollection<EarningsAnnouncementModel> allItems;

    public EarningsAnnouncementViewModel()
    {
      base.DisplayName = "Earnings Announcements";
      LoadItems();
      PropertyChanged += OnEarningsAnnouncementViewModelPropertyChanged;
    }
    public override SaveParameters GetSaveParameters()
    {
      SaveParameters saveParams = new SaveParameters();
      saveParams.Add(new KeyValuePair<String, String>("Type",GetType().Namespace+"."+GetType().Name));
      saveParams.Add(new KeyValuePair<String, String>("DaysOut", daysOut.ToString()));
      return saveParams;
    }
    public override void SetSaveParameters(SaveParameters saveParameters)
    {
      try
      {
        daysOut = int.Parse((from KeyValuePair<String, String> item in saveParameters where item.Key.Equals("DaysOut") select item).FirstOrDefault().Value);
        Referer=saveParameters.Referer;
        base.OnPropertyChanged("DaysOut");
      }
      catch (Exception)
      {
      }    }
    public override bool CanPersist()
    {
      return true;
    }
    private void OnEarningsAnnouncementViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs)
    {
    }
    public ObservableCollection<EarningsAnnouncementModel> AllItems
    {
      get { return allItems; }
    }
    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 Dividend History", MenuItemClickedCommand = DisplayDividendHistory, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display Sticker Valuation", MenuItemClickedCommand = DisplayStickerValuation, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display Historical", MenuItemClickedCommand = DisplayHistorical, 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 Price History", MenuItemClickedCommand = DisplayPriceHistory, StaysOpenOnClick = false });
        collection.Add(new MenuItem() { Text = "Display DCF Valuation", MenuItemClickedCommand = DisplayDCFValuation, 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 Valuation", MenuItemClickedCommand = DisplayValuation, StaysOpenOnClick = false });
        return collection;
      }
    }
    public bool BusyIndicator
    {
      get { return busyIndicator; }
      set
      {
        busyIndicator = value;
        base.OnPropertyChanged("BusyIndicator");
      }
    }
    public String BusyContent
    {
      get { return busyContent; }
      set
      {
        busyContent = value;
        base.OnPropertyChanged("BusyContent");
      }
    }
    private void LoadItems()
    {
      BusyIndicator = true;
      bool itemsToday = false;
      Task workerTask = Task.Factory.StartNew(() =>
      {
        allItems=GetEarningsAnnouncements(daysOut);
      });
      workerTask.ContinueWith((continuation)=>
      {
        BusyIndicator = false;
        base.OnPropertyChanged("AllItems");
        base.OnPropertyChanged("Title");
      });
    }
    public static ObservableCollection<EarningsAnnouncementModel> GetEarningsAnnouncements(int daysOutstanding)
    {
      List<EarningsAnnouncementModel> earningsAnnouncementModels = new List<EarningsAnnouncementModel>();
      List<String> symbols = WatchListDA.GetWatchList("valuations");
      if(null==symbols)return new ObservableCollection<EarningsAnnouncementModel>();
      foreach (String symbol in symbols)
      {
        EarningsAnnouncementModel earningsAnnouncementModel=CompositeDA.GetEarningsAnnouncement(symbol);
        if(null==earningsAnnouncementModel)continue;
        if (Math.Abs(earningsAnnouncementModel.DaysFromToday) >= daysOutstanding) continue;
        earningsAnnouncementModels.Add(earningsAnnouncementModel);
      }
      earningsAnnouncementModels.Sort();
      return  new ObservableCollection<EarningsAnnouncementModel>(earningsAnnouncementModels);
    }
    public int DaysOut
    {
      get { return daysOut; }
      set { daysOut = value; base.OnPropertyChanged("DaysOut"); }
    }
    public override String Title
    {
      get { return "Earnings Announcements Next " + daysOut + " Days"; }
    }
    private void Refresh()
    {
      LoadItems();
    }
    private bool CanRefresh
    {
      get { return true; }
    }
    public ICommand DisplayAnalystRatings
    {
      get
      {
        if (null==analystRatingsCommand)
        {
          analystRatingsCommand = new RelayCommand(param => 
          {
            SaveParameters saveParams = new SaveParameters();
            String companyName = PricingDA.GetNameForSymbol(selectedItem.Symbol);
            saveParams.Add(new KeyValuePair<String, String>("Type", "TradeBlotter.ViewModels.AnalystRatingsViewModel"));
            saveParams.Add(new KeyValuePair<String, String>("SelectedSymbol", selectedItem.Symbol));
            saveParams.Add(new KeyValuePair<String, String>("SelectedCompany", companyName));
            saveParams.Add(new KeyValuePair<String, String>("SelectedWatchList", Constants.CONST_ALL));
            saveParams.Referer=this;
            WorkspaceInstantiator.Invoke(saveParams);
          }, param => { return null==selectedItem||null==selectedItem.Symbol?false:true; });
        }
        return analystRatingsCommand;
      }
    }
    public ICommand DisplayStochastics
    {
      get
      {
        if (stochasticsCommand == null)
        {
          stochasticsCommand = new RelayCommand(param => this.DisplayStochasticsCommand(), param => { return null!=selectedItem&&null!=selectedItem.Symbol?true:false; });
        }
        return stochasticsCommand;
      }
    }
    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 ICommand DisplayRelativeStrength
    {
      get
      {
        if (relativeStrengthCommand == null)
        {
          relativeStrengthCommand = new RelayCommand(param => this.DisplayRelativeStrengthCommand(), 
            param => { return null != selectedItem && null!=selectedItem.Symbol; });
        }
        return relativeStrengthCommand;
      }
    }
    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 ICommand DisplayStickerValuation
    {
      get
      {
        if (null == displayStickerValuationCommand)
        {
          displayStickerValuationCommand = 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 displayStickerValuationCommand;
      }
    }
    public ICommand DisplayDCFValuation
    {
      get
      {
        if (null == displayDCFValuationCommand)
        {
          displayDCFValuationCommand = 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 displayDCFValuationCommand;
      }
    }
    public ICommand DisplayMACD
    {
      get
      {
        if (macdCommand == null)
        {
          macdCommand = new RelayCommand(param => this.DisplayMACDCommand(), param => { return null!=selectedItem&&null!=selectedItem.Symbol?true:false; });
        }
        return macdCommand;
      }
    }
    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 ICommand DisplayPriceHistory
    {
      get
      {
        if (priceHistoryCommand == null)
        {
          priceHistoryCommand = new RelayCommand(param => this.DisplayPriceHistoryCommand(), param => { return null!=selectedItem&&null!=selectedItem.Symbol?true:false; });
        }
        return priceHistoryCommand;
      }
    }
    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?true:false; });
        }
        return bollingerBandCommand;
      }
    }
    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 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 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 void DisplayBollingerBandCommand()
    {
      SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.BollingerBandViewModel,SelectedSymbol,"+selectedItem.Symbol+",SelectedWatchList,{All},SelectedDayCount,180");
      saveParams.Referer=this;
      WorkspaceInstantiator.Invoke(saveParams);
    }
    public ICommand DisplayValuation
    {
      get
      {
        if (valuationCommand == null)
        {
          valuationCommand = new RelayCommand(param => this.DisplayValuationCommand(), param => { return true; });
        }
        return valuationCommand;
      }
    }
    public void DisplayValuationCommand()
    {
      List<DateTime> valuationDates = ValuationDA.GetValuationDates();
      if (null == valuationDates || 0 == valuationDates.Count) return;
      DateTime valuationDate = valuationDates[0];
      SaveParameters saveParams = SaveParameters.Parse("Type,TradeBlotter.ViewModels.ValuationsViewModel,SelectedValuationDate," + valuationDate);
      saveParams.Referer=this;
      WorkspaceInstantiator.Invoke(saveParams);
    }
    public ICommand RefreshCommand
    {
      get
      {
        if (refreshCommand == null)
        {
          refreshCommand = new RelayCommand(param => this.Refresh(), param => this.CanRefresh);
        }
        return refreshCommand;
      }
    }
    public EarningsAnnouncementModel SelectedItem
    {
      get
      {
        return selectedItem;
      }
      set
      {
        selectedItem = value;
      }
    }
  }
}
