using Arction.Wpf.Charting;
using Arction.Wpf.Charting.Axes;
using Arction.Wpf.Charting.SeriesXY;
using Arction.Wpf.Charting.Views.ViewXY;
using Microsoft.Win32;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using ServiceStack;
using StartServerWPF.Assets;
using StartServerWPF.Models;
using StartServerWPF.Modules.MseedChart.Models;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using ZhaoXi.Advanced.MyRedis.Service;

namespace StartServerWPF.Modules.MseedChart.ViewModels
{
    public class ChartPlotRealDataViewModel : BindableBase, INavigationAware
    {

         Mseed2asciiApi.LoopCallbackHandler loopCallback;
        WorkareaModel workarea;
        public ChartPlotRealDataViewModel(SystemConfigModel configModel,WorkareaModel workareaModel, IDialogService dialogService)
        {
            (Application.Current.MainWindow as System.Windows.Window).Closing += ApplicationClosingDispose;
            _dispatcher = Application.Current.Dispatcher;
            IntervalTime =1000;
           loopCallback = new Mseed2asciiApi.LoopCallbackHandler(Mseed2AsciiEvent);
          
           GC.KeepAlive(loopCallback);
            workarea= workareaModel;
            _wavesModel = new WavesModel();
            if (workarea.StationConfig.Stations != null)
            {
                List<string> devicesNums = new List<string>();
                foreach (var item in workarea.StationConfig.Stations)
                {
                    if (item.IsEnable)
                    {
                        devicesNums.Add(item.Name);
                    }
                }
                devicesNums.Sort();
                smList = _wavesModel.ReadWavesFromJson(devicesNums.ToArray());
                subNameList = new Dictionary<string, ASCiiData>();
                CreateChart();
                StartChart();
                Sure();
            }
            this._dialogService = dialogService;
        }

        #region 字段
        System.Timers.Timer time=new System.Timers.Timer(1000);
        Dispatcher _dispatcher;
        public int CurPoints;
        int _channelCount = 0;         
        int _samplingFrequency = 500;  // 采样频率 (Hz).
        WavesModel _wavesModel;
        private int _lChartCount = 1;
        public ConcurrentQueue<StationModel> smList=new ConcurrentQueue<StationModel>();

        public List<AxisY> _chartAxisY=new List<AxisY>();

        //   Dictionary<string, ASCiiData> cacheChartDic=new Dictionary<string, ASCiiData>();
        Dictionary<string, ASCiiData> subNameList;
        #endregion

        #region 属性
        private string _title = "数据中心";
        public string Title
        {
            get { return _title; }
            set
            {
                SetProperty(ref _title, value);
            }
        }
        private bool _IsEnableStartRealtime = true;
        public bool IsEnableStartRealtime
        {
            get { return _IsEnableStartRealtime; }
            set
            {
                SetProperty(ref _IsEnableStartRealtime, value);
            }
        }
        private bool _IsEnableStopRealtime = false;
        public bool IsEnableStopRealtime
        {
            get { return _IsEnableStopRealtime; }
            set
            {
                SetProperty(ref _IsEnableStopRealtime, value);
            }
        }
        private bool _isMultFiles;
        public bool IsMultFiles
        {
            get { return _isMultFiles; }
            set 
            {
                SetProperty(ref _isMultFiles, value);
            }
        }
        private int _xaisInterval;

        public int XaisInterval
        {
            get { return _xaisInterval; }
            set
            {
                SetProperty(ref _xaisInterval, value);
            }
        }
        /// <summary>
        /// 波形控件数量
        /// </summary>
        public int LChartCount
        {
            get { return _lChartCount; }
            set { _lChartCount = value; }
        }
        private LightningChart _lChartAll;
        /// <summary>
        /// 所有波形
        /// </summary>
        public LightningChart LChartALL
        {
            get { return _lChartAll; }
            set { _lChartAll = value; }
        }

        private FrameworkElement childContent;
        public FrameworkElement ChildContent
        {
            get { return childContent; }
            set { SetProperty(ref childContent, value); }
        }

        private StationEventJson _currentEventTime;

        public StationEventJson CurrentEventTime    
        {

            get { return _currentEventTime; }
            set { _currentEventTime = value; }
        }

        private List<StationAxis> _stationsName;

        public List<StationAxis> StationsName
        {
            get { return _stationsName; }
            set {

                SetProperty(ref _stationsName, value);
            }
        }

        private string _currentTime;

        public string CurrentTime
        {
            get { return _currentTime; }
            set {

                SetProperty(ref _currentTime, value);
            }
        }

        private YAxisAutoPlacement _yaxisPlacement;

        public YAxisAutoPlacement YaxisPlacement
        {
            get { return _yaxisPlacement; }
            set
            {
                LChartALL.ViewXY.AxisLayout.YAxisAutoPlacement = value;
                int distancetoX =_wavesModel.SetYasixPlacement(LChartALL);
                foreach (var item in LChartALL.ViewXY.YAxes)
                {
                    item.Title.DistanceToAxis = distancetoX;
                }
                SetProperty(ref _yaxisPlacement, value);
            }
        }

        private int _IntervalTime=1000;

        public int IntervalTime
        {
            get { return _IntervalTime; }
            set 
            {
                if (value >=10)
                {
                 //   time.Interval = value;
                }
                SetProperty(ref _IntervalTime, value);
            }
        }

        
        private int _StationsNumberIndex=3;

        public int StationsNumberIndex
        {
            get { return _StationsNumberIndex; }
            set
            {
                SetProperty(ref _StationsNumberIndex, value);
            }
        }
        
        private bool _SHZChannel=true;
        public bool SHZChannel
        {
            get { return _SHZChannel; }
            set
            {
                SetProperty(ref _SHZChannel, value);
            }
        }

        private bool _SHEChannel = true;
        public bool SHEChannel
        {
            get { return _SHEChannel; }
            set
            {
                SetProperty(ref _SHEChannel, value);
            }
        }
        private bool _SHNChannel = true;
        public bool SHNChannel
        {
            get { return _SHNChannel; }
            set
            {
                SetProperty(ref _SHNChannel, value);
            }
        }


        private double _ChartHeight;
        public double ChartHeight
        {
            get { return _ChartHeight; }
            set
            {
                SetProperty(ref _ChartHeight, value);
            }
        }
        #endregion

        #region 事件
        public DelegateCommand LoadedCommand => new DelegateCommand(Loaded);
        public DelegateCommand UnloadedCommand => new DelegateCommand(UnLoaded);
        public DelegateCommand SureCommand => new DelegateCommand(Sure);
        public DelegateCommand StationSelectCommand => new DelegateCommand(StationSelect);
        public DelegateCommand<object> FileSelectorCommand => new DelegateCommand<object>(FileSelector);
        public DelegateCommand<object> OtimeSortCommand => new DelegateCommand<object>(OtimeSort);
        public DelegateCommand IntervalSureCommand => new DelegateCommand(IntervalSure);
        public DelegateCommand<object> RealTimeDataCommand => new DelegateCommand<object>(RealTimeData);
        
        private void Loaded()
        {
            Mseed2asciiApi.MseedDatasCallFun(loopCallback);
        }

        private void UnLoaded()
        {
            Mseed2asciiApi.MseedDatasCallFun(null);
        }

        private void Sure()
        {
            if (_lChartAll != null)
            {
                _lChartAll.BeginUpdate();
                int index = (StationsNumberIndex == 3) ? _chartAxisY.Count : ((StationsNumberIndex + 1) * 3) * 3;
                _lChartAll.ViewXY.YAxes.Clear();
                for (int i = 0; i < index; i++)
                {
                    _lChartAll.ViewXY.YAxes.Add(_chartAxisY[i]);
                    _lChartAll.ViewXY.SampleDataSeries[i].AssignYAxisIndex = i;
                }
                YasixZENVisible(".Z", SHZChannel);
                YasixZENVisible(".E", SHEChannel);
                YasixZENVisible(".N", SHNChannel);
                _lChartAll.EndUpdate();
            }
        }

        private void StationSelect()
        {
            DialogParameters param = new DialogParameters();
            param.Add("station", workarea.StationConfig.Stations);// 编辑
            _dialogService.ShowDialog("ChartStationDialog"
                , param, ((result)=>
                {
                    var station= result.Parameters.GetValue<List<StationState>>("station");

                    if (station != null)
                    {
                        List<string> devicesNums = new List<string>();
                        foreach (var item in station)
                        {
                            if (item.IsEnable)
                            {
                                devicesNums.Add(item.Name);
                            }
                        }
                        devicesNums.Sort();
                        smList = _wavesModel.ReadWavesFromJson(devicesNums.ToArray());
                        subNameList = new Dictionary<string, ASCiiData>();
                        _dispatcher.Invoke(new Action(() =>
                        {
                            //  CreateChart();
                            StartChart();
                            Sure();
                        }));
                    }

                }));
        }
        private void FileSelector(object obj)
        {
            IsMultFiles = Convert.ToBoolean(obj);
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                RestoreDirectory = true,
                Filter = ".mseed|*.mseed|.json|*.json|.txt|*.txt",
            };
            if (openFileDialog.ShowDialog() == true)
            {
                string asciiSavePath = openFileDialog.FileName.Replace("Mseed", "Txt");
                asciiSavePath = Path.ChangeExtension(asciiSavePath, ".txt");
                string JsonPath = Path.ChangeExtension(openFileDialog.FileName, "Json");
                Stopwatch st = new Stopwatch();
                st.Start();
                //读取.json文件
                CurrentEventTime = _wavesModel.ReadChartJsonFile(JsonPath);
                //读取.mseed文件
                smList = _wavesModel.ReadMseedFile(openFileDialog.FileName, asciiSavePath, IsMultFiles);
                _channelCount = smList.Count * 3;
                CurrentTime = smList.First().BeginTime.ToShortDateString();
                StationsName = smList.Select(a => new StationAxis{Name= a.Name,IsChecked=true,SelectCommand =new DelegateCommand<object>(StationsNameVisible)}).ToList();
                StartChart();
                st.Stop();
                Debug.WriteLine("统计时间StartChart************：{0}", st.Elapsed);
                FeedDatasToChart();
                if (CurrentEventTime != null)
                {
                   _wavesModel.CreateAxisYEventTime(CurrentEventTime, LChartALL.ViewXY, smList.ToList());
                }
            }
        }
       
        private void OtimeSort(object isCheck)
        {
            if (_lChartAll != null&& (_chartAxisY.Count!=0))
            {
                LChartALL.BeginUpdate();
                bool yAxesVisible = ((bool)isCheck == true);
                ViewXY v = _lChartAll.ViewXY;
                IOrderedEnumerable<LineCollection> lines;
                if (yAxesVisible)
                {
                    lines = v.LineCollections.Where(a => a.Tag != null && a.Tag.ToString().Contains("SHZ")).OrderBy(a => a.Lines[0].AX);
                }
                else
                {
                    lines = v.LineCollections.Where(a => a.Tag != null && a.Tag.ToString().Contains("SHZ")).OrderByDescending(b => b.Lines[0].AX); ;
                }
                int number = v.YAxes.Count / (_chartAxisY.Count / 3);
                foreach (var item in lines.Reverse())
                {
                    int index = item.AssignYAxisIndex;
                    for (int i = 0; i < number; i++)
                    {
                        if (index == -1) continue;   //隐藏轴不需要处理
                        AxisY axisY = v.YAxes[index + i];
                        v.YAxes.RemoveAt(index + i);
                        v.YAxes.Insert(i, axisY);
                    }
                }
                LChartALL.EndUpdate();
            }
        }
        /// <summary>
        /// Y轴的显示和隐藏
        /// </summary>
        /// <param name="content">SHZ,SHN,SHE</param>
        /// <param name="isVisible">true 隐藏轴，false显示轴</param>
        private void YasixZENVisible(string content, bool isVisible)
        {
            ViewXY v = _lChartAll.ViewXY;
            List<AxisY> currentY= new List<AxisY>();
            currentY.AddRange( v.YAxes.Where(y => y.Title.Text.Contains(content)));
            foreach (var item in currentY)
            {
                if (!isVisible)
                {
                    v.YAxes.Remove(item);
                }
                else
                {
                    var yAxis = v.YAxes.Where(vy => vy.Title.Text == item.Title.Text).FirstOrDefault();
                    if (yAxis == null)
                    {
                        //没有查到重新添加
                        string str = item.Title.Text.Replace(content, "");
                        int yIndex = 0;
                        if (content == ".Z")
                        {
                            yIndex = v.YAxes.FindIndex(y => y.Title.Text.Contains(str));
                        }
                        else if (content == ".E")
                        {
                            yIndex = v.YAxes.FindLastIndex(y => y.Title.Text.Contains(str));
                            if (yIndex != -1) yIndex += 1;
                        }
                        else if (content == ".N")
                        {
                            yIndex = v.YAxes.FindIndex(y => y.Title.Text.Contains(str));
                            if (yIndex != -1)
                            {
                                if (v.YAxes[yIndex].Title.Text.Contains(".Z"))
                                {
                                    yIndex = yIndex + 1;
                                }
                            }
                        }
                        //如果没有查到，直接添加到前面,如果为容器最大索引，只能添加到后面
                        if (yIndex == -1 || (yIndex == v.YAxes.Count))
                        {
                            yIndex = v.YAxes.Count;
                            v.YAxes.Add(item);
                        }
                        else
                        {
                            v.YAxes.Insert(yIndex, item);
                        }
                        int sampleIndex = v.SampleDataSeries.FindIndex(y => y.Title.Text == item.Title.Text);
                        v.SampleDataSeries[sampleIndex].AssignYAxisIndex = yIndex;
                    }
                }
            }
        }

        private void IntervalSure()
        {
            if (_lChartAll != null)
            {
                _lChartAll.BeginUpdate();

                if (XaisInterval >= 2)
                {
                    _lChartAll.ViewXY.XAxes[0].MajorDivCount = XaisInterval;
                }
                _lChartAll.EndUpdate();

            }
        }

        private void StationsNameVisible(object obj)
        {
            var station = obj as StationAxis;
            if (_lChartAll != null)
            {
                _lChartAll.BeginUpdate();
                bool yAxesVisible = (station.IsChecked == false);
                ViewXY v = _lChartAll.ViewXY;
                var yAxisList= _chartAxisY.Where(y => y.Title.Text.Contains(station.Name));
                foreach (var item in yAxisList)
                {
                    if (yAxesVisible)
                    {
                        v.YAxes.Remove(item);
                    }
                    else
                    {                      
                        v.YAxes.Add(item);
                        //SampleDataSeries查找数据对应的Y轴索引, 重新分配到对应的轴
                        int sampleIndex = v.SampleDataSeries.FindIndex(s => s.Title.Text == item.Title.Text);
                        v.SampleDataSeries[sampleIndex].AssignYAxisIndex = v.YAxes.Count()-1;
                        //LineCollections查找数据对应的Y轴索引, 重新分配到对应的轴
                        int lineIndex = v.LineCollections.FindIndex(s => s.Title.Text.Contains(item.Title.Text));
                        if (lineIndex != -1)
                        {
                            v.LineCollections[lineIndex].AssignYAxisIndex = v.YAxes.Count() - 1;
                        }
                    }
                }           
                _lChartAll.EndUpdate();
            }
        }
        private void RealTimeData(object isCheck)
        {
            _channelCount = smList.Count * 3;
            CurrentTime = smList.First().BeginTime.ToShortDateString();
            StationsName = smList.Select(a => new StationAxis { Name = a.Name, IsChecked = true, SelectCommand = new DelegateCommand<object>(StationsNameVisible) }).ToList();
            if (_lChartAll != null)
            {
                bool isStartRealData = (Convert.ToBoolean(isCheck) == true);
                if (smList.Count == 0)
                {
                    return;
                }
                _lChartAll.BeginUpdate();
                if (isStartRealData)
                {
                    IsEnableStartRealtime = false;
                    IsEnableStopRealtime = true;
                    _data = new double[smList.Count * 3][];
                    beginTime = DateTime.Now.AddSeconds(-30.5);
                    currentTime = beginTime;
                    if (AxisValueType.DateTime == LChartALL.ViewXY.XAxes[0].ValueType)
                    {
                        DateTime MaxDateTime = currentTime.AddSeconds(30);
                        LChartALL.ViewXY.XAxes[0].SetRange(LChartALL.ViewXY.XAxes[0].DateTimeToAxisValue(currentTime), LChartALL.ViewXY.XAxes[0].DateTimeToAxisValue(MaxDateTime));
                    }
                    LChartALL.ViewXY.DropOldSeriesData = true;

                    _pointsAppended = LChartALL.ViewXY.XAxes[0].Minimum;
                    _lChartAll.ViewXY.XAxes[0].ScrollPosition = _pointsAppended;

                    time.Elapsed -= CompositionTarget_Rendering;
                    time.Elapsed += CompositionTarget_Rendering;
                    LChartALL.ViewXY.XAxes[0].ScrollMode = XAxisScrollMode.Scrolling;

                    time.Start();

                    foreach (var subName in subNameList)
                    {
                        //清空缓存数据；
                        while (subName.Value.DataOrders.TryDequeue(out ChartSamples result))
                        {
                        }
                    }
                    Task.Run(() =>
                    {
                        using (RedisListService service = new RedisListService())
                        {
                            //  Debug.WriteLine($"注册，:{subName.Key}，时间：{DateTime.Now}");                              
                            service.Subscribe((c, message, iRedisSubscription) =>
                                {
                                    //  Debug.WriteLine($"Name:{subName.Key}, length:{message.Length}");
                                    string mes = System.Text.Encoding.Default.GetString(message);
                                    byte[] data = message.Skip(15).ToArray();
                                    string mes1 = System.Text.Encoding.Default.GetString(data);
                                  // if (message.Length == 7 && System.Text.Encoding.Default.GetString(message) == "shutoff")
                                  if(!IsEnableStopRealtime)
                                    {
                                        iRedisSubscription.UnSubscribeFromChannels(subNameList.Keys.ToArray());
                                    }
                                    Mseed2asciiApi.bufferMseedData(message.Length, message);
                                }, subNameList.Keys.ToArray());
                        }
                    });
                }
                else
                {
                    IsEnableStartRealtime = true;
                    IsEnableStopRealtime = false;
                    time.Stop();
                    time.Elapsed -= CompositionTarget_Rendering;
                    LChartALL.ViewXY.XAxes[0].ScrollMode = XAxisScrollMode.None;
                }
                
                _lChartAll.EndUpdate();
            }
        }

        private void Mseed2AsciiEvent(AsciiDataStruct asciiData)
        {
            DateTime startTime = Convert.ToDateTime(asciiData.starttime).AddHours(8);
            DateTime endTime = Convert.ToDateTime(asciiData.endtime).AddHours(8);
            byte[] bytes = new byte[asciiData.numsamples * asciiData.samplesize];
            //   IntPtr bufferHandler = Marshal.AllocHGlobal((int)asciiData.datasize);
            Marshal.Copy(asciiData.datasamples, bytes, 0, bytes.Length);
            List<double> lines = new List<double>();
            string[] sid = asciiData.sid.Substring(5).Split('_');
            string name = $"{sid[0]}.{sid[1]}.{sid[2]}.{sid[3]}{sid[4]}{sid[5]}";
            var ts = DateTime.Now.Subtract(startTime);
            System.Diagnostics.Debug.WriteLine($"台站号：{name},总数：{asciiData.samprate},{asciiData.datasize},{asciiData.samplecnt}, {asciiData.numsamples},当前时间：{DateTime.Now.ToString("o")},接时间：{startTime.ToString("o")}********时间差：{ts.TotalSeconds}秒");
            if ( ts.TotalSeconds > 20)
            {
                return;
            }
            if (asciiData.sampletype == 'i')
            {
                for (int index = 0; index < bytes.Length; index += 4)
                {
                    var a = BitConverter.ToInt32(bytes, index);
                    lines.Add(a);
                }
            }
            else if (asciiData.sampletype == 'f')
            {
                for (int index = 0; index < bytes.Length; index += 4)
                {
                    var b = BitConverter.ToSingle(bytes, index);
                    lines.Add(b);
                }
            }
            else if (asciiData.sampletype == 'd')
            {
                for (int index = 0; index < bytes.Length; index += 8)
                {
                    var b = BitConverter.ToDouble(bytes, index);
                    lines.Add(b);
                }
            }

            subNameList[name].AddChartSam(asciiData.numsamples, new ChartSamples
            {
                StartTime = startTime,
                DataArray = lines.ToArray()
            });

            while (true)
            {
                var flag = subNameList[name].DataOrders.TryPeek(out ChartSamples dataOrder);
                if (flag && DateTime.Now.Subtract(dataOrder.StartTime).TotalSeconds > 60)
                {
                    //删除过期数据
                    subNameList[name].DataOrders.TryDequeue(out ChartSamples chart);
                }
                else
                {
                    break;
                }               
            }
        }
        #endregion
        Grid GridChart;
        private void CreateChart()
        {
            if (LChartALL != null)
            {
                LChartALL = null;
            }
            LChartALL = new LightningChart();
            LChartALL.Title.Align = ChartTitleAlignment.TopCenter;
            LChartALL.ChartRenderOptions.DeviceType = RendererDeviceType.AutoPreferD11;
            LChartALL.ChartRenderOptions.LineAAType2D = LineAntiAliasingType.QLAA;

            LChartALL.Title.Text = "Realtime Waves";
            LChartALL.Title.Color = Colors.Black;
            LChartALL.Title.Font = new WpfFont("Arial", 20);
            LChartALL.Title.Shadow.Style = 0;

            //轴属性和布局
            LChartALL.ViewXY.AxisLayout.YAxesLayout = YAxesLayout.Stacked;
            LChartALL.ViewXY.AxisLayout.SegmentsGap = 0;
            LChartALL.ViewXY.ZoomPanOptions.PanDirection = PanDirection.Horizontal;
            LChartALL.ViewXY.ZoomPanOptions.WheelZooming = WheelZooming.Horizontal;
            LChartALL.ViewXY.AxisLayout.YAxisAutoPlacement = YAxisAutoPlacement.AllRight;
            LChartALL.ViewXY.AxisLayout.YAxisTitleAutoPlacement = false;
            LChartALL.ViewXY.AxisLayout.AutoAdjustMargins = false;

            LChartALL.ViewXY.ZoomPanOptions.DevicePrimaryButtonAction = UserInteractiveDeviceButtonAction.None;
            LChartALL.ViewXY.ZoomPanOptions.DeviceSecondaryButtonAction = UserInteractiveDeviceButtonAction.None;
            LChartALL.ViewXY.ZoomPanOptions.WheelZooming = WheelZooming.Off;
            LChartALL.Options.AllowInternalCursorChange = false;//来禁用掉全部图表的鼠标交互
            //  LChartALL.Options.ShowHints =  HintsVisible.Never;
            //鼠标选中高亮
            LChartALL.Options.AllowUserInteraction = false;

            // 反锯齿系数。值0和1都不会应用反锯齿
            LChartALL.ChartRenderOptions.AntiAliasLevel = 0;
            //X轴设置
            LChartALL.ViewXY.XAxes[0].AllowScrolling = false;
            LChartALL.ViewXY.XAxes[0].PanningEnabled = false;
            LChartALL.ViewXY.XAxes[0].MajorGrid.Pattern = LinePattern.Solid;
            LChartALL.ViewXY.XAxes[0].ValueType = AxisValueType.DateTime;
            LChartALL.ViewXY.XAxes[0].KeepDivCountOnRangeChange = true;
            //LChartALL.ViewXY.XAxes[0].MajorDiv =6;
            LChartALL.ViewXY.XAxes[0].LabelsColor = Colors.Black;
            LChartALL.ViewXY.XAxes[0].AutoDivSpacing = false;
            LChartALL.ViewXY.XAxes[0].MajorDivCount = 5;
            LChartALL.ViewXY.XAxes[0].Title.Text = "times";
            LChartALL.ViewXY.XAxes[0].Title.Font = new WpfFont("Arial", 14);
            LChartALL.ViewXY.XAxes[0].Title.Shadow.Style = 0;
            LChartALL.ViewXY.XAxes[0].Title.Color = Colors.Black;
            XaisInterval = 5;

            //图表背景颜色
            LChartALL.ViewXY.GraphBackground.Color = Colors.White;
            LChartALL.ViewXY.GraphBackground.GradientColor = Colors.White;
            LChartALL.ChartBackground.GradientFill = GradientFill.Solid;
            LChartALL.ChartBackground.Color = Color.FromArgb(0, 0, 0, 0);
            GridChart = new Grid();
            GridChart.ColumnDefinitions.Add(new ColumnDefinition());
            GridChart.Name = "chartGrid";
            GridChart.Children.Add(LChartALL);

            this.ChildContent = GridChart;
        }

        private void StartChart()
        {
            DisposeAllAndClear(_chartAxisY);
            ViewXY v = LChartALL.ViewXY;
            LChartALL.SizeChanged -= LChartALL_SizeChanged;
            LChartALL.SizeChanged += LChartALL_SizeChanged;
            LChartALL.ViewXY.Zoomed -= ViewXY_Zoomed;
            LChartALL.ViewXY.Zoomed += ViewXY_Zoomed;
            LChartALL.ViewXY.Panned -= ViewXY_Panned;
            LChartALL.ViewXY.Panned += ViewXY_Panned;
            DisposeAllAndClear(v.YAxes);
            DisposeAllAndClear(v.SampleDataSeries);
            DisposeAllAndClear(v.LineCollections);
             v.Margins=new Thickness(60, 30, 60, 60);

            v.YAxes.AddRange(_wavesModel.CreateYAxisChart(smList.ToList(), LChartALL));
            v.LegendBoxes[0].Position = LegendBoxPositionXY.RightCenter;
            v.LegendBoxes[0].Offset.SetValues(-10, 180);
            v.LegendBoxes[0].Layout = LegendBoxLayout.Vertical;
            v.LegendBoxes[0].Visible = false;
            v.LegendBoxes[0].Shadow.Color = Colors.Transparent;
            v.LegendBoxes[0].BorderColor = Colors.Transparent;
            v.AutoSpaceLegendBoxes = true;
            v.AxisLayout.SegmentsGap = 3;
            v.LegendBoxes[0].Shadow.Visible = false;

            StationModel stationModel = smList.First();
            var beginTime = DateTime.Now;
            if (AxisValueType.DateTime == v.XAxes[0].ValueType)
            {
                //设置X轴的开始时间
                v.XAxes[0].AutoFormatLabels = false;
                v.XAxes[0].LabelsTimeFormat = "HH:mm:ss.f";
             //  DateTime MaxDateTime = beginTime.AddSeconds(30);
               //v.XAxes[0].SetRange(v.XAxes[0].DateTimeToAxisValue(beginTime), v.XAxes[0].DateTimeToAxisValue(MaxDateTime));
            }
            double firstSampleTimeStamp = v.XAxes[0].DateTimeToAxisValue(beginTime);

            int count = stationModel.Dzne.Count;
            int number= smList.Count*3;
            bool isAdd = false;
            if (subNameList.Count == 0)
            {
                isAdd = true;
            }
            for (int i = 0; i < number; i++)
            {
                int seriesIndex = i;
                AxisY axisY = v.YAxes[seriesIndex];
                axisY.LabelsColor = Colors.Black;
                axisY.Title.Shadow.Style = 0;
                axisY.Title.Font = new WpfFont("Courier New", 16);
                // axisY.Title.Shadow.ContrastColor = Colors.Transparent;
                axisY.Title.AllowDragging = false;
                axisY.AllowAutoYFit = false;
                axisY.Units.Visible = false;
                axisY.LabelsFont = new WpfFont("Courier New", 7);
                axisY.Title.Angle = 0;
                axisY.MinorGrid.Visible = false;
                axisY.AutoDivSpacing = false;
                axisY.MajorDivCount = 2;
              // axisY.MajorDiv = 1;
                axisY.MinorDivTickStyle.Visible = false;
                axisY.MajorGrid.Visible = true;
                axisY.MajorGrid.Pattern = LinePattern.Solid;
                axisY.MajorDivTickStyle.Alignment = Alignment.Far; //seriesIndex % 2 == 0 ? Alignment.Near : Alignment.Far;
                // axisY.MajorDivTickStyle.LineLength = 6;
                axisY.MajorDivTickStyle.Color = Colors.Black;
                axisY.Title.Color = Colors.Black;
                axisY.Title.Font = new WpfFont("Courier New", 12);
                axisY.PanningEnabled = false;
                axisY.AllowScrolling = false;
                axisY.AllowScaling = false;

                SampleDataSeries series = new SampleDataSeries(v, v.XAxes[0], axisY);
                series.ShowInLegendBox = false;
                series.FirstSampleTimeStamp = firstSampleTimeStamp;
                series.SamplingFrequency = _samplingFrequency;
                series.Title.Text = axisY.Title.Text;
                series.SampleFormat = SampleFormat.DoubleFloat;
     
                string subName = string.Empty;
                string name = axisY.Title.Text.Substring(0,3);
                if (seriesIndex % 3 == 0)
                {
                    subName = $"{workarea.StationConfig.Network}.{name}.{workarea.StationConfig.Location}." +
                        $"{workarea.StationConfig.Channels.Split(':')[0]}";
                    series.LineStyle.Color = System.Windows.Media.Colors.DeepSkyBlue;
                }
                else if (seriesIndex % 3 == 1)
                {
                    subName = $"{workarea.StationConfig.Network}.{name}.{workarea.StationConfig.Location}." +
                        $"{workarea.StationConfig.Channels.Split(':')[1]}";
                    series.LineStyle.Color = System.Windows.Media.Colors.OrangeRed;
                }
                else if (seriesIndex % 3 == 2)
                {
                    subName = $"{workarea.StationConfig.Network}.{name}.{workarea.StationConfig.Location}." +
                        $"{workarea.StationConfig.Channels.Split(':')[2]}";
                    series.LineStyle.Color = System.Windows.Media.Colors.ForestGreen;
                }
                if (isAdd)
                {
                    subNameList.Add(subName, new ASCiiData { Index = i, sid = subName });
                }
                series.LineStyle.Width = 1;
                series.ScrollModePointsKeepLevel = 1;
                //series.ScrollingStabilizing = true;
                v.SampleDataSeries.Add(series);
                _chartAxisY.Add(axisY);
            }
        }

        private void ViewXY_Panned(object sender, PannedXYEventArgs e)
        {
            foreach (var item in LChartALL.ViewXY.LineCollections)
            {
                double b = LChartALL.ViewXY.XAxes[0].ValueToCoordD(item.Lines[0].AX) - 80;
                item.Title.Offset.SetValues((int)b, 3);
            }
        }

        private void ViewXY_Zoomed(object sender, ZoomedXYEventArgs e)
        {
            foreach (var item in LChartALL.ViewXY.LineCollections)
            {
                double b = LChartALL.ViewXY.XAxes[0].ValueToCoordD(item.Lines[0].AX) - 80;
                item.Title.Offset.SetValues((int)b, 3);
            }
        }

        private void LChartALL_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            int distancetoX = _wavesModel.SetYasixPlacement(LChartALL);
            foreach (var item in LChartALL.ViewXY.YAxes)
            {
                item.Title.DistanceToAxis = distancetoX;
            }
            foreach (var item in LChartALL.ViewXY.LineCollections)
            {
                double b = LChartALL.ViewXY.XAxes[0].ValueToCoordD(item.Lines[0].AX)-80;
                item.Title.Offset.SetValues((int)b, 3);
            }
        }

        private void FeedDatasToChart()
        {
            _data = new double[smList.Count * 3][];
            try
            {
                for (int channelIndex = 0; channelIndex < smList.Count; channelIndex++)
                {
                    _data[channelIndex * 3] = smList.ElementAt(channelIndex).dz.ToArray();
                    _data[channelIndex * 3 + 1] = smList.ElementAt(channelIndex).dn.ToArray();
                    _data[channelIndex * 3 + 2] = smList.ElementAt(channelIndex).de.ToArray();
                }
                // Invoke FeedNewDataToChart.
                _dispatcher.Invoke(() =>
                {
                    LChartALL.BeginUpdate();
                    for (int channelIndex = 0; channelIndex < _channelCount; channelIndex++)
                    {
                        LChartALL.ViewXY.SampleDataSeries[channelIndex].AddSamples(_data[channelIndex], true);
                    }
                    LChartALL.EndUpdate();
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void ApplicationClosingDispose(object sender, CancelEventArgs e)
        {
            if (LChartALL != null)
            {
                LChartALL.Dispose();
                LChartALL = null;
            }
        }

        private void DisposeAllAndClear<T>(List<T> list) where T : IDisposable
        {
            if (list == null)
            {
                return;
            }

            while (list.Count > 0)
            {
                int lastInd = list.Count - 1;
                T item = list[lastInd]; // take item ref from list. 
                list.RemoveAt(lastInd); // remove item first
                if (item != null)
                {
                    (item as IDisposable).Dispose();     // then dispose it. 
                }
            }
        }
        public void Dispose()
        {
            GridChart.Children.Clear();

            if (LChartALL != null)
            {
                LChartALL.Dispose();
                LChartALL = null;
            }
        }

        #region  实时数据
        private void CompositionTarget_Rendering(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                RenderNextFrame();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            //_dispatcher.Invoke(() =>
            //{
                   //测试数据
              //    FeedDataTest();
            //});
        }

        DateTime currentTime = DateTime.Now;
        DateTime beginTime = DateTime.Now;
        private void RenderNextFrame()
        {
            string minName = string.Empty;
            if (_lChartAll == null )
            {
                return;
            }
            Stopwatch stopwatch = Stopwatch.StartNew();

;            foreach (var item in subNameList)
            {
                List<double> temDou = new List<double>();
                var tem = item.Value.DataOrders.Where(d => d.StartTime > currentTime.AddSeconds(-30) && d.StartTime < currentTime.AddSeconds(1));
                if (tem.Any())
                {
                    item.Value.FirstSampleTime = tem.ElementAt(0).StartTime;   //设置数据的开始时间
                    tem.ToList().ForEach(d => temDou.AddRange(d.DataArray));
   
                    _data[item.Value.Index] = temDou.ToArray();
                }
                else
                {
                    //没有收到数据的通道填充0
                    var duration = (currentTime - beginTime.AddSeconds(-1)).Duration();
                    item.Value.FirstSampleTime = duration.TotalSeconds > 30 ? currentTime.AddSeconds(-29) : beginTime;
                    int feed = duration.TotalSeconds > 30 ? 30 * _samplingFrequency : (int)duration.TotalSeconds* _samplingFrequency;
                    _data[item.Value.Index] = new double[feed];
                }
            }

            stopwatch.Stop();
            double time1 = stopwatch.ElapsedMilliseconds;
            stopwatch.Restart();

            stopwatch.Stop();
            double time2 = stopwatch.ElapsedMilliseconds;
            stopwatch.Restart();
            _dispatcher.Invoke(() =>
            {
                FeedData();
            });
            stopwatch.Stop();
            currentTime = currentTime.AddSeconds(1);
            double time3 = stopwatch.ElapsedMilliseconds;
            Debug.WriteLine("timeFrame:{0},time1:{1}ms,time2:{2}ms，time3:{3}ms", currentTime, time1, time2,time3);
        }
        double _pointsAppended = 0;
        double[][] _data;

        private void FeedData()
        {
            if (_lChartAll == null) return;
            _lChartAll.BeginUpdate();
            foreach (var item in subNameList)
            {
                int index = item.Value.Index;
                _lChartAll.ViewXY.SampleDataSeries[index].Clear();
                var d = _lChartAll.ViewXY.XAxes[0].DateTimeToAxisValue(item.Value.FirstSampleTime);
                _lChartAll.ViewXY.SampleDataSeries[index].FirstSampleTimeStamp = d;// _lChartAll.ViewXY.XAxes[0].Minimum;// item.Value.FirstSampleTimeStamp;
            }
            Parallel.For(0, _channelCount, (seriesIndex) =>
            {
                double[] thisSeriesData = _data[seriesIndex];

                int yindex = _lChartAll.ViewXY.SampleDataSeries[seriesIndex].AssignYAxisIndex;
                if (yindex >= 0)
                {
                    _lChartAll.ViewXY.YAxes[yindex].SetRange(thisSeriesData.Min()-1, thisSeriesData.Max() + 1); 
                }
                _lChartAll.ViewXY.SampleDataSeries[seriesIndex].AddSamples(thisSeriesData, false);
                Debug.WriteLine($"{DateTime.Now}*********** index:{seriesIndex}," +
                    $" pointCount:{_lChartAll.ViewXY.SampleDataSeries[seriesIndex].PointCount}");
            });
            _pointsAppended += 1;

            double lastX = _pointsAppended * XInterval;
            _lChartAll.ViewXY.XAxes[0].ScrollPosition = lastX;
            _lChartAll.EndUpdate();

        }
        private const double XInterval = 1;
        private readonly IDialogService _dialogService;

        private DateTime GetTime()
        {
            DateTime time ;
            var client = new System.Net.Sockets.TcpClient("time.nist.gov", 13);
            using (var streamReader = new System.IO.StreamReader(client.GetStream()))
            {
                var response = streamReader.ReadToEnd();
                var utcDateTimeString = response.Substring(7, 17);
                time= DateTime.ParseExact(utcDateTimeString, "yy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
            }
            return time; 
        }


        public void OnNavigatedTo(NavigationContext navigationContext)
        {
           var str=  navigationContext.Parameters.GetValue<string>("model");
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
        }

        #endregion
    }
}
