using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Runtime.CompilerServices;
using System.Text;
using Avalonia.Threading;
using Axiom.Utils;
using MarketData.Cache;
using MarketData.DataAccess;
using PortfolioManager.Cache;
using PortfolioManager.Command;

namespace PortfolioManager.ViewModels
{
  public class TabIndexArgs : EventArgs
  {
    public int Index { get; set; }
  }

  public partial class MainWindowViewModel : WorkspaceViewModel
    {
      private ReadOnlyCollection<CommandViewModel> commands;
      private ObservableCollection<WorkspaceViewModel> workspaces;
      private int selectedIndex = -1;

      public EventHandler<TabIndexArgs> OnIndexChangeEventHandler;


      public MainWindowViewModel()
      {
        base.DisplayName = GetTitle();
        Dispatcher.UIThread.InvokeAsync(() => LoadViewStateThreadProc());
      }


      protected override void OnDispose()
      {
        MDTrace.WriteLine(LogLevel.DEBUG, "[MainWindowViewModel:OnDispose] ");
        WorkspacePersistenceHelper.Save(WorkspacePersistenceHelper.PARAMS_FILE, this.Workspaces);
        foreach (WorkspaceViewModel workspaceViewModel in this.Workspaces)
        {
          workspaceViewModel.Dispose();
        }
        try { LocalPriceCache.GetInstance().Dispose(); } catch (Exception) {; }
        try { GBPriceCache.GetInstance().Dispose(); } catch (Exception) {; }
        try { ImageCache.GetInstance().Dispose(); } catch (Exception) {; }
        //try{PriceCache.GetInstance().Dispose();}catch(Exception){;}
      // try{SymbolCache.GetInstance().Dispose();}catch(Exception){;}
      base.OnDispose();
        MDTrace.WriteLine(LogLevel.DEBUG, "[MainWindowViewModel:OnDispose] LEAVE");
      }

      private static String GetTitle()
      {
        DataSourceEx dataSource = MainDataSource.Instance.LocateDataSource("market_data");
        StringBuilder sb = new StringBuilder();
        sb.Append("eNavigator").Append(" ").Append("(").Append(Environment.UserName).Append(")").Append(" ");
        sb.Append("[").Append(Environment.OSVersion.VersionString).Append("]").Append(" ");
        sb.Append("[").Append("DataSource->").Append(dataSource.Datasource).Append("]");
        return sb.ToString();
      }

      private void LoadViewStateThreadProc()
      {
        WorkspacePersistenceHelper.Load(WorkspacePersistenceHelper.PARAMS_FILE, this.Workspaces, InstantiateWorkspace);
      }

      public override bool CanPersist()
      {
        return false;
      }

      public override SaveParameters GetSaveParameters()
      {
        return null;
      }

      public override void SetSaveParameters(SaveParameters saveParameters)
      {
      }

      public ReadOnlyCollection<CommandViewModel> Commands
      {
        get
        {
          if (null == commands)
          {
            List<CommandViewModel> commandList = this.CreateCommands();
            commands = new ReadOnlyCollection<CommandViewModel>(commandList);
          }
          return commands;
        }
      }

      private List<CommandViewModel> CreateCommands()
      {
        return new List<CommandViewModel>()
        {
          new CommandViewModel("ScottPlot", new MyRelayCommand(ParamArrayAttribute => this.ViewScottPlot())),          
          new CommandViewModel("Bollinger Bands", new MyRelayCommand(ParamArrayAttribute => this.ViewBollingerBands())),
          new CommandViewModel("Gain/Loss", new MyRelayCommand(ParamArrayAttribute => this.ViewGainLoss())),
          new CommandViewModel("Momentum Model", new MyRelayCommand(ParamArrayAttribute => this.ViewMomentum())),
          new CommandViewModel("MGSHMomentum Model", new MyRelayCommand(ParamArrayAttribute => this.ViewMGSHMomentum())),
          new CommandViewModel("CMMomentum Model", new MyRelayCommand(ParamArrayAttribute => this.ViewCMMomentum())),
          new CommandViewModel("CMTrend Model", new MyRelayCommand(ParamArrayAttribute => this.ViewCMTrend()))
        };
      }

      private void ViewScottPlot()
      {
        ScottPlotViewModel workspace = null;
        if (null == workspace)
        {
          workspace = new ScottPlotViewModel();
          workspace.WorkspaceInstantiator = InstantiateWorkspace;
          workspace.Referer = GetReferal();
          //        AddMenuItem(workspace);
        this.Workspaces.Add(workspace);
        }
        this.SetActiveWorkspace(workspace);
      }    

    private void ViewBollingerBands()
    {
      BollingerBandViewModel workspace = null;
      if (null == workspace)
      {
        workspace = new BollingerBandViewModel();
        workspace.WorkspaceInstantiator = InstantiateWorkspace;
        workspace.Referer = GetReferal();
        //        AddMenuItem(workspace);
        this.Workspaces.Add(workspace);
      }
      this.SetActiveWorkspace(workspace);
    }      

      private void ViewCMTrend()
    {
      CMTrendViewModel workspace = null;
      if (null == workspace)
      {
        workspace = new CMTrendViewModel();
        workspace.WorkspaceInstantiator = InstantiateWorkspace;
        workspace.Referer = GetReferal();
        //        AddMenuItem(workspace);
        this.Workspaces.Add(workspace);
      }
      this.SetActiveWorkspace(workspace);
    }
      
      private void ViewGainLoss()
      {
        GainLossViewModel workspace = null;
        if (null == workspace)
        {
          workspace = new GainLossViewModel();
          workspace.WorkspaceInstantiator = InstantiateWorkspace;
          workspace.Referer = GetReferal();
          //        AddMenuItem(workspace);
        this.Workspaces.Add(workspace);
        }
        this.SetActiveWorkspace(workspace);
      }      

      private void ViewMGSHMomentum()
    {
      MGSHMomentumViewModel workspace = null;
      if (null == workspace)
      {
        workspace = new MGSHMomentumViewModel();
        workspace.WorkspaceInstantiator = InstantiateWorkspace;
        workspace.Referer = GetReferal();
        //        AddMenuItem(workspace);
        this.Workspaces.Add(workspace);
      }
      this.SetActiveWorkspace(workspace);
    }

      private void ViewMomentum()
      {
        MomentumViewModel workspace = null;
        if (null == workspace)
        {
          workspace = new MomentumViewModel();
          workspace.WorkspaceInstantiator = InstantiateWorkspace;
          workspace.Referer = GetReferal();
          //        AddMenuItem(workspace);
        this.Workspaces.Add(workspace);
        }
        this.SetActiveWorkspace(workspace);
      }

      private void ViewCMMomentum()
      {
        CMMomentumViewModel workspace = null;
        if (null == workspace)
        {
          workspace = new CMMomentumViewModel();
          workspace.WorkspaceInstantiator = InstantiateWorkspace;
          workspace.Referer = GetReferal();
          //        AddMenuItem(workspace);
        this.Workspaces.Add(workspace);
        }
        
        this.SetActiveWorkspace(workspace);
      }

      public ObservableCollection<WorkspaceViewModel> Workspaces
      {
        get
        {
          if (null == workspaces)
          {
            workspaces = new ObservableCollection<WorkspaceViewModel>();
            workspaces.CollectionChanged += this.OnWorkspacesChanged;
          }
          return workspaces;
        }
      }

      private void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e)
      {
        if (e.NewItems != null && e.NewItems.Count != 0)
        {
          foreach (WorkspaceViewModel workspace in e.NewItems)
          {
            workspace.RequestClose += this.OnWorkspaceRequestClose;
          }
        }

        if (e.OldItems != null && e.OldItems.Count != 0)
        {
          foreach (WorkspaceViewModel workspace in e.OldItems)
          {
            workspace.RequestClose -= this.OnWorkspaceRequestClose;
          }
        }
      }

      private void OnWorkspaceRequestClose(object sender, EventArgs e)
      {
        WorkspaceViewModel workspace = sender as WorkspaceViewModel;
        workspace.Dispose();
        this.Workspaces.Remove(workspace);
        RemoveMenuItem(workspace);
        if (null != workspace.Referer) this.SetActiveWorkspace(workspace.Referer);
      }

      public void RemoveMenuItem(WorkspaceViewModel viewModel)
      {
        // if(!menuCollectionDictionary.ContainsKey(viewModel))return;
        // menuCollection.Remove(menuCollectionDictionary[viewModel]);
        // menuCollectionDictionary.Remove(viewModel);
      }

      private void SetActiveWorkspace(WorkspaceViewModel workspace)
      {
        int itemIndex = workspaces.IndexOf(workspace);
        SelectedIndex = itemIndex;
      }

    private WorkspaceViewModel GetReferal()
    {
      if (null == workspaces || 0 == workspaces.Count) return null;
      return workspaces[workspaces.Count-1];
    } 
      
      public int SelectedIndex
    {
      get
      {
        return selectedIndex;
      }
      set
      {
        selectedIndex = value;
        TabIndexArgs args = new TabIndexArgs() { Index = selectedIndex };
        OnIndexChangeEventHandler.Invoke(this, args);
        base.OnPropertyChanged("SelectedIndex");
      }
    }

    public void InstantiateWorkspace(SaveParameters saveParameters)
    {
      WorkspaceViewModel workspaceViewModel = WorkspacePersistenceHelper.Load(saveParameters, workspaces, InstantiateWorkspace);
      SetActiveWorkspace(workspaceViewModel);
        //      AddMenuItem(workspaceViewModel);
    }
    }
}
