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

namespace MarketData.MarketDataModel
{
  public class BalanceSheet
  {
    public enum PeriodType { Annual = 0, Quarterly = 1 }
    private String symbol;
    private DateTime asof;
    private double longTermDebt;
    private double otherLiabilities;
    private double deferredLongTermLiabilities;
    private double minorityInterest;
    private double negativeGoodwill;
    private double goodwill;
    private double totalStockHolderEquity;
    private double inventory;
    private double propertyPlantAndEquipment;
    private double intangibleAssets;
    private double accumulatedAmortization;
    private double totalAssets;
    private double totalCurrentAssets;
    private double totalLiabilities;
    private double totalCurrentLiabilities;
    private double cashAndCashEquivalents;
    private PeriodType period;
    private DateTime modified;

    public BalanceSheet()
    {
    }
// 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(BalanceSheet previousBalanceSheet)
    {
      if(null==previousBalanceSheet)return;
      if(!Symbol.Equals(previousBalanceSheet.Symbol))return;
      if(!AsOf.Date.Equals(previousBalanceSheet.AsOf.Date))return;
      if(!Period.Equals(previousBalanceSheet.Period))return;
      if(Utility.IsZeroOrNaN(LongTermDebt))LongTermDebt=previousBalanceSheet.LongTermDebt;
      if(Utility.IsZeroOrNaN(OtherLiabilities))OtherLiabilities=previousBalanceSheet.OtherLiabilities;
      if(Utility.IsZeroOrNaN(DeferredLongTermLiabilities))DeferredLongTermLiabilities=previousBalanceSheet.DeferredLongTermLiabilities;
      if(Utility.IsZeroOrNaN(MinorityInterest))MinorityInterest=previousBalanceSheet.MinorityInterest;
      if(Utility.IsZeroOrNaN(NegativeGoodwill))NegativeGoodwill=previousBalanceSheet.NegativeGoodwill;
      if(Utility.IsZeroOrNaN(Goodwill))Goodwill=previousBalanceSheet.Goodwill;
      if(Utility.IsZeroOrNaN(TotalStockHolderEquity))TotalStockHolderEquity=previousBalanceSheet.TotalStockHolderEquity;
      if(Utility.IsZeroOrNaN(Inventory))Inventory=previousBalanceSheet.Inventory;
      if(Utility.IsZeroOrNaN(PropertyPlantAndEquipment))PropertyPlantAndEquipment=previousBalanceSheet.PropertyPlantAndEquipment;
      if(Utility.IsZeroOrNaN(IntangibleAssets))IntangibleAssets=previousBalanceSheet.IntangibleAssets;
      if(Utility.IsZeroOrNaN(AccumulatedAmortization))AccumulatedAmortization=previousBalanceSheet.AccumulatedAmortization;
      if(Utility.IsZeroOrNaN(TotalAssets))TotalAssets=previousBalanceSheet.TotalAssets;
      if(Utility.IsZeroOrNaN(TotalCurrentAssets))TotalCurrentAssets=previousBalanceSheet.TotalCurrentAssets;
      if(Utility.IsZeroOrNaN(TotalLiabilities))TotalLiabilities=previousBalanceSheet.TotalLiabilities;
      if(Utility.IsZeroOrNaN(TotalCurrentLiabilities))TotalCurrentLiabilities=previousBalanceSheet.TotalCurrentLiabilities;
      if(Utility.IsZeroOrNaN(CashAndCashEquivalents))CashAndCashEquivalents=previousBalanceSheet.CashAndCashEquivalents;
    }
    public String Symbol
    {
      get { return symbol; }
      set { symbol = value; }
    }
    public DateTime AsOf
    {
      get { return asof; }
      set { asof = value; }
    }
    public double CashAndCashEquivalents
    {
      get { return cashAndCashEquivalents; }
      set { cashAndCashEquivalents = value; }
    }
    public double LongTermDebt
    {
      get { return longTermDebt; }
      set { longTermDebt = value; }
    }
    public double OtherLiabilities
    {
      get { return otherLiabilities; }
      set { otherLiabilities = value; }
    }
    public double DeferredLongTermLiabilities
    {
      get { return deferredLongTermLiabilities; }
      set { deferredLongTermLiabilities = value; }
    }
    public double MinorityInterest
    {
      get { return minorityInterest; }
      set { minorityInterest = value; }
    }
    public double Goodwill
    {
      get { return goodwill; }
      set { goodwill = value; }
    }
    public double NegativeGoodwill
    {
      get { return negativeGoodwill; }
      set { negativeGoodwill = value; }
    }
    public double TotalStockHolderEquity
    {
      get { return totalStockHolderEquity; }
      set { totalStockHolderEquity=value; }
    }
    public PeriodType Period
    {
      get { return period; }
      set { period = value; }
    }
    public double Inventory
    {
      get { return inventory; }
      set { inventory = value; }
    }
    public double PropertyPlantAndEquipment
    {
      get { return propertyPlantAndEquipment; }
      set { propertyPlantAndEquipment = value; }
    }
    public double IntangibleAssets
    {
      get { return intangibleAssets; }
      set { intangibleAssets = value; }
    }
    public double AccumulatedAmortization
    {
      get { return accumulatedAmortization; }
      set { accumulatedAmortization=value; }
    }
    public String PeriodAsString
    {
      get { return PeriodType.Quarterly.Equals(period) ? "Quarterly" : "Annual"; }
    }
    public double TotalAssets
    {
      get{return totalAssets;}
      set{totalAssets=value;}
    }
    public double TotalCurrentAssets
    {
      get{return totalCurrentAssets;}
      set{totalCurrentAssets=value;}
    }
    public double TotalLiabilities
    {
      get{return totalLiabilities;}
      set{totalLiabilities=value;}
    }
    public double TotalCurrentLiabilities
    {
      get{return totalCurrentLiabilities;}
      set{totalCurrentLiabilities=value;}
    }
    public double NetCurrentAssetValue
    {
      get{return TotalCurrentAssets-TotalLiabilities;}
    }
    public double NetFixedAssets
    {
      get
      {
        if(double.IsNaN(TotalAssets)||double.IsNaN(TotalCurrentAssets)||double.IsNaN(Goodwill))return double.NaN;
        return TotalAssets-TotalCurrentAssets-Goodwill;
      }
    }
    public DateTime Modified
    {
      get { return modified; }
      set { modified = value; }
    }

    public static String Heading
    {
      get
      {
        StringBuilder sb = new StringBuilder();
        sb.Append("Symbol,AsOf,LongTermDebt,OtherLiabilities,DeferredLongTermLiabilities,MinorityInterest,NegativeGoodwill,TotalStockHolderEquity,Inventory,PP&E,IntangibleAssets,AccumulatedAmortization,Period,TotalAssets,TotalCurrentAssets,TotalLiabilities,TotalCurrentLiabilities,CashAndCashEquivalents,NetCurrentAssetValue");
        return sb.ToString();
      }
    }
    public override string ToString()
    {
      StringBuilder sb = new StringBuilder();
      sb.Append(symbol).Append(",");
      sb.Append(Utility.DateTimeToStringMMSDDSYYYY(asof)).Append(",");
      sb.Append(String.Format("{0:C}", LongTermDebt)).Append(",");
      sb.Append(String.Format("{0:C}", OtherLiabilities)).Append(",");
      sb.Append(String.Format("{0:C}", DeferredLongTermLiabilities)).Append(",");
      sb.Append(String.Format("{0:C}", MinorityInterest)).Append(",");
      sb.Append(String.Format("{0:C}", NegativeGoodwill)).Append(",");
      sb.Append(String.Format("{0:C}", TotalStockHolderEquity)).Append(",");
      sb.Append(String.Format("{0:C}", Inventory)).Append(",");
      sb.Append(String.Format("{0:C}", PropertyPlantAndEquipment)).Append(",");
      sb.Append(String.Format("{0:C}", IntangibleAssets)).Append(",");
      sb.Append(String.Format("{0:C}", AccumulatedAmortization)).Append(",");
      sb.Append(PeriodAsString).Append(",");
      sb.Append(String.Format("{0:C}", TotalAssets)).Append(",");
      sb.Append(String.Format("{0:C}", TotalCurrentAssets)).Append(",");
      sb.Append(String.Format("{0:C}", TotalLiabilities)).Append(",");
      sb.Append(String.Format("{0:C}", TotalCurrentLiabilities)).Append(",");
      sb.Append(String.Format("{0:C}", CashAndCashEquivalents)).Append(",");
      sb.Append(String.Format("{0:C}", NetCurrentAssetValue));
      return sb.ToString();
    }
  }
}