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

namespace TradeBlotter.ViewModels
{
  public class FeedStatisticsViewModel : WorkspaceViewModel
  {
    private String selectedFeedStatisticType=null;
    private List<String> feedTypes=null;
    private FeedStatistics feedStatistics = null;
    private bool busyIndicator = false;
    private RelayCommand refreshCommand;
    private RelayCommand clearCacheCommand;

    public FeedStatisticsViewModel()
    {
      base.DisplayName = "Feed Statistics";
      feedTypes = FeedStatistic.GetFeedStatisticTypes();
      PropertyChanged += OnViewModelPropertyChanged;
    }
    public override SaveParameters GetSaveParameters()
    {
      return null;
    }
    public override void SetSaveParameters(SaveParameters saveParameters)
    {
    }
    public override bool CanPersist()
    {
      return true;
    }
    public ObservableCollection<FeedStatistic> AllItems
    {
      get;
      private set;
    }
    public bool BusyIndicator
    {
      get { return busyIndicator; }
      set
      {
        busyIndicator = value;
        base.OnPropertyChanged("BusyIndicator");
      }
    }
    private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs)
    {
      if (eventArgs.PropertyName.Equals("SelectedFeedType"))
      {
        BusyIndicator = true;
        Task workerTask = Task.Factory.StartNew(() =>
        {
          base.DisplayName = "Feed Statistics(" + selectedFeedStatisticType + ")";
          base.OnPropertyChanged("DisplayName");
          feedStatistics=CompositeDA.GetFeedStatistics(FeedStatistic.FromString(selectedFeedStatisticType));
          this.AllItems = new ObservableCollection<FeedStatistic>(feedStatistics);
        });
        workerTask.ContinueWith((continuation) =>
        {
          BusyIndicator = false;
          base.OnPropertyChanged("AllItems");
          base.OnPropertyChanged("Statistics");
          base.OnPropertyChanged("Title");
        });
      }
    }
    public override String Title
    {
      get
      {
        if (null == selectedFeedStatisticType ) return "";
        return selectedFeedStatisticType;
      }
    }
    public List<String> FeedTypes
    {
      get
      {
        return feedTypes;
      }
      set { ;}
    }
    public String SelectedFeedType
    {
      get { return selectedFeedStatisticType; }
      set { selectedFeedStatisticType = value; base.OnPropertyChanged("SelectedFeedType"); }
    }
    public CompositeDataSource Statistics
    {
      get
      {
        return GetCompositeDataSource();
      }
    }
    private CompositeDataSource GetCompositeDataSource()
    {
      if (null == feedStatistics) return null;
      CompositeDataSource compositeDataSource;
      var xData = new EnumerableDataSource<DateTime>(feedStatistics.Select(x => x.Date.Date));
      xData.SetXMapping(x => (x.Ticks / 10000000000.0));
      var yData = new EnumerableDataSource<double>(feedStatistics.Select(y => (double)y.Records));
      yData.SetYMapping(y => y);
      compositeDataSource = xData.Join(yData);
      return compositeDataSource;
    }
    public ICommand RefreshCommand
    {
      get
      {
        if(refreshCommand==null)
        {
          refreshCommand=new RelayCommand(param => this.Refresh(),param => this.CanRefresh);
        }
        return refreshCommand;
      }
    }
    public ICommand ClearCacheCommand
    {
      get
      {
        if(clearCacheCommand==null)
        {
          clearCacheCommand=new RelayCommand(param => this.ClearCache(),param => {return true;});
        }
        return clearCacheCommand;
      }
    }
    private void ClearCache()
    {
      try{LocalPriceCache.GetInstance().Clear();}catch(Exception){;}
      try{GBPriceCache.GetInstance().Clear();}catch(Exception){;}
      try{PriceCache.GetInstance().Clear();}catch(Exception){;}
      MessageBox.Show("All caches have been re-intiialized.",base.DisplayName);
    }
    private void Refresh()
    {
      base.OnPropertyChanged("SelectedFeedType");
    }
    private bool CanRefresh
    {
      get { return true; }
    }
  }
}