using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

using FObjBase;
using FlyADBase;
using FLY.Thick.Base.IService;
using System.IO;


namespace FLY.Thick.Base.Server
{
    public class GM_ScanCorr:GM_ScanMotion2, IScanCorrService,Misc.ISaveToXml
    {
        #region 延时推送 MARKNO
        
        #endregion

        #region IScanCorrService 接口
        private bool _enable = false;
        /// <summary>
        /// 使能!!
        /// </summary>
        public bool Enable
        {
            get { return _enable; }
            set
            {
                if (_enable != value)
                {
                    _enable = value;
                    NotifyPropertyChanged("Enable");
                }
            }
        }

        private int _smoothfactor = 1;
        /// <summary>
        /// 修正数据滤波,平均滤波,多少个数据平均
        /// </summary>
        public int SmoothFactor
        {
            get { return _smoothfactor; }
            set
            {
                if (_smoothfactor != value)
                {
                    _smoothfactor = value;
                    NotifyPropertyChanged("SmoothFactor");
                }
            }
        }
        private int scanTimer = 2;
        /// <summary>
        /// 来回次数
        /// </summary>
        public int ScanTimer 
        {
            get { return scanTimer; }
            set {
                if (scanTimer != value) 
                {
                    scanTimer = value;
                    NotifyPropertyChanged("ScanTimer");
                }
            }
        }
        private int validbegin = 0;
        /// <summary>
        /// 有效范围.开始,单位脉冲
        /// </summary>
        public int ValidBegin
        {
            get
            {
                return validbegin;
            }
            set
            {
                if (validbegin != value)
                {
                    validbegin = value;
                    NotifyPropertyChanged("ValidBegin");
                }
            }
        }

        private int validend = 8000;
        /// <summary>
        /// 有效范围.结束,单位脉冲
        /// </summary>
        public int ValidEnd
        {
            get
            {
                return validend;
            }
            set
            {
                if (validend != value)
                {
                    validend = value;
                    NotifyPropertyChanged("ValidEnd");
                }
            }
        }

        private int _posofgrid = 8;
        /// <summary>
        /// 机架修正数据, 
        /// </summary>
        public int PosOfGrid
        {
            get { return _posofgrid; }
            set
            {
                if (_posofgrid != value)
                {
                    _posofgrid = value;
                }
                NotifyPropertyChanged("PosOfGrid");
            }
        }

        private int _poslen = 9000;
        /// <summary>
        /// 机架修正数据, 
        /// </summary>
        public int PosLen
        {
            get { return _poslen; }
            set
            {
                if (_poslen != value)
                {
                    _poslen = value;
                }
                NotifyPropertyChanged("PosLen");
            }
        }

        private ScanCorrGroup[] _groups = new ScanCorrGroup[2] { new ScanCorrGroup(), new ScanCorrGroup() };
        public IScanCorrGroup Group0
        {
            get
            {
                return _groups[0];
            }
        }
        public IScanCorrGroup Group1
        {
            get
            {
                return _groups[1];
            }
        }
        public ScanCorrGroup[] Groups
        {
            get
            {
                return _groups;
            }
        }
        #endregion

        string param_path = "scancorr.csv";

        public GM_ScanCorr(FlyAD7 flyad)
            : this(flyad, "scancorr.csv")
        { 
            
        }
        public GM_ScanCorr(FlyAD7 flyad, string param_path)
            : base(flyad)
        {
            GMState = Common.CTRL_STATE.CORR;

            if (string.IsNullOrEmpty(param_path))
                this.param_path = param_path;
            Load();

            MakeValid();




            CurrGroupIndex = 0;

            this.PropertyChanged += new PropertyChangedEventHandler(ScanCorr_PropertyChanged);
            DataPosEvent += new EndEventHandler(pollCorrect_DataPosEvent);
            EndEvent += new EndEventHandler(pollCorrect_EndEvent);
            FinishEvent += new EventHandler(pollCorrect_FinishEvent);
        }
        void MakeValid() 
        {
            //确保 ForwDatas BackwDatas 大小 为 PosLen / PosOfGrid
            int dataLen = PosLen / PosOfGrid;
            List<List<int>> datasList = new List<List<int>>();
            datasList.Add(Group0.ForwDatas);
            datasList.Add(Group0.BackwDatas);
            datasList.Add(Group1.ForwDatas);
            datasList.Add(Group1.BackwDatas);

            for (int i = 0; i < datasList.Count(); i++)
            {
                int idx = dataLen;
                List<int> datas = datasList[i];
                int remove_cnt = datas.Count() - dataLen;
                if (remove_cnt > 0)
                {
                    datas.RemoveRange(idx, remove_cnt);
                }
                else if (remove_cnt < 0)
                {
                    for (int j = 0; j < (-remove_cnt); j++)
                    {
                        datas.Add(Misc.MyBase.NULL_VALUE);
                    }
                }
            }
            if (ValidBegin < 0)
                ValidBegin = 0;
            if (ValidEnd >= PosLen)
                ValidEnd = PosLen - 1;
        }
        void ScanCorr_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if ((e.PropertyName == "ValidBegin") || (e.PropertyName == "ValidEnd")) 
            {
                UpdateAvg();
            }
        }

        void pollCorrect_DataPosEvent(object obj, FlyADBase.MiniGridEventArgs e)
        {
            int grid_len = PosLen / PosOfGrid;
            //TODO
            if (e.direction == Misc.DIRECTION.FORWARD)
            {
                int p = e.grid_start * 100 / grid_len;

                Progress = (100 * tempDataCnt + p) / (2* ScanTimer);
            }
            else
            {
                int p = (grid_len - e.grid_start) * 100 / grid_len;

                Progress = (100 * tempDataCnt + p) / (2 * ScanTimer);
            }
        }

        #region 属性,动态
        private int _corrPoint;
        /// <summary>
        /// 当前操作的组
        /// </summary>
        public int CurrGroupIndex
        {
            get { return _corrPoint; }
            set
            {
                _corrPoint = value;
                NotifyPropertyChanged("CurrGroupIndex");
            }
        }

        private int _progress = 0;
        /// <summary>
        /// 进度 =100完成
        /// </summary>
        public int Progress
        {
            get { return _progress; }
            set
            {
                _progress = value;
                if (value == 0)
                    Ing = true;
                else if (value >= 100)
                    Ing = false;
                NotifyPropertyChanged("Progress");
            }
        }

        private bool _ing;
        /// <summary>
        /// 校正中
        /// </summary>
        public bool Ing
        {
            get { return _ing; }
            set
            {
                _ing = value;
                NotifyPropertyChanged("Ing");
            }
        }


        private int[][] tempData = new int[2][];
        private int tempDataCnt = 0;

        private int _progress_cnt = 0;
        private Misc.DIRECTION _progress_direction = Misc.DIRECTION.FORWARD;
        #endregion
        public void Smooth(int index)
        {
            Groups[index].Smooth(SmoothFactor);
            Save();
        }
        public override bool Start()
        {
            bool b = base.Start();
            if (!b)
                return false;

            Progress = 0;
            ScanCnt = ScanTimer;
            PosOfGrid = mFlyAD.PosOfGrid;
            PosLen = mFlyAD.PosLen;
            int grid_size = PosLen / PosOfGrid;

            tempData[0] = new int[grid_size];
            tempData[1] = new int[grid_size];
            for (int i = 0; i < grid_size; i++)
            {
                tempData[0][i] = Misc.MyBase.NULL_VALUE;
                tempData[1][i] = Misc.MyBase.NULL_VALUE;
            }
            tempDataCnt = 0;

            return base.Start2();
        }
        public void Start( int index)
        {
            Enable = false;//关闭校正,让flyad7 输出的是原始数据
            
            //ScanTimer = scantimer;
            
            //SmoothFactor = smoothfactor;
            
            if (index < 0) index = 0;
            if (index > 1) index = 1;
            CurrGroupIndex = index;

            Start();
        }
        public override void Stop()
        {
            base.Stop();
            Ing = false;
        }
        public void Clear(int index)
        {
            if (index < 0) index = 0;
            if (index > 1) index = 1;
            Groups[index].Clear();
            Save();
        }
        public void Apply() 
        {
            Save();
        }
        void pollCorrect_FinishEvent(object sender, EventArgs e)
        {
            //if (!Ing)
            //    return;
            if (Make())
                Save();
            Progress = 100;
        }

        void pollCorrect_EndEvent(object obj, FlyADBase.MiniGridEventArgs e)
        {
            //if (!Ing)
            //    return;

            DataEnd(e.direction, e.posOfGrid, e.grid_start, e.buf);
        }

        void DataEnd(Misc.DIRECTION direction, int posOfGrid, int start_grid, int[] dat)
        {
            int idx = 0;
            if (direction == Misc.DIRECTION.BACKWARD)
                idx = 1;
            int start_pos = start_grid * posOfGrid;

            for (int i = 0; i < dat.Length; i++)
            {
                int grid = i + start_grid;
                if (grid >= tempData[idx].Length)
                    break;

                if (Misc.MyBase.ISVALIDATA(tempData[idx][grid]) && Misc.MyBase.ISVALIDATA(dat[i]))
                {
                    tempData[idx][grid] = (tempData[idx][grid] * tempDataCnt + dat[i]) / (tempDataCnt + 1);
                }
                else if (Misc.MyBase.ISVALIDATA(dat[i]))
                {
                    tempData[idx][grid] = dat[i];
                }
            }

            tempDataCnt++;
            Progress = 100 * tempDataCnt / (ScanTimer * 2);
        }

        void UpdateAvg() 
        {
            int begin = ValidBegin / PosOfGrid;
            int end = ValidEnd / PosOfGrid;
            if (begin >= end)
            {
                begin = 0;
                end = PosLen / PosOfGrid - 1;
            }

            for (int i = 0; i < 2; i++) 
            {
                ((ScanCorrGroup)(Groups[i])).CalAvg(begin, end);
            }
        }

        bool Make()
        {
            
            int pindex = CurrGroupIndex;
            if (pindex != 0) pindex = 1;

            //tempData 的数据必须全部都是有效的!!!!
            //for (int i = 0; i < 2; i++)
            //{
            //    if (tempData[i].Contains(Misc.MyBase.NULL_VALUE))
            //        return false;
            //}

            //make
            ((ScanCorrGroup)(Groups[pindex])).Make( tempData[0], tempData[1]);
            ((ScanCorrGroup)(Groups[pindex])).Smooth(SmoothFactor / PosOfGrid);


            int begin = ValidBegin / PosOfGrid;
            int end = ValidEnd / PosOfGrid;
            if (begin >= end)
            {
                begin = 0;
                end = PosLen / PosOfGrid - 1;
            }
            ((ScanCorrGroup)(Groups[pindex])).CalAvg(begin, end);
            return true;
        }
        public void CorrectADs(Misc.DIRECTION direction, int start_grid, int[] dat)
        {
            if (Enable)
            {
                for (int i = 0; i < dat.Length; i++)
                {
                    int grid = start_grid + i;

                    dat[i] = CorrectAD(direction, grid, dat[i]);
                }
            }
        }
        public int CorrectAD(Misc.DIRECTION direction, int grid, int ad)
        {
            if ((Misc.MyBase.ISVALIDATA(ad) == false) ||
                (Misc.MyBase.ISVALIDATA(grid) == false) ||
                (Enable == false) ||
                ((Groups[0].ForwDatas.Count() ==0) && (Groups[1].ForwDatas.Count() ==0)))
                return ad;



            int datasize;
            if(Groups[0].ForwDatas.Count()>0)
                datasize = Groups[0].ForwDatas.Count();
            else
                datasize = Groups[1].ForwDatas.Count();




            int begin = ValidBegin / PosOfGrid;
            int end = ValidEnd / PosOfGrid;
            if (begin >= end)
            {
                begin = 0;
                end = PosLen / PosOfGrid - 1;
            }

            if (grid < 0)
                grid = 0;
            else if (grid >= datasize)
                grid = datasize - 1;
            else if (grid < begin)
                grid = begin;
            else if (grid > end)
                grid = end;


            int ad0 = Misc.MyBase.NULL_VALUE;//group 0
            int ad1 = Misc.MyBase.NULL_VALUE;//group 1
            int ad0_avg = Groups[0].AvgAD;//group 0
            int ad1_avg = Groups[1].AvgAD;//group 1

            if (direction == Misc.DIRECTION.FORWARD)
            {
                if(Groups[0].ForwDatas.Count>0)
                    ad0 = Groups[0].ForwDatas[grid];

                if (Groups[1].ForwDatas.Count > 0)
                    ad1 = Groups[1].ForwDatas[grid];
            }
            else if (direction == Misc.DIRECTION.BACKWARD)
            {
                if (Groups[0].BackwDatas.Count > 0)
                    ad0 = Groups[0].BackwDatas[grid];

                if (Groups[1].BackwDatas.Count > 0)
                    ad1 = Groups[1].BackwDatas[grid];
            }
            else
            {

                int ad2 = Misc.MyBase.NULL_VALUE;
                int ad3 = Misc.MyBase.NULL_VALUE;
                if (Groups[0].ForwDatas.Count > 0)
                {
                    ad0 = Groups[0].ForwDatas[grid];
                    ad2 = Groups[0].BackwDatas[grid];
                }
                if (Groups[1].ForwDatas.Count > 0)
                {
                    ad1 = Groups[1].ForwDatas[grid];
                    ad3 = Groups[1].BackwDatas[grid];
                }

                if (Misc.MyBase.ISVALIDATA(ad0) && Misc.MyBase.ISVALIDATA(ad2))
                    ad0 = (ad0 + ad2) / 2;
                else if (Misc.MyBase.ISVALIDATA(ad2))
                    ad0 = ad2;

                if (Misc.MyBase.ISVALIDATA(ad1) && Misc.MyBase.ISVALIDATA(ad3))
                    ad1 = (ad1 + ad3) / 2;
                else if (Misc.MyBase.ISVALIDATA(ad3))
                    ad1 = ad3;

            }

            //TODO
            double x, p0, p1;
            if (Misc.MyBase.ISVALIDATA(ad0) && Misc.MyBase.ISVALIDATA(ad1))
            {
                // ad0_avg 与 ad1_avg 偏差必须 40%以上
                double d = (double)Math.Abs(ad0_avg - ad1_avg) / (ad0_avg + ad1_avg);
          
                if (d < 0.2)
                {
                    //异常
                    x = (double)ad0_avg / ad0;

                    ad = (int)(x * ad);
                }
                else
                {
                    p0 = (double)ad0_avg / ad0;
                    p1 = (double)ad1_avg / ad1;

                    x = (p0 - p1) * (ad - ad1_avg) / (ad0_avg - ad1_avg) + p1;

                    ad = (int)(x * ad);
                }
            }
            else if (Misc.MyBase.ISVALIDATA(ad0))
            {
                x = (double)ad0_avg / ad0;

                ad = (int)(x * ad);
            }
            else if (Misc.MyBase.ISVALIDATA(ad1))
            {
                x = (double)ad1_avg / ad1;

                ad = (int)(x * ad);
            }


            return ad;
        }

        public bool Load()
        {
            if(!LoadCSV())
                return Misc.SaveToXmlHepler.Load("scancorr.xml", this);
            return true;
        }
        public void Save()
        {
            //Misc.SaveToXmlHepler.Save("scancorr.xml", this);
            SaveCSV();
        }

        void SaveCSV() 
        {
            try
            {
                string filepath = param_path;// "scancorr.csv";
                using (StreamWriter sw = new StreamWriter(filepath, false, Encoding.GetEncoding("GB2312")))
                {
                    sw.WriteLine("Enable" + "," + Enable.ToString());
                    sw.WriteLine("ScanTimer" + "," + ScanTimer.ToString());
                    sw.WriteLine("SmoothFactor" + "," + SmoothFactor.ToString());
                    sw.WriteLine("PosOfGrid" + "," + PosOfGrid.ToString());
                    sw.WriteLine("PosLen" + "," + PosLen.ToString());
                    sw.WriteLine();

                    int posOfGrid = PosOfGrid;
                    int gridcnt = PosLen / PosOfGrid;
                    //标题
                    StringBuilder sb_header = new StringBuilder();
                    sb_header.Append("position");
                    sb_header.Append(",Group0_forw");
                    sb_header.Append(",Group0_backw");
                    sb_header.Append(",Group1_forw");
                    sb_header.Append(",Group1_backw");
                    sw.WriteLine(sb_header.ToString());


                    for (int j = 0; j < gridcnt; j++)
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.Append((j * posOfGrid).ToString());
                        sb.Append(",");
                        if (j < Group0.ForwDatas.Count())
                        {
                            int ad = Group0.ForwDatas[j];
                            if (Misc.MyBase.ISVALIDATA(ad))
                                sb.Append(ad.ToString());
                        }
                        sb.Append(",");
                        if (j < Group0.BackwDatas.Count())
                        {
                            int ad = Group0.BackwDatas[j];
                            if (Misc.MyBase.ISVALIDATA(ad))
                                sb.Append(ad.ToString());
                        }
                        sb.Append(",");
                        if (j < Group1.ForwDatas.Count())
                        {
                            int ad = Group1.ForwDatas[j];
                            if (Misc.MyBase.ISVALIDATA(ad))
                                sb.Append(ad.ToString());
                        }
                        sb.Append(",");
                        if (j < Group1.BackwDatas.Count())
                        {
                            int ad = Group1.BackwDatas[j];
                            if (Misc.MyBase.ISVALIDATA(ad))
                                sb.Append(ad.ToString());
                        }

                        sw.WriteLine(sb.ToString());
                    }
                    sw.Flush();
                    sw.Close();
                }
            }
            catch
            {
                
            }
        }
        bool LoadCSV() 
        {
            string filepath = param_path;// "scancorr.csv";
            try
            {
                bool keyvalue_state = true;//键值对模式
                using (StreamReader sw = new StreamReader(filepath, Encoding.GetEncoding("GB2312")))
                {
                    while (!sw.EndOfStream)
                    {
                        string item;
                        item = sw.ReadLine();
                        string[] items = item.Split(',');
                        if (keyvalue_state)
                        {
                            if (items.Count() >= 2)
                            {
                                if (items[0].StartsWith("Enable"))
                                {
                                    bool b;
                                    if (bool.TryParse(items[1], out b))
                                        Enable = b;
                                    else
                                        return false;
                                }
                                else if (items[0].StartsWith("ScanTimer"))
                                {
                                    int i;
                                    if (int.TryParse(items[1], out i))
                                        ScanTimer = i;
                                    else
                                        return false;
                                }
                                else if (items[0].StartsWith("SmoothFactor"))
                                {
                                    int i;
                                    if (int.TryParse(items[1], out i))
                                        SmoothFactor = i;
                                    else
                                        return false;
                                }
                                else if (items[0].StartsWith("PosOfGrid"))
                                {
                                    int i;
                                    if (int.TryParse(items[1], out i))
                                        PosOfGrid = i;
                                    else
                                        return false;
                                }
                                else if (items[0].StartsWith("PosLen"))
                                {
                                    int i;
                                    if (int.TryParse(items[1], out i))
                                        PosLen = i;
                                    else
                                        return false;
                                }
                                else if (items[0].StartsWith("position")) 
                                {
                                    keyvalue_state = false;//正文

                                    //标题,忽略
                                    Group0.AvgAD = Misc.MyBase.NULL_VALUE;
                                    Group0.ForwDatas.Clear();
                                    Group0.BackwDatas.Clear();

                                    Group1.AvgAD = Misc.MyBase.NULL_VALUE;
                                    Group1.ForwDatas.Clear();
                                    Group1.BackwDatas.Clear();
                                }
                            }
                        }
                        else
                        {
                            //正文
                            if (items.Count() == 0)
                            { 
                                //没数据了
                                return true;
                            }

                            for (int i = 1; i < 5; i++)
                            {
                                if (i >= items.Count())
                                    break;
                                int ad;
                                if (string.IsNullOrEmpty(items[i]))
                                    ad = Misc.MyBase.NULL_VALUE;
                                else
                                {
                                    if (!int.TryParse(items[i], out ad))
                                        ad = Misc.MyBase.NULL_VALUE;
                                }
                                switch (i)
                                {
                                    case 1:
                                        Group0.ForwDatas.Add(ad);
                                        break;
                                    case 2:
                                        Group0.BackwDatas.Add(ad);
                                        break;
                                    case 3:
                                        Group1.ForwDatas.Add(ad);
                                        break;
                                    case 4:
                                        Group1.BackwDatas.Add(ad);
                                        break;
                                }
                            }
                        }
                    }
                }
            }
            catch
            {
                return false;
            }
            return true;
        }
        public string[] GetSavePropertyNames()
        {
            return new string[] { 
                "Enable", 
                "ScanTimer" ,
                "SmoothFactor",
                "PosOfGrid",
                "PosLen",
                "Group0",
                "Group1"
            };
        }
    }

    public class ScanCorrGroup : IScanCorrGroup, Misc.ISaveToXml
    {
        private int _avgad = Misc.MyBase.NULL_VALUE;
        /// <summary>
        /// 平均AD值
        /// </summary>
        public int AvgAD
        {
            get { return _avgad; }
            set
            {
                _avgad = value;
                NotifyPropertyChanged("AvgAD");
            }
        }

        private List<int> forwdatas = new List<int>();
        /// <summary>
        /// 正方向机架AD值数据, grid数据
        /// </summary>
        public List<int> ForwDatas
        {
            get { return forwdatas; }
        }
        private List<int> backwdatas = new List<int>();
        /// <summary>
        /// 正方向机架AD值数据, grid数据
        /// </summary>
        public List<int> BackwDatas
        {
            get { return backwdatas; }
        }

        public ScanCorrGroup()
        {
            Clear();
        }


        public void Clear()
        {
            AvgAD = Misc.MyBase.NULL_VALUE;
            ForwDatas.Clear();
            BackwDatas.Clear();
            NotifyPropertyChanged("ForwDatas");
            NotifyPropertyChanged("BackwDatas");
        }

        /// <summary>
        /// 必须保证 f_ad, 与 b_ad 长度一致!!!
        /// </summary>
        /// <param name="avgad"></param>
        /// <param name="f_ad"></param>
        /// <param name="b_ad"></param>
        public void Make(int[] f_ad, int[] b_ad)
        {
            Clear();
            ForwDatas.AddRange(f_ad);
            BackwDatas.AddRange(b_ad);
            NotifyPropertyChanged("ForwDatas");
            NotifyPropertyChanged("BackwDatas");
        }
        public void CalAvg(int begin, int end) 
        {
            if ((ForwDatas.Count() == 0) || (BackwDatas.Count() == 0))
                return;//失败,没数据

            if (begin < 0)
                begin = 0;
            if (end >= ForwDatas.Count())
                end = ForwDatas.Count() - 1;

            int sum=0;
            int cnt = 0;
            for (int i = begin; i <= end; i++) 
            {
                if (Misc.MyBase.ISVALIDATA(ForwDatas[i]))
                {
                    sum += ForwDatas[i];
                    cnt++;
                }
                if (Misc.MyBase.ISVALIDATA(BackwDatas[i]))
                {
                    sum += BackwDatas[i];
                    cnt++;
                }
            }
            if (cnt > 0)
                AvgAD = sum / cnt;
            else
                AvgAD = Misc.MyBase.NULL_VALUE;
        }
        void Smooth(int smoothfactor, List<int> corr)
        {
            int[] result = new int[corr.Count()];
            for (int i = 0; i < corr.Count(); i++)
            {

                int begin = i - smoothfactor;
                int end = i + smoothfactor;
                if (begin < 0)
                    begin = 0;
                
                if (end >= corr.Count())
                    end = corr.Count() - 1;

                double sum = 0;
                int cnt = 0;
                for (int j = begin; j <= end; j++)
                {
                    if (Misc.MyBase.ISVALIDATA(corr[j]))
                    {
                        sum += corr[j];
                        cnt++;
                    }
                }
                if (cnt > 0)
                    result[i] = (int)(sum / cnt);
                else
                    result[i] = Misc.MyBase.NULL_VALUE;
            }
            for (int i = 0; i < corr.Count(); i++)
            {
                corr[i] = result[i];
            }
        }
        /// <summary>
        /// 平滑处理, 中值滤波
        /// </summary>
        /// <param name="smoothfactor"> 平均滤波的个数=smoothfactor*2+1</param>
        public void Smooth(int smoothfactor)
        {
            if (smoothfactor <= 0)
                return;

            Smooth(smoothfactor, ForwDatas);
            Smooth(smoothfactor, BackwDatas);
            NotifyPropertyChanged("ForwDatas");
            NotifyPropertyChanged("BackwDatas");
        }
        #region INotifyPropertyChanged 成员
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion




        public string[] GetSavePropertyNames()
        {
            return new string[]{
              "AvgAD","ForwDatas","BackwDatas"};

        }
    }


}