using System;
using System.Text;
using MarketData.Utils;

namespace MarketData.MarketDataModel
{

  public class CashflowStatement
  {
    public enum PeriodType { Annual=0,Quarterly=1}
    private String symbol;
    private DateTime asof;
    private double depreciationAndAmortization;
    private double deferredIncomeTaxes;
    private double stockBasedCompensation;
    private double accountsReceivable;
    private double inventory;
    private double accountsPayable;
    private double accruedLiabilities;
    private double operatingCashflow;
    private double freeCashflow;
    private PeriodType period;
    private DateTime modified;

    public CashflowStatement()
    {
    }
// It is appropriate to use the AsOf date in the comparison of the financial statements because the AsOf date is the statement date.
    public void MergeFrom(CashflowStatement previousCashflowStatement)
    {
      if(null==previousCashflowStatement)return;
      if(!symbol.Equals(previousCashflowStatement.Symbol))return;
      if(!AsOf.Date.Equals(previousCashflowStatement.AsOf.Date))return;
      if(!Period.Equals(previousCashflowStatement.Period))return;
      if(Utility.IsZeroOrNaN(DepreciationAndAmortization))DepreciationAndAmortization=previousCashflowStatement.DepreciationAndAmortization;
      if(Utility.IsZeroOrNaN(DeferredIncomeTaxes))DeferredIncomeTaxes=previousCashflowStatement.DeferredIncomeTaxes;
      if(Utility.IsZeroOrNaN(StockBasedCompensation))StockBasedCompensation=previousCashflowStatement.StockBasedCompensation;
      if(Utility.IsZeroOrNaN(AccountsReceivable))AccountsReceivable=previousCashflowStatement.AccountsReceivable;
      if(Utility.IsZeroOrNaN(Inventory))Inventory=previousCashflowStatement.Inventory;
      if(Utility.IsZeroOrNaN(AccountsPayable))AccountsPayable=previousCashflowStatement.AccountsPayable;
      if(Utility.IsZeroOrNaN(AccruedLiabilities))AccruedLiabilities=previousCashflowStatement.AccruedLiabilities;
      if(Utility.IsZeroOrNaN(OperatingCashflow))OperatingCashflow=previousCashflowStatement.OperatingCashflow;
      if(Utility.IsZeroOrNaN(FreeCashflow))FreeCashflow=previousCashflowStatement.FreeCashflow;
    }

    public bool IsValid()
    {
      if(String.IsNullOrEmpty(symbol))return false;
      if(AsOf.Date.Equals(Utility.Epoch))return false;
      if(Utility.IsZeroOrNaN(DepreciationAndAmortization)&&
          Utility.IsZeroOrNaN(DeferredIncomeTaxes)&&
          Utility.IsZeroOrNaN(StockBasedCompensation)&&
          Utility.IsZeroOrNaN(AccountsReceivable)&&
          Utility.IsZeroOrNaN(Inventory)&&
          Utility.IsZeroOrNaN(AccountsPayable)&&
          Utility.IsZeroOrNaN(AccruedLiabilities)&&
          Utility.IsZeroOrNaN(OperatingCashflow)&&
          Utility.IsZeroOrNaN(FreeCashflow)
      )return false;
      return true;
    }

    public String Symbol
    {
      get { return symbol; }
      set { symbol = value; }
    }
    public DateTime AsOf
    {
      get { return asof; }
      set { asof = value; }
    }
    public double DepreciationAndAmortization
    {
      get{return depreciationAndAmortization;}
      set{depreciationAndAmortization=value;}
    }
    public double DeferredIncomeTaxes
    {
      get{return deferredIncomeTaxes;}
      set{deferredIncomeTaxes=value;}
    }
    public double StockBasedCompensation
    {
      get{return stockBasedCompensation;}
      set{stockBasedCompensation=value;}
    }
    public double AccountsReceivable
    {
      get{return accountsReceivable;}
      set{accountsReceivable=value;}
    }
    public double Inventory
    {
      get{return inventory;}
      set{inventory=value;}
    }
    public double AccountsPayable
    {
      get{return accountsPayable;}
      set{accountsPayable=value;}
    }
    public double AccruedLiabilities
    {
      get{return accruedLiabilities;}
      set{accruedLiabilities=value;}
    }
    public double OperatingCashflow
    {
      get{return operatingCashflow;}
      set{operatingCashflow=value;}
    }
    public double FreeCashflow
    {
      get{return freeCashflow;}
      set{freeCashflow=value;}
    }
    public PeriodType Period
    {
      get { return period; }
      set { period = value; }
    }
    public String PeriodAsString
    {
      get { return PeriodType.Quarterly.Equals(period) ? "Quarterly" : "Annual"; }
    }
    public DateTime Modified
    {
      get { return modified; }
      set { modified = value; }
    }
    public static String Heading
    {
      get
      {
        StringBuilder sb = new StringBuilder();
        sb.Append("Symbol,AsOf,DepreciationAndAmortization,DeferredIncomeTaxes,StockBasedCompensation,AccountsReceivable,Inventory,AccountsPayable,AccruedLiabilities,OperatingCashflow,FreeCashflow,Period");
        return sb.ToString();
      }
    }
    public override string ToString()
    {
      StringBuilder sb = new StringBuilder();
      sb.Append(symbol).Append(",");
      sb.Append(Utility.DateTimeToStringMMSDDSYYYY(asof)).Append(",");
      sb.Append(Utility.AddQuotes(String.Format("{0:C}", DepreciationAndAmortization))).Append(",");
      sb.Append(Utility.AddQuotes(String.Format("{0:C}", DeferredIncomeTaxes))).Append(",");
      sb.Append(Utility.AddQuotes(String.Format("{0:C}", StockBasedCompensation))).Append(",");
      sb.Append(Utility.AddQuotes(String.Format("{0:C}", AccountsReceivable))).Append(",");
      sb.Append(Utility.AddQuotes(String.Format("{0:C}", Inventory))).Append(",");
      sb.Append(Utility.AddQuotes(String.Format("{0:C}", AccountsPayable))).Append(",");
      sb.Append(Utility.AddQuotes(String.Format("{0:C}", AccruedLiabilities))).Append(",");
      sb.Append(Utility.AddQuotes(String.Format("{0:C}", OperatingCashflow))).Append(",");
      sb.Append(Utility.AddQuotes(String.Format("{0:C}", FreeCashflow))).Append(",");
      sb.Append(PeriodAsString);
      return sb.ToString();
    }
  }
}

