using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Navigation;
using System.Windows.Shapes;
using System.Net;

using FLY.Thick.Base.Client;
using System.Windows.Forms.DataVisualization.Charting;
using System.Drawing;

namespace ThickTcpUiInWindow
{
    /// <summary>
    /// Page_BorderSearch.xaml 的交互逻辑
    /// </summary>
    public partial class Page_BorderSearch : Page
    {
        #region 延时推送 MARKNO
        const int MARKNO_UPDATE_BORDER = 0;
        const int MARKNO_UPDATE_DATAS = 1;
        #endregion

        BorderSearchServiceClient mBorderSearchService;
        InitParamServiceClient mInitParamService;

        public Page_BorderSearch()
        {
            InitializeComponent();
            InitializeChart();
        }
        void InitializeChart()
        {
            System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
            System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
            System.Windows.Forms.DataVisualization.Charting.Series series_datas = new System.Windows.Forms.DataVisualization.Charting.Series();
            System.Windows.Forms.DataVisualization.Charting.Series series_border_forw = new System.Windows.Forms.DataVisualization.Charting.Series();
            System.Windows.Forms.DataVisualization.Charting.Series series_border_backw = new System.Windows.Forms.DataVisualization.Charting.Series();

            // 
            // chart1
            // 
            //this.chart1.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(211)), ((System.Byte)(223)), ((System.Byte)(240)));
            //this.chart1.BackSecondaryColor = System.Drawing.Color.White;
            //this.chart1.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.TopBottom;
            //this.chart1.BorderlineColor = System.Drawing.Color.FromArgb(((System.Byte)(26)), ((System.Byte)(59)), ((System.Byte)(105)));
            //this.chart1.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
            //this.chart1.BorderlineWidth = 2;
            //this.chart1.BorderSkin.SkinStyle = System.Windows.Forms.DataVisualization.Charting.BorderSkinStyle.Emboss;
            #region chartArea
            #region chartArea1

            chartArea1.Name = "chartArea1";

            chartArea1.AxisX.IsLabelAutoFit = false;
            chartArea1.AxisX.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);
            //chartArea1.AxisX.LabelStyle.IsEndLabelVisible = false;
            chartArea1.AxisX.LineColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)));
            chartArea1.AxisX.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)));
            chartArea1.AxisX.Title = "位置(脉冲)";

            chartArea1.AxisY.IsLabelAutoFit = false;
            chartArea1.AxisY.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);
            chartArea1.AxisY.LineColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)));
            chartArea1.AxisY.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)));
            chartArea1.AxisY.Title = "AD值";
            //chartArea1.AxisY.IsStartedFromZero = false;

            chartArea1.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(165)), ((System.Byte)(191)), ((System.Byte)(228)));
            chartArea1.BackSecondaryColor = System.Drawing.Color.White;
            chartArea1.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.TopBottom;
            chartArea1.BorderColor = System.Drawing.Color.FromArgb(((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)), ((System.Byte)(64)));
            chartArea1.BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;

            chartArea1.CursorX.IsUserEnabled = true;
            chartArea1.CursorX.IsUserSelectionEnabled = true;
            chartArea1.CursorX.SelectionColor = System.Drawing.SystemColors.Highlight;

            chartArea1.CursorY.IsUserEnabled = true;
            chartArea1.CursorY.IsUserSelectionEnabled = true;
            chartArea1.CursorY.SelectionColor = System.Drawing.SystemColors.Highlight;
            
            chartArea1.Position.Auto = true;
            chartArea1.ShadowColor = System.Drawing.Color.Transparent;

            #endregion

            this.chart1.ChartAreas.Add(chartArea1);
            #endregion

            #region legend
            legend1.Name = "legend1";

            legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Right;
            legend1.Alignment = System.Drawing.StringAlignment.Far;
            legend1.LegendStyle = LegendStyle.Column;
            legend1.IsDockedInsideChartArea = true;
            legend1.DockedToChartArea = chartArea1.Name;

            legend1.IsTextAutoFit = false;
            legend1.BackColor = System.Drawing.Color.Transparent;
            legend1.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);
            legend1.Position.Auto = true;
            chart1.Legends.Add(legend1);
            #endregion

            #region series
            series_datas.Name = "series_datas";
            series_datas.BorderColor = System.Drawing.Color.FromArgb(((System.Byte)(180)), ((System.Byte)(26)), ((System.Byte)(59)), ((System.Byte)(105)));
            series_datas.BorderWidth = 2;
            series_datas.ChartArea = chartArea1.Name;
            series_datas.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
            series_datas.Color = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(65)))), ((int)(((byte)(140)))), ((int)(((byte)(240)))));
            
            series_datas.LegendText = "AD数据";
            series_datas.IsVisibleInLegend = true;
            series_datas.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
            series_datas.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;

            series_datas.ShadowColor = System.Drawing.Color.Black;
            series_datas.ShadowOffset = 2;


            series_border_forw.Name = "series_border_forw";
            series_border_forw.LegendText = "正向边界点";
            series_border_forw.ChartArea = chartArea1.Name;
            series_border_forw.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
            series_border_forw.Color = System.Drawing.Color.Green;
            series_border_forw.BorderColor = System.Drawing.Color.DarkGreen;
            series_border_forw.BorderWidth = 3;

            series_border_forw.MarkerSize = 6;
            series_border_forw.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
            series_border_forw.MarkerBorderColor = System.Drawing.Color.DarkGreen;
            series_border_forw.MarkerColor = System.Drawing.Color.Green;

            series_border_forw.ShadowColor = System.Drawing.Color.Black;
            series_border_forw.ShadowOffset = 2;


            series_border_backw.Name = "series_border_backw";
            series_border_backw.LegendText = "反向边界点";
            series_border_backw.ChartArea = chartArea1.Name;
            series_border_backw.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
            series_border_backw.Color = System.Drawing.Color.Orange;
            series_border_backw.BorderColor = System.Drawing.Color.DarkOrange;
            series_border_backw.BorderWidth = 3;

            series_border_backw.MarkerSize = 6;
            series_border_backw.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
            series_border_backw.MarkerBorderColor = System.Drawing.Color.Orange;
            series_border_backw.MarkerColor = System.Drawing.Color.DarkOrange;

            series_border_backw.ShadowColor = System.Drawing.Color.Black;
            series_border_backw.ShadowOffset = 2;


            chart1.Series.Add(series_datas);
            chart1.Series.Add(series_border_forw);
            chart1.Series.Add(series_border_backw);
            #endregion

            chart1.Name = "chart1";
            chart1.Palette = System.Windows.Forms.DataVisualization.Charting.ChartColorPalette.BrightPastel;
            //chart1.Location = new System.Drawing.Point(0, 0);

            chart1.PrePaint += Chart1_PrePaint;
        }

        private void Chart1_PrePaint(object sender, ChartPaintEventArgs e)
        {
            if (e.ChartElement is ChartArea)
            {
                ChartArea area = (ChartArea)e.ChartElement;
                if (Double.IsNaN(area.AxisY.Minimum))
                    return;

                //阀值线
                System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 2);

                int threshold = mBorderSearchService.TempAD - mBorderSearchService.TempRange;
                DrawYGridTick(e.ChartGraphics, pen, threshold);
            }
        }

        private void button_apply_Click(object sender, RoutedEventArgs e)
        {
            mBorderSearchService.Apply();
            try
            {
                string title = Application.Current.FindResource("strApplySuccess") as string;
                FLY.ControlLibrary.Window_Tip.Show(title,
                    null,
                    TimeSpan.FromSeconds(2));
            }
            catch
            {

            }
        }

        public void Init(IPEndPoint serverep) 
        {
            mBorderSearchService = new BorderSearchServiceClient(FLY.Thick.Base.OBJ_INTERFACE.OBJ_INTERFACE_ID.BORDERSEARCH_ID);

            mInitParamService = new InitParamServiceClient(FLY.Thick.Base.OBJ_INTERFACE.OBJ_INTERFACE_ID.INITPARAM_ID);


            FObjBase.FObjSys.Current.Connect_to_Another_OBJSys(
                serverep, mBorderSearchService.ID, mInitParamService.ID);

            this.DataContext = mBorderSearchService;

            this.grid_null.DataContext = mInitParamService;

            mBorderSearchService.PropertyChanged += MBorderSearchService_PropertyChanged;
            mBorderSearchService.Border_Forw.PropertyChanged += (s, e) =>
            {
                FObjBase.PollModule.Current.Poll_JustOnce(
                    UpdateBorder, this, MARKNO_UPDATE_BORDER);
            };
            mBorderSearchService.Border_Backw.PropertyChanged += (s, e) =>
            {
                FObjBase.PollModule.Current.Poll_JustOnce(
                    UpdateBorder, this, MARKNO_UPDATE_BORDER);
            };

            mInitParamService.PropertyChanged += MInitParamService_PropertyChanged;
            UpdateX();
        }

        private void MInitParamService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "PosLength")
            {
                UpdateX();
            }
        }

        private void MBorderSearchService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Datas")
            {
                FObjBase.PollModule.Current.Poll_JustOnce(
                    UpdateDatas, this, MARKNO_UPDATE_DATAS);
                FObjBase.PollModule.Current.Poll_JustOnce(
                    UpdateBorder, this, MARKNO_UPDATE_BORDER);
            }
            else if ((e.PropertyName == "TempAD") ||
                (e.PropertyName == "TempRange"))
            {
                chart1.Invalidate();
            }
        }

 
        void DrawYGridTick(ChartGraphics cg, System.Drawing.Pen pen, double y)
        {
            ChartArea area = chart1.ChartAreas[0];

            if (y > area.AxisY.Maximum || y < area.AxisY.Minimum)
                return;

            // Take Graphics object from chart
            Graphics graph = cg.Graphics;

            // Convert X and Y values to screen position
            double py = cg.GetPositionFromAxis(area.Name, AxisName.Y, y);

            double XMin = cg.GetPositionFromAxis(area.Name, AxisName.X, area.AxisX.Minimum);
            double XMax = cg.GetPositionFromAxis(area.Name, AxisName.X, area.AxisX.Maximum);

            System.Drawing.PointF[] points = new System.Drawing.PointF[2];
            points[0].X = (float)XMin;
            points[1].X = (float)XMax;
            points[0].Y = points[1].Y = (float)py;

            // Convert relative coordinates to absolute coordinates.
            points[0] = cg.GetAbsolutePoint(points[0]);
            points[1] = cg.GetAbsolutePoint(points[1]);

            graph.DrawLine(pen, points[0], points[1]);

        }
        void UpdateY()
        {
            int[] grid = mBorderSearchService.Datas;
            if (grid == null)
                return;

            int max = Misc.MyMath.Max(grid);
            int min = Misc.MyMath.Min(grid);
            if (Misc.MyBase.ISVALIDATA(max))
            {
                if (max != min)
                {
                    chart1.ChartAreas[0].AxisY.Maximum = max + (max - min) * 0.1;
                    chart1.ChartAreas[0].AxisY.Minimum = min - (max - min) * 0.1;
                    if (chart1.ChartAreas[0].AxisY.Minimum < 0)
                        chart1.ChartAreas[0].AxisY.Minimum = 0;
                }
                else
                {
                    chart1.ChartAreas[0].AxisY.Minimum = 0;
                    chart1.ChartAreas[0].AxisY.Maximum = 60000;
                }
            }
            else
            {
                chart1.ChartAreas[0].AxisY.Minimum = 0;
                chart1.ChartAreas[0].AxisY.Maximum = 60000;
            }

            if (chart1.ChartAreas[0].AxisY.Minimum == chart1.ChartAreas[0].AxisY.Maximum)
            {
                chart1.ChartAreas[0].AxisY.Minimum -= 1000;
                chart1.ChartAreas[0].AxisY.Maximum += 1000;
            }
        }
        void UpdateX()
        {
            chart1.ChartAreas[0].AxisX.Minimum = 0;
            chart1.ChartAreas[0].AxisX.Maximum = mInitParamService.PosLength;
        }
        void UpdateDatas()
        {
            System.Windows.Forms.DataVisualization.Charting.Series series = chart1.Series["series_datas"];

            series.Points.Clear();

            int[] grid = mBorderSearchService.Datas;
            if (grid == null)
                return;
            int posOfGrid = mInitParamService.PosOfGrid;
            
            for (int i = 0; i < grid.Length; i++)
            {
                series.Points.AddXY(i * posOfGrid, grid[i]);
                if (!Misc.MyBase.ISVALIDATA(grid[i]))
                {
                    series.Points[i].IsEmpty = true;
                }
            }
            UpdateY();
        }


        #region 更新边界
        bool UpdateBorder_pos(
            System.Windows.Forms.DataVisualization.Charting.Series series,
            int pos)
        {
            int[] grid = mBorderSearchService.Datas;
            if (grid == null)
                return false;

            int posOfGrid = mInitParamService.PosOfGrid;
            
            int grid_idx = pos / posOfGrid;
            if (grid_idx < 0)
                return false;
            if (grid_idx >= grid.Length)
                return false;

            int d = grid[grid_idx];
            if (!Misc.MyBase.ISVALIDATA(d))
                return false;

            series.Points.AddXY(pos, d);
            return true;
        }


        void UpdateBorder(System.Windows.Forms.DataVisualization.Charting.Series series, Misc.Range border)
        {
            series.Points.Clear();
            if (!border.IsValid)
                return;
            if (!UpdateBorder_pos(series, border.Begin))
                return;

            if (!UpdateBorder_pos(series, border.End))
                return;
        }

        void UpdateBorder()
        {
            UpdateBorder(chart1.Series["series_border_forw"], mBorderSearchService.Border_Forw);
            UpdateBorder(chart1.Series["series_border_backw"], mBorderSearchService.Border_Backw);
            UpdateSensorWidth();
        }

        void UpdateSensorWidth()
        {
            StripLinesCollection stripLines = chart1.ChartAreas[0].AxisX.StripLines;

            stripLines.Clear();

            if (!mBorderSearchService.Border_Forw.IsValid)
                return;

            StripLine stripline = new StripLine();
            stripline.BackColor = System.Drawing.Color.FromArgb(64, System.Drawing.Color.Green);
            stripline.Interval = 0;
            stripline.IntervalOffset = mBorderSearchService.Border_Forw.Begin;
            stripline.StripWidth = mBorderSearchService.SensorWidth;
            stripLines.Add(stripline);

            stripline = new StripLine();
            stripline.BackColor = System.Drawing.Color.FromArgb(64, System.Drawing.Color.Green);
            stripline.Interval = 0;
            stripline.IntervalOffset = mBorderSearchService.Border_Forw.End - mBorderSearchService.SensorWidth;
            stripline.StripWidth = mBorderSearchService.SensorWidth;
            stripLines.Add(stripline);
        }

        #endregion

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {

        }

        private void Page_Unloaded(object sender, RoutedEventArgs e)
        {
            mBorderSearchService.Dispose();
            mInitParamService.Dispose();
        }
    }
}
