using MarketData.DataAccess;
using MarketData.DividendRiskParity;
using MarketData.MarketDataModel;
using MarketData.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace TradeBlotter.UIUtils
{
  public class ProformaAddRiskDividendParityPositionDialogResult
  {
    public DividendRiskParityPositionCollection DividendRiskParityPositionCollection { get; set; }
    public DividendRiskParityPosition DividendRiskParityPositionProforma { get; set; }
    public bool Success { get; set; }
  }
  public partial class ProformaAddRiskDividendParityPositionDialog : Window
  {
    private List<String> symbols;
    private ManualResetEvent manualResetEvent = new ManualResetEvent(false);
    private DateTime PurchaseDate { get; set; }
    private double PurchasePrice { get; set; }
    private String SelectedSymbol { get; set; }
    private double Exposure { get; set; }
    private double Shares { get; set; }
    private bool Result { get; set; }
    private DividendRiskParityPosition dividendRiskParityPositionProforma = null;

    private ProformaAddRiskDividendParityPositionDialog(String title,String symbol, DateTime purchaseDate, DividendRiskParityPositionCollection dividendRiskParityPositionCollection)
    {
      this.Background = new SolidColorBrush(Colors.AliceBlue);
      this.Owner = Application.Current.MainWindow;
      InitializeComponent();
      this.Loaded += new RoutedEventHandler(AddPositionDialog_Loaded);
      this.Closing += Window_Closing;
      txtPurchasePrice.SelectionChanged += txtPurchasePrice_SelectionChanged;
      txtShares.SelectionChanged += txtShares_SelectionChanged;
      txtExposure.TextChanged += txtExposure_SelectionChanged;
      txtSymbol.SelectionChanged+=txtSymbol_SelectionChanged;
      txtSymbol.Text = symbol;
      SelectedSymbol = symbol;
      Title = title;
      Shares = 0.00;
      Exposure = 0.00;
      if (Utility.IsEpoch(purchaseDate)) PurchaseDate = PricingDA.GetLatestDate();
      else PurchaseDate = purchaseDate;
      Price price = PricingDA.GetPrice(symbol, purchaseDate);
      if (null != price) PurchasePrice = price.Close;
      txtPurchaseDate.Text = purchaseDate.ToShortDateString();
      UpdatePrice();
      txtShares.Text = Utility.FormatNumber(Shares, 3);
      txtPurchaseDate.IsReadOnly = true;
      txtSymbol.IsReadOnly = true;
    }
    public ManualResetEvent Event { get {return manualResetEvent;}}
    public static ProformaAddRiskDividendParityPositionDialogResult Prompt(string title, String account, DateTime effectiveDate, DividendRiskParityPositionCollection dividendRiskParityPositionCollection)
    {
      ProformaAddRiskDividendParityPositionDialogResult proformaAddRiskDividendParityPositionDialogResult = new ProformaAddRiskDividendParityPositionDialogResult();
      proformaAddRiskDividendParityPositionDialogResult.Success = false;
      ProformaAddRiskDividendParityPositionDialog proformaAddRiskDividendParityPositionDialog = new ProformaAddRiskDividendParityPositionDialog(title, account, effectiveDate, dividendRiskParityPositionCollection);
      try { proformaAddRiskDividendParityPositionDialog.ShowDialog(); }
      catch (Exception) { return proformaAddRiskDividendParityPositionDialogResult; }
      proformaAddRiskDividendParityPositionDialog.Event.WaitOne();
      if (proformaAddRiskDividendParityPositionDialog.Result == true)
      {
        DividendRiskParityPosition dividendRiskParityPosition = proformaAddRiskDividendParityPositionDialog.CreatePosition();
        dividendRiskParityPositionCollection.Add(dividendRiskParityPosition);
        proformaAddRiskDividendParityPositionDialogResult.Success = true;
        proformaAddRiskDividendParityPositionDialogResult.DividendRiskParityPositionProforma = proformaAddRiskDividendParityPositionDialog.dividendRiskParityPositionProforma;
      }
      proformaAddRiskDividendParityPositionDialogResult.DividendRiskParityPositionCollection = dividendRiskParityPositionCollection;
      return proformaAddRiskDividendParityPositionDialogResult;
    }


    void AddPositionDialog_Loaded(object sender, RoutedEventArgs e)
    {
        //cbSymbols.Focus();
    }
    public DividendRiskParityPosition CreatePosition()
    {
      try                                                     
      {
        dividendRiskParityPositionProforma = new DividendRiskParityPosition();
        dividendRiskParityPositionProforma.Symbol = SelectedSymbol;
        dividendRiskParityPositionProforma.PurchasePrice = PurchasePrice;
        dividendRiskParityPositionProforma.Shares = Shares;
        dividendRiskParityPositionProforma.TradeDate = PurchaseDate;
        dividendRiskParityPositionProforma.TypeOfPosition = DividendRiskParityPosition.PositionType.Proforma;
        return dividendRiskParityPositionProforma;
      }
      catch (Exception)
      {
        return null;
      }
    }
    private void btnOk_Click(object sender, RoutedEventArgs e)
    {
      Result = Validate();
      Close();
      Event.Set();
      return;
    }
    private void txtPurchasePrice_SelectionChanged(object sender, RoutedEventArgs e)
    {
      double value=0.00;
      value = Utility.ParseCurrency(txtPurchasePrice.Text);
      if (PurchasePrice.Equals(value)) return;
      PurchasePrice = value;
      if (!txtPurchasePrice.IsFocused)
      {
        UpdatePrice();
        UpdateExposure();
      }
      else UpdateExposure();
    }
    private void txtShares_SelectionChanged(object sender, RoutedEventArgs e)
    {
      double value = 0.00;
      double.TryParse(txtShares.Text, out value);
      if (Shares.Equals(value)) return;
      Shares = Math.Round(value,3);
      if (txtShares.IsFocused)
      {
        UpdatePrice();                                                 
        UpdateExposure();
      }
    }
    private void txtSymbol_SelectionChanged(object sender, RoutedEventArgs e)
    {
      //double value = 0.00;
      //double.TryParse(txtShares.Text, out value);
      //if (Shares.Equals(value)) return;
      //Shares = Math.Round(value, 3);
      //if (txtShares.IsFocused)
      //{
      //  UpdatePrice();
      //  UpdateExposure();
      //}
    }
    private void txtExposure_SelectionChanged(object sender, RoutedEventArgs e)
    {
      if (null == txtExposure.Text || "".Equals(txtExposure.Text)) return;
      double value=Utility.ParseCurrency(txtExposure.Text);
      if (0.00 == value || value==Exposure) return;
      txtExposure.Text = Utility.FormatCurrency(value);
      txtExposure.CaretIndex = txtExposure.Text.IndexOf('.');
      if (0.00 == PurchasePrice) return;
      Shares = Math.Round(value / PurchasePrice,3);
      if (txtExposure.IsFocused)
      {
        UpdateShares();
      }
    }
    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
      Event.Set();
    }
    private void btnCancel_Click(object sender, RoutedEventArgs e)
    {
      Result = false;
      Close();
      Event.Set();
    }
    private bool Validate()
    {
      if (null == SelectedSymbol) return false;
      //if(null==Account)return false;
      if(Utility.IsEpoch(PurchaseDate))return false;
      if (double.IsNaN(PurchasePrice)) return false;
      if (0 == Shares) return false;
      return true;
    }
    private void UpdatePrice()
    {
      if (Utility.IsEpoch(PurchaseDate)) return;
      Price price = PricingDA.GetPrice(SelectedSymbol, PurchaseDate);
      if (null == price)
      {
        DateGenerator dateGenerator = new DateGenerator();
        DateTime prevBusinessDate=dateGenerator.FindPrevBusinessDay(PurchaseDate);
        price = PricingDA.GetPrice(SelectedSymbol, prevBusinessDate);
        if (null != price)
        { 
          PurchasePrice = price.Close; 
          PurchaseDate = prevBusinessDate; 
          //dpPurchaseDate.SelectedDate = PurchaseDate; 
          txtPurchaseDate.Text=PurchaseDate.ToShortDateString();
        }
        else PurchasePrice = 0.00;
      }
      else PurchasePrice = price.Close;
      txtPurchasePrice.Text = Utility.FormatCurrency(PurchasePrice);
    }
    private void UpdateExposure()
    {
      Exposure = PurchasePrice * Shares;
      txtExposure.Text = Utility.FormatCurrency(Exposure);
    }
    private void UpdateShares()
    {
      txtShares.Text = Utility.FormatNumber(Shares,3);
    }
    private void UpdateCompanyName()
    {
      CompanyProfile companyProfile = CompanyProfileDA.GetCompanyProfile(SelectedSymbol);
      if (null == companyProfile||null==companyProfile.CompanyName) return;
      lblCompanyName.Content = companyProfile.CompanyName.ToUpper();
    }
  }
}

