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

namespace TradeBlotter.ViewModels
{
  public class DCFValuationViewModel : WorkspaceViewModel
  {
    private List<String> symbols;
    private List<String> watchLists;
    private String selectedWatchList;
    private String selectedSymbol;
    private String companyName;
    private ObservableCollection<ReturnItem> dcf = null;
    private bool busyIndicator = false;
    private DCFValuation dcfValuation = null;

    public DCFValuationViewModel()
    {
      base.DisplayName = "DCF Valuation";
      watchLists = WatchListDA.GetWatchLists();
      watchLists.Insert(0, Constants.CONST_ALL);
      selectedWatchList = watchLists.Find(x => x.Equals("Valuations"));
      symbols = WatchListDA.GetWatchList(selectedWatchList);
      selectedSymbol = null;
      PropertyChanged += OnDCFViewModelPropertyChanged;
      base.OnPropertyChanged("SelectedSymbol");
    }
    // ******************************************************************************************** P E R S I S T E N C E ********************************************************************************************
    public override bool CanPersist()
    {
      return true;
    }
    public override SaveParameters GetSaveParameters()
    {
      SaveParameters saveParams = new SaveParameters();
      if (null == selectedSymbol) return null;
      saveParams.Add(new KeyValuePair<String, String>("Type", GetType().Namespace + "." + GetType().Name));
      saveParams.Add(new KeyValuePair<String, String>("SelectedSymbol", selectedSymbol));
      saveParams.Add(new KeyValuePair<String, String>("SelectedWatchList", selectedWatchList));
      return saveParams;
    }
    public override void SetSaveParameters(SaveParameters saveParameters)
    {
      try
      {
        if(saveParameters.ContainsKey("SelectedSymbol")) selectedSymbol=(from KeyValuePair<String,String> item in saveParameters where item.Key.Equals("SelectedSymbol") select item).FirstOrDefault().Value;
        if(saveParameters.ContainsKey("SelectedWatchList")) selectedWatchList=(from KeyValuePair<String,String> item in saveParameters where item.Key.Equals("SelectedWatchList") select item).FirstOrDefault().Value;
        Referer=saveParameters.Referer;
        base.OnPropertyChanged("SelectedWatchList");
        base.OnPropertyChanged("SelectedSymbol");
      }
      catch (Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString()));
      }
    }
    // ******************************************************************************************************************************************************
    public bool BusyIndicator
    {
      get { return busyIndicator; }
      set
      {
        busyIndicator = value;
        base.OnPropertyChanged("BusyIndicator");
      }
    }
    public ObservableCollection<ReturnItem> AllDCF
    {
      get 
      { 
        return dcf; 
      }
      set
      {
        dcf = value;
        base.OnPropertyChanged("AllDCF");
      }
    }
    private void OnDCFViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs)
    {
      if (eventArgs.PropertyName.Equals("SelectedSymbol"))
      {
        if(null==selectedSymbol)return;
        base.DisplayName = "Discounted Cashflow Valuation(" + selectedSymbol + ")";
        base.OnPropertyChanged("DisplayName");
        HandleSelectedSymbol();
      }
      else if (eventArgs.PropertyName.Equals("SelectedWatchList"))
      {
        if(null==selectedWatchList)return;
        HandleSelectedWatchList();
      }
    }
    private void HandleSelectedSymbol()
    {
      BusyIndicator = true;
      Task workerTask = Task.Factory.StartNew(() =>
      {
        if (null != selectedSymbol)
        {
          dcf = null;
          companyName = PricingDA.GetNameForSymbol(selectedSymbol);
          dcfValuation = DCFGenerator.GenerateDCFValuation(selectedSymbol);
          if (null != dcfValuation.ReturnItems && 0 != dcfValuation.ReturnItems.Count)
          {
            dcf = new ObservableCollection<ReturnItem>();
            for(int index=0;index<dcfValuation.ReturnItems.Count;index++)
            {
              ReturnItem returnItem=dcfValuation.ReturnItems[index];
              dcf.Add(returnItem);
            }
          }
        }
      });
      workerTask.ContinueWith((continuation) =>
      {
        BusyIndicator = false;
        UpdateData();
        UpdateDescriptions();
      });
    }
    private void UpdateData()
    {
      base.OnPropertyChanged("AllDCF");
      base.OnPropertyChanged("Beta");
      base.OnPropertyChanged("HistoricalMarketReturn");
      base.OnPropertyChanged("RiskFreeRate");
      base.OnPropertyChanged("MarketCap");
      base.OnPropertyChanged("TotalDebt");
      base.OnPropertyChanged("WACC");
      base.OnPropertyChanged("ROIC");
      base.OnPropertyChanged("CapitalBackground");
      base.OnPropertyChanged("CostOfDebt");
      base.OnPropertyChanged("CostOfEquity");
      base.OnPropertyChanged("TaxRate");
      base.OnPropertyChanged("TotalEquity");
      base.OnPropertyChanged("TotalCapitalInvested");
      base.OnPropertyChanged("InterestExpense");
      base.OnPropertyChanged("OutstandingShares");
      base.OnPropertyChanged("PresentValue");
      base.OnPropertyChanged("EstimatedStockPrice");
      base.OnPropertyChanged("MOS");
      base.OnPropertyChanged("MOSBackground");
      base.OnPropertyChanged("MOS80");
      base.OnPropertyChanged("MOS80Background");
      base.OnPropertyChanged("IntrinsicValue");
      base.OnPropertyChanged("RGVIntrinsic");
      base.OnPropertyChanged("IntrinsicValueRevised");
      base.OnPropertyChanged("RGVIntrinsicValueRevised");
      base.OnPropertyChanged("CurrentPrice");
      base.OnPropertyChanged("PriceDate");
      base.OnPropertyChanged("FreeCashflowGrowth");
      base.OnPropertyChanged("Message");
      base.OnPropertyChanged("Title");
    }
    private void UpdateDescriptions()
    {
      base.OnPropertyChanged("BetaDescription");
      base.OnPropertyChanged("InterestExpenseDescription");
      base.OnPropertyChanged("CostOfEquityDescription");
      base.OnPropertyChanged("CostOfDebtDescription");
      base.OnPropertyChanged("ROICDescription");
      base.OnPropertyChanged("WACCDescription");
      base.OnPropertyChanged("TotalCapitalInvestedDescription");
      base.OnPropertyChanged("TotalLongAndShortTermDebtDescription");
      base.OnPropertyChanged("TotalEquityDescription");
      base.OnPropertyChanged("RiskFreeRateDescription");
      base.OnPropertyChanged("HistoricalMarketReturnDescription");
      base.OnPropertyChanged("OutstandingSharesDescription");
      base.OnPropertyChanged("MOSDescription");
      base.OnPropertyChanged("MOS80Description");
      base.OnPropertyChanged("SumOfDiscountedCashflowsDescription");
      base.OnPropertyChanged("EstimatedStockPriceDescription");
      base.OnPropertyChanged("LatestPriceDescription");
      base.OnPropertyChanged("PriceDateDescription");
      base.OnPropertyChanged("IntrinsicValueDescription");
      base.OnPropertyChanged("IntrinsicValueRevisedDescription");
      base.OnPropertyChanged("RGVIntrinsicRevDescription");
      base.OnPropertyChanged("FreeCashflowGrowthDescription");
    }
    public void OnErrorItemHandler(String symbol, String message)
    {
    }
    private void HandleSelectedWatchList()
    {
//      if (selectedWatchList.Equals(Constants.CONST_ALL)) symbols = PricingDA.GetSymbols();
      if (selectedWatchList.Equals(Constants.CONST_ALL)) symbols = SymbolCache.GetInstance().GetSymbols();
      else
      {
        symbols = WatchListDA.GetWatchList(selectedWatchList);
      }
      base.OnPropertyChanged("Symbols");
    }
// ************************************************************************************************************************************************************************
// ********************************************************************************** C O L O R  S C H E M E **************************************************************
// ************************************************************************************************************************************************************************
    public Brush CapitalBackground
    {
      get
      {
        if (null == dcfValuation || !dcfValuation.Success) return null;
        if (dcfValuation.Enhancements.ROIC > dcfValuation.WACC) return new SolidColorBrush(Colors.LightGreen);
        return new SolidColorBrush(Colors.Red);
      }
    }
    public Brush MOSBackground
    {
      get
      {
        if (null == dcfValuation || !dcfValuation.Success || null == dcfValuation.CurrentPrice) return null;
        if (dcfValuation.CurrentPrice.Close > dcfValuation.StockPriceValuation) return new SolidColorBrush(Colors.Red);
        return new SolidColorBrush(Colors.LightGreen);
      }
    }
    public Brush MOS80Background
    {
      get
      {
        if (null == dcfValuation || !dcfValuation.Success || null == dcfValuation.CurrentPrice) return null;
        if (dcfValuation.CurrentPrice.Close > dcfValuation.StockPriceValuation) return new SolidColorBrush(Colors.Red);
        return new SolidColorBrush(Colors.LightGreen);
      }
    }
// ************************************************************************************************************************************************************************
    public override String Title
    {
      get
      {
        if (null != companyName && null != selectedSymbol) return "Discounted Cashflow Valuation - (" + selectedSymbol + ") " + companyName;
        return "Discounted Cashflow Valuation";
      }
    }
    public String Beta
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.Beta)? Constants.CONST_DASHES : Utility.FormatNumber(dcfValuation.Beta,2);
      }
    }
    public String HistoricalMarketReturn
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.MarketReturn) ? Constants.CONST_DASHES : Utility.FormatPercent(dcfValuation.MarketReturn);
      }
    }
    public String RiskFreeRate
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.RiskFreeRate) ? Constants.CONST_DASHES : Utility.FormatPercent(dcfValuation.RiskFreeRate);
      }
    }
    public String MarketCap
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.MarketValueOfEquity) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.MarketValueOfEquity);
      }
    }
    public String TotalDebt
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.TotalDebt) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.TotalDebt);
      }
    }
    public String WACC
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.WACC) ? Constants.CONST_DASHES : Utility.FormatPercent(dcfValuation.WACC);
      }
    }
    public String ROIC
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.Enhancements.ROIC) ? Constants.CONST_DASHES : Utility.FormatPercent(dcfValuation.Enhancements.ROIC);
      }
    }
    public String CostOfDebt
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.CostOfDebt) ? Constants.CONST_DASHES : Utility.FormatPercent(dcfValuation.CostOfDebt);
      }
    }
    public String CostOfEquity
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.CostOfEquity) ? Constants.CONST_DASHES : Utility.FormatPercent(dcfValuation.CostOfEquity);
      }
    }
    public String TaxRate
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.CorporateTaxRate) ? Constants.CONST_DASHES : Utility.FormatPercent(dcfValuation.CorporateTaxRate);
      }
    }
    public String TotalEquity
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.MarketValueOfEquity) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.MarketValueOfEquity);
      }
    }
    public String TotalCapitalInvested
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.TotalCapitalInvested) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.TotalCapitalInvested);
      }
    }
    public String InterestExpense
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.InterestExpense) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.InterestExpense);
      }
    }
    public String OutstandingShares
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.OutstandingShares) ? Constants.CONST_DASHES : Utility.FormatNumber(dcfValuation.OutstandingShares, 0, true);
      }
    }
    public String PresentValue
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.PresentValue) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.PresentValue);
      }
    }
    public String EstimatedStockPrice
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.StockPriceValuation) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.StockPriceValuation);
      }
    }
    public String CurrentPrice
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || null == dcfValuation.CurrentPrice || double.NaN.Equals(dcfValuation.CurrentPrice.Close) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.CurrentPrice.Close);
      }
    }
    public String PriceDate
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || null == dcfValuation.CurrentPrice ? Constants.CONST_DASHES : Utility.DateTimeToStringMMHDDHYYYY(dcfValuation.CurrentPrice.Date);
      }
    }
    public String FreeCashflowGrowth
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.FreeCashflowGrowth) ? Constants.CONST_DASHES : Utility.FormatPercent(dcfValuation.FreeCashflowGrowth);
      }
    }
    public String MOS
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.Enhancements.MOS) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.Enhancements.MOS);
      }
    }
    public String MOS80
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.Enhancements.MOS80) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.Enhancements.MOS80);
      }
    }
    public String IntrinsicValue
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.Enhancements.IntrinsicValue) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.Enhancements.IntrinsicValue);
      }
    }
    public String RGVIntrinsic
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.Enhancements.RGVIntrinsic) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.Enhancements.RGVIntrinsic);
      }
    }
    public String IntrinsicValueRevised
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.Enhancements.IntrinsicValueRevised) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.Enhancements.IntrinsicValueRevised);
      }
    }
    public String RGVIntrinsicValueRevised
    {
      get
      {
        return dcfValuation == null || !dcfValuation.Success || double.NaN.Equals(dcfValuation.Enhancements.RGVIntrinsicRevised) ? Constants.CONST_DASHES : Utility.FormatCurrency(dcfValuation.Enhancements.RGVIntrinsicRevised);
      }
    }
    public String Message
    {
      get
      {
        return dcfValuation == null ? Constants.CONST_DASHES : dcfValuation.Message;
      }
    }
    public List<String> Symbols
    {
      get
      {
        return symbols;
      }
    }
    public String SelectedSymbol
    {
      get
      {
        return selectedSymbol;
      }
      set
      {
        if (value == selectedSymbol || String.IsNullOrEmpty(value)) return;
        selectedSymbol = value;
        base.OnPropertyChanged("SelectedSymbol");
      }
    }
    public List<String> WatchListNames
    {
      get
      {
        return watchLists;
      }
      set { ;}
    }
    public String SelectedWatchList
    {
      get { return selectedWatchList; }
      set { selectedWatchList = value; base.OnPropertyChanged("SelectedWatchList"); }
    }
// ************************************************************************************************************************************************************************************************************************************************
// ************************************************************************************************ T O O L  T I P  C A L L O U T S  **************************************************************************************************************
// ************************************************************************************************************************************************************************************************************************************************
    public String HistoricalMarketReturnDescription
    {
      get
      {
        try
        {
          StringBuilder sb=new StringBuilder();
          if(dcfValuation.UseMarketReturn)sb.Append("Using a calculated market return of ").Append(Utility.FormatPercent(dcfValuation.MarketReturn,2));
          else sb.Append("Using a constant market return of ").Append(Utility.FormatPercent(dcfValuation.MarketReturn,2)); 
          return sb.ToString();
        }
        catch(Exception)
        {
          return Constants.NA; 
        }
      }
    }
    public String BetaDescription
    {
      get
      {
        try
        {
          StringBuilder sb=new StringBuilder();
          sb.Append("Beta is a measure of a stock's volatility in relation to the overall market. By definition, the market, such as the S&P 500 Index, has a beta of 1.0, and individual stocks are ranked according to how").Append("\n");
          sb.Append("much they deviate from the market.   A stock that swings more than the market has a beta above 1.0. If a stock moves less than the market, the stock's beta is less than 1.0. ").Append("\n");
          sb.Append("High-beta stocks are supposed to be riskier but provide higher return potential; low-beta stocks pose less risk but also lower returns. ").Append("\n");
          sb.Append("Beta = 36 month internally calculated beta.").Append("\n");
          sb.Append("Beta = Covariance(Ra,Rm)/Variance(Ra).  Where Rm = Return of the market (SPY), Ra = Return of the asset.").Append("\n");
          sb.Append(dcfValuation.Symbol).Append(" has a Beta of ").Append(Utility.FormatNumber(dcfValuation.Beta,2)).Append(" which is ").Append(dcfValuation.Beta>1?"more volatile ":"less volatile ").Append("than the market.").Append("\n");
          sb.Append(dcfValuation.Symbol).Append(" offers ").Append(dcfValuation.Beta>1?"more risk but more return potential ":"less risk but less return potential ").Append("than the market.").Append("\n");
          return sb.ToString();
        }
        catch(Exception)
        {
          return Constants.NA;
        }
      }
    }
    public String InterestExpenseDescription
    {
      get
      {
        return "Interest Expense (Annual): This is sourced from Historical(M*) as 'InterestExpense' if available otherwise from the IncomeStatement as 'InterestExpense'";
      }
    }
    public String CostOfEquityDescription
    {
      get
      {
        try
        {
          StringBuilder sb=new StringBuilder();
          sb.Append("Cost of equity is the return that a company requires for an investment or project, or the return that an individual requires for an equity investment.").Append("\n");
          sb.Append("Cost of Equity: Using CAPM cost of equity is calculated as rE = RFR + Beta * (Rm - RFR).  Where RFR=Risk Free Rate, Beta=Market Beta, Rm=Annual Return.").Append("\n");
          sb.Append("rE = ").Append(Utility.FormatNumber(dcfValuation.RiskFreeRate,2)).Append(" + ");
          sb.Append(Utility.FormatNumber(dcfValuation.Beta,2)).Append(" * ").Append("(");
          sb.Append(Utility.FormatNumber(dcfValuation.MarketReturn)).Append(" - ").Append(Utility.FormatNumber(dcfValuation.RiskFreeRate,2)).Append(")");
          if(dcfValuation.UseMarketReturn)sb.Append("Using a calculated market return of ").Append(Utility.FormatNumber(dcfValuation.MarketReturn,2));
          else sb.Append("Using a constant market return of ").Append(Utility.FormatNumber(dcfValuation.MarketReturn,2)); 
          return sb.ToString();
        }
        catch(Exception)
        {
          return Constants.NA;
        }
      }
    }
    public String CostOfDebtDescription
    {
      get
      {
        try
        {
          StringBuilder sb=new StringBuilder();
          sb.Append("Cost of debt is the effective interest rate that a company pays on its debts, such as bonds and loans.").Append("\n");
          sb.Append("Cost of Debt rD = ( Ei / D) * (1 - Tc).").Append("Where Ei = Interest Expense,  D = Total Debt, Tc = Tax Rate.").Append("\n");
          sb.Append("rD = ").Append(Utility.FormatNumber(dcfValuation.InterestExpense,2,true)).Append(" / ").Append(Utility.FormatNumber(dcfValuation.TotalDebt,2,true)).Append(")");
          sb.Append(" * ").Append("(").Append(Utility.FormatNumber(1,2)).Append(" - ").Append(Utility.FormatNumber(dcfValuation.CorporateTaxRate,2)).Append(")");
          return sb.ToString();
        }
        catch(Exception)
        {
          return Constants.NA;
        }
      }
    }
    public String RiskFreeRateDescription
    {
      get
      {
        return "Current yield on 90 day (3M) Treasury.  This can be verified by going to the \"Treasury Yield Curve\" tab and looking at the current 3M value.";
      }
    }
    public String ROICDescription
    {
      get
      {
        StringBuilder sb=new StringBuilder();
        sb.Append("Return on Invested Capital.  Sourced from historical time series").Append("\n");
        sb.Append(@"Return on Invested Capital (ROIC) is a return ratio that expresses recurring operating profits as a percentage of the company's net operational assets ").Append("\n");
        sb.Append("The profit figure used is earnings before interest and taxes or EBIT and is unaffected by capital structure.").Append("\n");
        return sb.ToString();
      }
    }
    public String WACCDescription
    {
      get
      {
        try
        {
          StringBuilder sb=new StringBuilder();
          sb.Append("Weighted average cost of capital (WACC) represents a firm’s average after-tax cost of capital from all sources, including common stock, preferred stock, bonds, and other forms of debt.").Append("\n");
          sb.Append("WACC is the average rate that a company expects to pay to finance its assets.").Append("\n");
          sb.Append("WACC is a common way to determine required rate of return (RRR) because it expresses, in a single number, the return that both bondholders and shareholders demand to provide the company with capital").Append("\n");
          sb.Append("WACC = rE * (E / V) + rD * (1 - Tc) * (D / V) .").Append("\n");
          sb.Append("Where rE = Cost of Equity, E = Total Equity, V = Total Capital Invested, rD = Cost of Debt, Tc = Tax Rate, D = Total Debt").Append("\n");
          sb.Append(Utility.FormatNumber(dcfValuation.CostOfEquity,2,true)).Append(" * " ).Append("(").Append(Utility.FormatNumber(dcfValuation.MarketValueOfEquity,2,true)).Append(" / ").Append(Utility.FormatNumber(dcfValuation.TotalCapitalInvested,2,true)).Append(")");
          sb.Append(" + ");
          sb.Append("(");
          sb.Append(Utility.FormatNumber(dcfValuation.CostOfDebt,2,true)).Append(" * ").Append("(").Append(Utility.FormatNumber(dcfValuation.MarketValueOfDebt,2,true)).Append(" / ").Append(Utility.FormatNumber(dcfValuation.TotalCapitalInvested,2,true)).Append(")");
          sb.Append(" * ").Append("(").Append(Utility.FormatNumber(1,2)).Append(" - ").Append(Utility.FormatNumber(dcfValuation.CorporateTaxRate,2)).Append(")");
          sb.Append(")");
          sb.Append("\n");
          return sb.ToString();
        }
        catch(Exception)
        {
          return Constants.NA;
        }
      }
    }
    public String TotalCapitalInvestedDescription
    {
      get
      {
        StringBuilder sb=new StringBuilder();
        sb.Append("Total Capital Invested : ");
        sb.Append("V = MV(D) + MV(E) Where MV(D) = Market value of debt, MV(E) = Market value of equity.").Append("\n");
        sb.Append("Market value of debt is sourced from Fundamentals").Append("\n");
        sb.Append("Market value of equity is sourced from Fundamentals").Append("\n");
        return sb.ToString();
      }
    }
    public String EstimatedStockPriceDescription
    {
      get
      {
        StringBuilder sb=new StringBuilder();
        sb.Append("Estimated Stock Price : This is the sum of the discounted cashflows minus debt; then divided by outstanding shares.").Append("\n");
        sb.Append("Estimated Stock Price = (Present Value - Debt) / Outstanding Shares.").Append("\n");
        sb.Append("(").Append(Utility.FormatNumber(dcfValuation.PresentValue,2,true)).Append(" - ").Append(Utility.FormatNumber(dcfValuation.TotalDebt,2,true)).Append(")").Append(" / ").Append(Utility.FormatNumber(dcfValuation.OutstandingShares,2,true)).Append("\n");
        sb.Append("Please refer to Debt and Oustanding Shares to see the source of those values").Append("\n");
        return sb.ToString();
      }
    }
    public String TotalLongAndShortTermDebtDescription
    {
      get{return "Total Long and Short Term Debt : This value if sourced from Fundamentals as TotalDebt";}
    }
    public String TotalEquityDescription
    {
      get{return "Total Equity : This value if sourced from Fundamentals as MarketCap";}
    }
    public String OutstandingSharesDescription
    {
      get{return "Outstanding Shares : This is sourced from Fundamentals as SharesOutstanding";}
    }
    public String MOSDescription
    {
      get{return "Est. Stock Price *.5";}
    }
    public String MOS80Description
    {
      get{return "Est. Stock Price *.8";}
    }
    public String SumOfDiscountedCashflowsDescription
    {
      get{return "Sum of discounted cashflows.  This is also known as the PresentValue.";}
    }
    public String LatestPriceDescription
    {
      get{return "Latest closing price in database.";}
    }
    public String PriceDateDescription
    {
      get{return "Date of latest closing price in database.";}
    }
    public String IntrinsicValueDescription
    {
      get{return "Benjamin Graham : EPS*(8.5+(2*EPSGrowth))";}
    }
    public String IntrinsicValueRevisedDescription
    {
      get{return "Benjamin Graham : (EPS*(8.5+(2*EPSGrowth))+4.4) / Yield on 20-year AAA bonds.";}
    }
    public String RGVIntrinsicRevDescription
    {
      get{return "Intrinsic Value Rev./ Last closing price.";}
    }
    public String FreeCashflowGrowthDescription
    {
      get{return "Mean of freecashflow returns.";}
    }
  }
}

