using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using MarketData.Utils;
using System.Collections.ObjectModel;
using MarketData.Generator.GainLoss;
using MarketData.DataAccess;

// The summary item collection is the data behind the views right-hand grid.  This view shows the gain/loss for the date that is selected in the compound model

namespace MarketData.MarketDataModel.GainLoss
{
  public class GainLossSummaryItemCollection:List<GainLossSummaryItem>
  {
    public GainLossSummaryItemCollection()
    {
    }
    public GainLossSummaryItemCollection(PortfolioTrades portfolioTrades,ITotalGainLossGenerator gainLossGenerator,IActiveGainLossGenerator activeGainLossGenerator,DateTime? maxDateRef=null)
    {
      List<String> symbols=portfolioTrades.Symbols;

      if(null==gainLossGenerator || null==activeGainLossGenerator)return;

      foreach(String symbol in symbols)
      {
        PortfolioTrades portfolioTradesSymbol=portfolioTrades.FilterSymbol(symbol);
        GainLossCollection gainLossCollection=activeGainLossGenerator.GenerateGainLoss(portfolioTradesSymbol,maxDateRef);

        TotalGainLossCollection totalGainLossCollection=gainLossGenerator.GenerateTotalGainLoss(portfolioTradesSymbol,maxDateRef);
        GainLossCompoundModelCollection gainLossCompoundModelCollection=new GainLossCompoundModelCollection(gainLossCollection,totalGainLossCollection);

        if(1>gainLossCompoundModelCollection.Count) continue;
        GainLossSummaryItem gainLossSummaryItem=new GainLossSummaryItem();
        gainLossSummaryItem.Date=gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-1].Date;
        gainLossSummaryItem.Symbol=symbol;
        gainLossSummaryItem.CompanyName=PricingDA.GetNameForSymbol(symbol);
        gainLossSummaryItem.CurrentGainLoss=gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-1].ActiveGainLoss;
        double previousGainLoss=1==gainLossCompoundModelCollection.Count?0.00:gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-2].ActiveGainLoss;
        gainLossSummaryItem.PreviousGainLoss=previousGainLoss;
        gainLossSummaryItem.Change=gainLossSummaryItem.CurrentGainLoss-gainLossSummaryItem.PreviousGainLoss;
        if(1==gainLossCollection.Count) gainLossSummaryItem.ChangePercent=0.00;
        else
        {
          double currentMarketValue=gainLossCollection[gainLossCollection.Count-1].Exposure+gainLossCollection[gainLossCollection.Count-1].GainLoss;
          double previousMarketValue=gainLossCollection[gainLossCollection.Count-2].Exposure+gainLossCollection[gainLossCollection.Count-2].GainLoss;
          if(0.00==previousMarketValue) gainLossSummaryItem.ChangePercent=0.00;
          else gainLossSummaryItem.ChangePercent=((currentMarketValue-previousMarketValue)/previousMarketValue)*100;
          if(gainLossSummaryItem.CurrentGainLoss<0&&gainLossSummaryItem.PreviousGainLoss<0)
          {  // if current gainloss is negative and previous gainloss is negative then show change percent as a further dip into negative (i.e.) make sure sign is negative
            if(Math.Abs(gainLossSummaryItem.CurrentGainLoss)>Math.Abs(gainLossSummaryItem.PreviousGainLoss)) gainLossSummaryItem.ChangePercent=Math.Abs(gainLossSummaryItem.ChangePercent)*-1.00;
          }
          else if(gainLossSummaryItem.CurrentGainLoss<0&&gainLossSummaryItem.PreviousGainLoss>0)
          {
            gainLossSummaryItem.ChangePercent=Math.Abs(gainLossSummaryItem.ChangePercent)*-1.00;
          }
          else if(gainLossSummaryItem.CurrentGainLoss>0&&gainLossSummaryItem.PreviousGainLoss>0)
          {
            if(gainLossSummaryItem.CurrentGainLoss<gainLossSummaryItem.PreviousGainLoss) gainLossSummaryItem.ChangePercent=Math.Abs(gainLossSummaryItem.ChangePercent)*-1.00;
          }
        }
        // here we need to check maxDateRef for null and then call appropriate HasOpenPositions() / HasOpenPositionsOn(date) method
        if(null!=maxDateRef)
        {
          if(!portfolioTrades.HasOpenPositionsOn(symbol,maxDateRef.Value)) continue;
        }
        else
        {
          if(!portfolioTrades.HasOpenPositions(symbol)) continue;
        }
        gainLossSummaryItem.HasStopLimit=PortfolioDA.HasStopLimit(symbol);
        Add(gainLossSummaryItem);
      }
      GainLossSummaryItemCollection gainLossSummaryCollection=new GainLossSummaryItemCollection((from GainLossSummaryItem gainLossSummaryItem in this orderby gainLossSummaryItem.Date descending,gainLossSummaryItem.Change descending,gainLossSummaryItem.Symbol descending select gainLossSummaryItem).ToList());
      Clear();
      AddRange(gainLossSummaryCollection);
    }
    public GainLossSummaryItemCollection(PortfolioTrades portfolioTrades,DateTime? maxDateRef=null)
    {
      List<String> symbols=portfolioTrades.Symbols;
      foreach(String symbol in symbols)
      {
        PortfolioTrades portfolioTradesSymbol=portfolioTrades.FilterSymbol(symbol);
        ITotalGainLossGenerator gainLossGenerator=new GainLossGenerator();
        IActiveGainLossGenerator activeGainLossGenerator=new ActiveGainLossGenerator();
        GainLossCollection gainLossCollection=activeGainLossGenerator.GenerateGainLoss(portfolioTradesSymbol,maxDateRef);
        TotalGainLossCollection totalGainLossCollection=gainLossGenerator.GenerateTotalGainLoss(portfolioTradesSymbol,maxDateRef);
        GainLossCompoundModelCollection gainLossCompoundModelCollection=new GainLossCompoundModelCollection(gainLossCollection,totalGainLossCollection);
        if(1>gainLossCompoundModelCollection.Count) continue;
        GainLossSummaryItem gainLossSummaryItem=new GainLossSummaryItem();
        gainLossSummaryItem.Date=gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-1].Date;
        gainLossSummaryItem.Symbol=symbol;
        gainLossSummaryItem.CompanyName=PricingDA.GetNameForSymbol(symbol);
        gainLossSummaryItem.CurrentGainLoss=gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-1].ActiveGainLoss;
        double previousGainLoss=1==gainLossCompoundModelCollection.Count?0.00:gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-2].ActiveGainLoss;
        gainLossSummaryItem.PreviousGainLoss=previousGainLoss;
        gainLossSummaryItem.Change=gainLossSummaryItem.CurrentGainLoss-gainLossSummaryItem.PreviousGainLoss;
        if(1==gainLossCollection.Count) gainLossSummaryItem.ChangePercent=0.00;
        else
        {
          double currentMarketValue=gainLossCollection[gainLossCollection.Count-1].Exposure+gainLossCollection[gainLossCollection.Count-1].GainLoss;
          double previousMarketValue=gainLossCollection[gainLossCollection.Count-2].Exposure+gainLossCollection[gainLossCollection.Count-2].GainLoss;
          if(0.00==previousMarketValue) gainLossSummaryItem.ChangePercent=0.00;
          else gainLossSummaryItem.ChangePercent=((currentMarketValue-previousMarketValue)/previousMarketValue)*100;
          if(gainLossSummaryItem.CurrentGainLoss<0&&gainLossSummaryItem.PreviousGainLoss<0)
          {  // if current gainloss is negative and previous gainloss is negative then show change percent as a further dip into negative (i.e.) make sure sign is negative
            if(Math.Abs(gainLossSummaryItem.CurrentGainLoss)>Math.Abs(gainLossSummaryItem.PreviousGainLoss)) gainLossSummaryItem.ChangePercent=Math.Abs(gainLossSummaryItem.ChangePercent)*-1.00;
          }
          else if(gainLossSummaryItem.CurrentGainLoss<0&&gainLossSummaryItem.PreviousGainLoss>0)
          {
            gainLossSummaryItem.ChangePercent=Math.Abs(gainLossSummaryItem.ChangePercent)*-1.00;
          }
          else if(gainLossSummaryItem.CurrentGainLoss>0&&gainLossSummaryItem.PreviousGainLoss>0)
          {
            if(gainLossSummaryItem.CurrentGainLoss<gainLossSummaryItem.PreviousGainLoss) gainLossSummaryItem.ChangePercent=Math.Abs(gainLossSummaryItem.ChangePercent)*-1.00;
          }
        }
        // here we need to check maxDateRef for null and then call appropriate HasOpenPositions() / HasOpenPositionsOn(date) method
        if(null!=maxDateRef)
        {
          if(!portfolioTrades.HasOpenPositionsOn(symbol,maxDateRef.Value)) continue;
        }
        else
        {
          if(!portfolioTrades.HasOpenPositions(symbol)) continue;
        }
        gainLossSummaryItem.HasStopLimit=PortfolioDA.HasStopLimit(symbol);
        Add(gainLossSummaryItem);
      }
      GainLossSummaryItemCollection gainLossSummaryCollection=new GainLossSummaryItemCollection((from GainLossSummaryItem gainLossSummaryItem in this orderby gainLossSummaryItem.Date descending,gainLossSummaryItem.Change descending,gainLossSummaryItem.Symbol descending select gainLossSummaryItem).ToList());
      Clear();
      AddRange(gainLossSummaryCollection);
    }
    public GainLossSummaryItemCollection(List<GainLossSummaryItem> gainLossSummaryItemCollection)
    {
      foreach(GainLossSummaryItem gainLossSummaryItem in gainLossSummaryItemCollection) Add(gainLossSummaryItem);
    }
    public GainLossSummaryItemCollection SortByChange()
    {
      GainLossSummaryItemCollection gainLossSummaryCollection=new GainLossSummaryItemCollection((from GainLossSummaryItem gainLossSummaryItem in this orderby gainLossSummaryItem.Date descending,gainLossSummaryItem.Change descending,gainLossSummaryItem.Symbol descending select gainLossSummaryItem).ToList());
      return gainLossSummaryCollection;
    }
  }  
}
