using System;
using System.Windows;
using System.Text;
using System.Windows.Controls;
using System.Windows.Threading;
using System.IO;
using Microsoft.Win32;
using Microsoft.Research.DynamicDataDisplay.Charts.Navigation;
using Telerik.Windows.Controls;
using Microsoft.Research.DynamicDataDisplay;
using System.Collections.ObjectModel;
using TradeBlotter.ViewModels;
using System.Windows.Data;
using System.Reflection;
using System.Collections.Generic;
using MarketData.MarketDataModel;

namespace TradeBlotter.UIUtils
{
  public class NameMultiValueConverter : IMultiValueConverter
  {
     public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
     {
         return String.Format("{0}:{1}", values[0], values[1]);
     }
     public object[] ConvertBack(object value,Type[] targetType, object parameter, System.Globalization.CultureInfo culture)
     {
         return null;
     }
  }
// ******************************************************************************************************************************
// ********************************************** G R I D   B E H A V I O R S ***********************************
// ******************************************************************************************************************************
// This attached behavior is used to initiate the re-calculation of all aggregates which radgridview does not do by default
  public class GridDataChangeBehavior
  {
    public static readonly DependencyProperty GridDataChangeProperty = DependencyProperty.RegisterAttached("GridDataChangeProperty", typeof(bool), typeof(GridDataChangeBehavior), new FrameworkPropertyMetadata(OnGridDataChangePropertyChanged));
    [AttachedPropertyBrowsableForType(typeof(RadGridView))]
    public static bool GetGridDataChangeProperty(RadGridView radGridView)
    {
      return (bool)radGridView.GetValue(GridDataChangeProperty);
    }
    public static void SetGridDataChangeProperty(RadGridView radGridView, bool value)
    {
      radGridView.SetValue(GridDataChangeProperty, value);
    }
    static void OnGridDataChangePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
      RadGridView radGridView = dependencyObject as RadGridView;
      radGridView.CalculateAggregates();
    }
  }
  public class GridExportGraphBehavior
  {
    public static readonly DependencyProperty ExportExcelProperty = DependencyProperty.RegisterAttached("ExportExcelProperty", typeof(String), typeof(GridExportGraphBehavior), new FrameworkPropertyMetadata(OnExportExcelPropertyChanged));
    [AttachedPropertyBrowsableForType(typeof(RadGridView))]
    public static string GetExportExcelProperty(RadGridView radGridView)
    {
      return (string)radGridView.GetValue(ExportExcelProperty);
    }
    public static void SetExportExcelProperty(RadGridView radGridView, string value)
    {
      radGridView.SetValue(ExportExcelProperty, value);
    }
    static void OnExportExcelPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
      RadGridView radGridView = dependencyObject as RadGridView;
      String pathFileName = e.NewValue as String;
      if (null == pathFileName) return;
      Action action = () =>
      {
        SaveFileDialog saveFileDialog = new SaveFileDialog()
        {
          InitialDirectory = Directory.GetCurrentDirectory(),
          Filter = "Excel files (.xls)|*.xls",
          FileName = pathFileName,
        };
        if (false == saveFileDialog.ShowDialog()) return;
        using (Stream stream = saveFileDialog.OpenFile())
        {
          radGridView.Export(stream, new GridViewExportOptions() { Format = ExportFormat.ExcelML, ShowColumnHeaders = true, ShowColumnFooters = true, ShowGroupFooters = true, });
        }
      };
      Dispatcher.CurrentDispatcher.BeginInvoke(action);
    }
  }
// ******************************************************************************************************************************
// *********************************** C H A R T  P L O T T E R  B E H A V I O R***********************************
// ******************************************************************************************************************************
  public class ChartPlotterLegendBehavior
  {
    public static readonly DependencyProperty LegendVisibleProperty = DependencyProperty.RegisterAttached("LegendVisibleProperty", typeof(string), typeof(ChartPlotterLegendBehavior), new FrameworkPropertyMetadata(OnLegendVisiblePropertyChanged));
    [AttachedPropertyBrowsableForType(typeof(ChartPlotter))]
    public static string GetLegendVisibleProperty(ChartPlotter d)
    {
      return (string)d.GetValue(LegendVisibleProperty);
    }
    [AttachedPropertyBrowsableForType(typeof(ChartPlotter))]
    public static void SetLegendVisibleProperty(ChartPlotter d, string value)
    {
      d.SetValue(LegendVisibleProperty, value);
    }
    static void OnLegendVisiblePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
      ChartPlotter chartPlotter = dependencyObject as ChartPlotter;
      if (chartPlotter != null)
      {
        chartPlotter.NewLegendVisible = Boolean.Parse((e.NewValue as String));
      }
    }
  }
// ******************************************************************************************************************************
// *********************************** C O O R D I N A T E  G R A P H  X  T E X T   B E H A V I O R***********************************
// ******************************************************************************************************************************
  public class CoordinateGraphBehavior
  {
    public static readonly DependencyProperty XTextMappingProperty = DependencyProperty.RegisterAttached("XTextMappingProperty", typeof(string), typeof(CoordinateGraphBehavior), new FrameworkPropertyMetadata(OnXTextMappingPropertyChanged));
    public static readonly DependencyProperty YTextMappingProperty = DependencyProperty.RegisterAttached("YTextMappingProperty", typeof(string), typeof(CoordinateGraphBehavior), new FrameworkPropertyMetadata(OnYTextMappingPropertyChanged));
    private static String dateFormat;
    private static String numericFormat;
    [AttachedPropertyBrowsableForType(typeof(CursorCoordinateGraph))]
    public static string GetXTextMappingProperty(CursorCoordinateGraph d)
    {
      return (string)d.GetValue(XTextMappingProperty);
    }
    public static void SetXTextMappingProperty(CursorCoordinateGraph d, string value)
    {
      d.SetValue(XTextMappingProperty, value);
    }
    static void OnXTextMappingPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
      CursorCoordinateGraph cursorCoordinateGraph = dependencyObject as CursorCoordinateGraph;
      dateFormat = e.NewValue as String;
      if (cursorCoordinateGraph != null)
      {
        cursorCoordinateGraph.XTextMapping = XConverter;
      }
    }
    public static String XConverter(double value)
    {
      DateTime dateAxis = new DateTime((long)(value * 10000000000.0));
      return dateAxis.ToString(dateFormat);
    }
    [AttachedPropertyBrowsableForType(typeof(CursorCoordinateGraph))]
    public static string GetYTextMappingProperty(CursorCoordinateGraph d)
    {
      return (string)d.GetValue(YTextMappingProperty);
    }
    public static void SetYTextMappingProperty(CursorCoordinateGraph d, string value)
    {
      d.SetValue(YTextMappingProperty, value);
    }
    static void OnYTextMappingPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
      CursorCoordinateGraph cursorCoordinateGraph = dependencyObject as CursorCoordinateGraph;
      numericFormat = e.NewValue as String;
      if (cursorCoordinateGraph != null)
      {
        cursorCoordinateGraph.YTextMapping = YConverter;
      }
    }
    public static String YConverter(double value)
    {
      StringBuilder sb = new StringBuilder();
      sb.Append("{0:").Append(numericFormat).Append("}");
      return String.Format(sb.ToString(), value);
    }
  }
// ******************************************************************************************************************************
// *************************************************** B R O W S E R  B E H A V I O R********************************************
// ******************************************************************************************************************************
  public class BrowserBehavior
  {
    public static readonly DependencyProperty HtmlProperty = DependencyProperty.RegisterAttached("Html",typeof(string),typeof(BrowserBehavior),new FrameworkPropertyMetadata(OnHtmlChanged));
    [AttachedPropertyBrowsableForType(typeof(WebBrowser))]
    public static string GetHtml(WebBrowser d)
    {
      return (string)d.GetValue(HtmlProperty);
    }
    public static void SetHtml(WebBrowser d, string value)
    {
      d.SetValue(HtmlProperty, value);
    }
    static void OnHtmlChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
      WebBrowser webBrowser = dependencyObject as WebBrowser;
      if (webBrowser != null)
      {
        FieldInfo field = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
        if (null != field)
        {
          object axIWebBrowser2 = field.GetValue(dependencyObject);
          axIWebBrowser2.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, axIWebBrowser2, new object[] { true });
        }        
        webBrowser.NavigateToString(e.NewValue as string);
        webBrowser.AllowDrop = false;

      }
    }
  }
// ******************************************************************************************************************************
// *************************************************** C A L E N D A R  B E H A V I O R ********************************************
// ******************************************************************************************************************************
  public class CalendarBehavior
  {
    public static readonly DependencyProperty RegisterBlackoutDatesProperty = DependencyProperty.RegisterAttached("RegisterBlackoutDates", typeof(System.Collections.Generic.List<System.Windows.Controls.CalendarDateRange>), typeof(CalendarBehavior), new FrameworkPropertyMetadata(OnRegisterCommandBindingChanged));
    [AttachedPropertyBrowsableForType(typeof(Calendar))]
    public static void SetRegisterBlackoutDates(UIElement element, System.Windows.Controls.CalendarBlackoutDatesCollection value)
    {
      if (element != null)element.SetValue(RegisterBlackoutDatesProperty, value);
    }
    public static System.Windows.Controls.CalendarBlackoutDatesCollection GetRegisterBlackoutDates(UIElement element)
    {
      return (element != null ? (System.Windows.Controls.CalendarBlackoutDatesCollection)element.GetValue(RegisterBlackoutDatesProperty) : null);
    }
    private static void OnRegisterCommandBindingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
      System.Windows.Controls.Calendar element = sender as System.Windows.Controls.Calendar;
      if (element != null)
      {
        List<CalendarDateRange> blackoutDates = e.NewValue as List<CalendarDateRange>;
        if (null!=blackoutDates)
        {
          element.BlackoutDates.Clear();
          foreach (CalendarDateRange dateRange in blackoutDates)
          {
            element.BlackoutDates.Add(dateRange);
          }
        }
      }
    }
  }
}