using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Controls;
using C1.WPF.C1Chart;
using System.Windows;
using System.ComponentModel;

namespace Chart_AlarmZones_WPF_CS
{
    public class AlarmZone : XYDataSeries
    {
        #region "constructor"
        public AlarmZone()
        {
            this.LayoutUpdated += new EventHandler(AlarmZone_LayoutUpdated);
            this.ChartType = C1.WPF.C1Chart.ChartType.PolygonFilled;
            this.XValues = new DoubleCollection();
            this.Values = new DoubleCollection();
            this.Opacity = 0.5;
            UpdateLegend();
            Update();
        }
        #endregion

        public static readonly DependencyProperty NearProperty = DependencyProperty.Register("Near", typeof(double?), typeof(AlarmZone), new FrameworkPropertyMetadata(null,
            new PropertyChangedCallback((d, e) =>
            {
                (d as AlarmZone).Update();
            })));
        public static readonly DependencyProperty FarProperty = DependencyProperty.Register("Far", typeof(double?), typeof(AlarmZone), new FrameworkPropertyMetadata(null,
            new PropertyChangedCallback((d, e) =>
            {
                (d as AlarmZone).Update();
            })));
        public static readonly DependencyProperty LowExtentProperty = DependencyProperty.Register("LowExtent", typeof(double?), typeof(AlarmZone), new FrameworkPropertyMetadata(null,
        new PropertyChangedCallback((d, e) =>
            {
            (d as AlarmZone).Update();
        })));
        public static readonly DependencyProperty UpperExtentProperty = DependencyProperty.Register("UpperExtent", typeof(double?), typeof(AlarmZone), new FrameworkPropertyMetadata(null,
        new PropertyChangedCallback((d, e) =>
            {
            (d as AlarmZone).Update();
        })));

        #region "members"
        private C1Chart _chart;
        public C1Chart Chart
        {
            get { return _chart; }
            set { _chart = value; }
        }
        [Bindable(true)]
        public double? Near
        {
            get { return (double?)this.GetValue(NearProperty); }
            set 
            {
                this.SetValue(NearProperty, value);
            }
        }
        [Bindable(true)]
        public double? Far
        {
            get { return (double?)this.GetValue(FarProperty); }
            set
            {
                this.SetValue(FarProperty, value);
            }
        }
        [Bindable(true)]
        public double? LowExtent
        {
            get { return (double?)this.GetValue(LowExtentProperty); }
            set
            {
                this.SetValue(LowExtentProperty, value);
            }
        }
        [Bindable(true)]
        public double? UpperExtent
        {
            get { return (double?)this.GetValue(UpperExtentProperty); }
            set
            {
                this.SetValue(UpperExtentProperty, value);
            }
        }

        private bool _showInLegend = false;
        public bool ShowInLegend
        {
            get { return _showInLegend; }
            set
            {
                _showInLegend = value;
                UpdateLegend();
            }
        }
        #endregion

        #region "implementation"
        public void Update()
        {
            double? _near = Near, _far = Far;
            if (_near != null && _far != null)
            {
                this.XValues.Clear();
                this.XValues.Add((double)_near);
                this.XValues.Add((double)_far);
                this.XValues.Add((double)_far);
                this.XValues.Add((double)_near);
            }

            double? _lowExtent = LowExtent, _upperExtent = UpperExtent;
            if (_lowExtent != null && _upperExtent != null)
            {
                this.Values.Clear();
                this.Values.Add((double)_lowExtent);
                this.Values.Add((double)_lowExtent);
                this.Values.Add((double)_upperExtent);
                this.Values.Add((double)_upperExtent);
            }
        }

        public void UpdateLegend()
        {
            if (_showInLegend)
            {
                this.Display = SeriesDisplay.SkipNaN;
            }
            else
            {
                this.Display = SeriesDisplay.HideLegend;
            }
        }

        private void chart_LayoutUpdated(object sender, EventArgs e)
        {
            if (this.Chart != null)
            {
                if (this.Chart.View != null)
                {
                    if (Near == null)
                    {
                        Near = Chart.View.AxisX.ActualMin;
                        Update();
                    }
                    if (Far == null)
                    {
                        Far = Chart.View.AxisX.ActualMax;
                        Update();
                    }
                    //if (LowExtent == null)
                    //{
                    //    LowExtent = Chart.View.AxisY.ActualMin;
                    //    Update();
                    //}
                    //if (UpperExtent == null)
                    //{
                    //    UpperExtent = Chart.View.AxisY.ActualMax;
                    //    Update();
                    //}
                }
            }
        }

        // obtains the parent chart control so we can later get axis bounds
        void AlarmZone_LayoutUpdated(object sender, EventArgs e)
        {
            if (this.Parent != null && this.Chart == null)
            {
                Canvas c = this.Parent as Canvas;
                if (c != null)
                {
                    Canvas cv = c.Parent as Canvas;
                    if (cv != null)
                    {
                        Border b = cv.Parent as Border;
                        if (b != null)
                        {
                            Grid g = b.Parent as Grid;
                            if (g != null)
                            {
                                C1Chart chart = g.Parent as C1Chart;
                                if (chart != null)
                                {
                                    this.Chart = chart;
                                    this.Chart.LayoutUpdated += chart_LayoutUpdated;
                                }
                            }
                        }
                    }
                }
            }
        }
        #endregion
    }
}