using C1.Xaml.Chart;
using System;
using System.Collections.Generic;
using System.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Shapes;

namespace ControlExplorer.Controls.Chart
{
    public partial class PopupLabels : UserControl, IExposeApplicationBarItems
    {
        AppBarButton btnStacked = new AppBarButton { Icon = new BitmapIcon { UriSource = new Uri("ms-appx:///Resources/AppBar/layers.png") } };
        Dictionary<string, Popup> lbls = new Dictionary<string, Popup>();

        public PopupLabels()
        {
            InitializeComponent();

            btnStacked.Label = "Stacked";
            btnStacked.Click += btnStacked_Click;

            // hide all grid lines
            c1Chart1.View.AxisX.MajorGridStrokeThickness = 0;
            c1Chart1.View.AxisX.MinorGridStrokeThickness = 0;
            //c1Chart1.View.AxisX.Scale = 0.6;
            //c1Chart1.Actions.Add(new TranslateAction());
            ((System.ComponentModel.INotifyPropertyChanged)c1Chart1.View.AxisX).PropertyChanged +=
              (s, e) =>
              {
                  if (e.PropertyName == "Value")
                      UpdateLabels();
              };

            // hide all tick marks
            c1Chart1.View.AxisX.MajorTickThickness = 0;
            c1Chart1.View.AxisX.MinorTickThickness = 0;
            c1Chart1.View.AxisY.MajorTickThickness = 0;
            c1Chart1.View.AxisY.MinorTickThickness = 0;

            // hide actual grid line
            c1Chart1.View.AxisY.AxisLine = new Line() { StrokeThickness = 0 };

            // add data




            //<c1:DataSeries Label="s1" Values="12, 16, 20, 24, 20, 16, 12" PlotElementLoaded="DataSeries_PlotElementLoaded" />
            //        <c1:DataSeries Label="s2" Values="8, 12, 10, 17, 10, 12, 8" PlotElementLoaded="DataSeries_PlotElementLoaded"/>
            DataSeries ds1 = new DataSeries();
            ds1.Label = "s1";
            ds1.Values = new Windows.UI.Xaml.Media.DoubleCollection();
            ds1.Values.Add(12);
            ds1.Values.Add(16);
            ds1.Values.Add(20);
            ds1.Values.Add(16);
            ds1.PlotElementLoaded += ds1_PlotElementLoaded;
            DataSeries ds2 = new DataSeries();
            ds2.Label = "s2";
            ds2.Values = new Windows.UI.Xaml.Media.DoubleCollection();
            ds2.Values.Add(8);
            ds2.Values.Add(12);
            ds2.Values.Add(14);
            ds2.Values.Add(10);
            ds2.PlotElementLoaded += ds1_PlotElementLoaded;
            c1Chart1.Data.Children.Add(ds1);
            c1Chart1.Data.Children.Add(ds2);

            this.Unloaded += new RoutedEventHandler(PopupLabels_Unloaded);
        }

        void btnStacked_Click(object sender, RoutedEventArgs e)
        {
            c1Chart1.ChartType = c1Chart1.ChartType == ChartType.Column ? ChartType.ColumnStacked : ChartType.Column;
            HideLabels();
        }

        void ds1_PlotElementLoaded(object sender, EventArgs e)
        {
            PlotElement pe = sender as PlotElement;
            if (pe != null)
            {
                pe.Tapped += pe_MouseLeftButtonUp;
                pe.Tapped += OnPlotElementTapped;
            }
        }

        void HideLabels()
        {
            foreach (var popup in lbls.Values)
            {
                popup.IsOpen = false;
            }
        }

        void UpdateLabels()
        {
            foreach (var popup in lbls.Values)
            {
                var child = popup.Child as FrameworkElement;
                var dp = child.DataContext as DataPoint;

                var pr = c1Chart1.View.PlotRect;

                var pt = c1Chart1.View.DataIndexToPoint(dp.SeriesIndex, dp.PointIndex);
                if (pt.X >= pr.Right || pt.X <= pr.Left)
                    child.Visibility = Visibility.Collapsed;
                else
                    child.Visibility = Visibility.Visible;

                popup.HorizontalOffset = pt.X - 0.5 * child.Width;
                if (popup.HorizontalOffset < pr.Left)
                    popup.HorizontalOffset = pr.Left;
                if (popup.HorizontalOffset + child.Width > pr.Right)
                    popup.HorizontalOffset = pr.Right - child.Width;
                popup.UpdateLayout();
            }
        }

        void PopupLabels_Unloaded(object sender, RoutedEventArgs e)
        {
            HideLabels();
        } 

        void pe_MouseLeftButtonUp(object sender, TappedRoutedEventArgs e)
        {
            PlotElement pe = sender as PlotElement;
            if (pe != null && IsPopup)
            {
                // initialize popup content
                // popup child must have explicit width set on UserControl!
                Popup popup = null;

                string key = "s" + pe.DataPoint.SeriesIndex + "p" + pe.DataPoint.PointIndex;
                if (lbls.Keys.Contains(key))
                    popup = lbls[key];
                else
                    lbls[key] = popup = new Popup();

                Interaction.PopupContent child = new Interaction.PopupContent();
                child.DataContext = pe.DataPoint;
                popup.Child = child;

                // declare local variables
                double y = e.GetPosition(c1Chart1).Y;
                double x = e.GetPosition(c1Chart1).X;
                double plotLeft = pe.PlotRect.Left;
                double plotTop = pe.PlotRect.Top;
                double plotBottom = pe.PlotRect.Bottom;
                double plotRight = pe.PlotRect.Right;
                double popupOffset = child.Width / 2;

                // set horizontal offset
                if (popupOffset > Math.Abs(x - plotLeft))
                {
                    // too far to the left
                    popup.HorizontalOffset = plotLeft;
                }
                else if (popupOffset > Math.Abs(x - plotRight))
                {
                    // too far to the right
                    popup.HorizontalOffset = plotRight - child.Width;
                }
                else
                {
                    popup.HorizontalOffset = e.GetPosition(c1Chart1).X - popupOffset;
                }


                // set vertical offset
                popup.VerticalOffset = e.GetPosition(LayoutRoot).Y - 50;
                if (popup.VerticalOffset < 0)
                    popup.VerticalOffset = 0;


                popup.IsOpen = true;
                popup.UpdateLayout();
            }
            IsPopup = false;
        }

        bool IsPopup = true;
        void OnPlotElementTapped(object sender, TappedRoutedEventArgs e)
        {
            IsPopup = true;
        }

        #region IExposeApplicationBarItems Members

        public IEnumerable<ICommandBarElement> ApplicationBarItems
        {
            get
            {
                yield return btnStacked;
            }
        }

        #endregion
    }
}
