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

namespace FLY.Thick.BulkDataModule
{
    public class BulkDataServiceClientAdv
    {
        public IBulkDataService bulkdata;

        public BulkDataServiceClientAdv(IBulkDataService bulkdata)
            : base()
        {
            this.bulkdata = bulkdata;
            bulkdata.PropertyChanged+=new PropertyChangedEventHandler(BulkdataClient_PropertyChanged);
        }

        void BulkdataClient_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsConnected")
            {
                if (bulkdata.IsConnected)
                {
                    //所有都要向服务器重新注册
                    List<BulkDataGraph> send = new List<BulkDataGraph>();

                    foreach (BulkDataGraph graph in mGraphs)
                    {
                        if (!send.Exists(graph.IsEquals))
                        {
                            Regist(graph);
                            send.Add(graph);
                        }
                    }
                }
            }
        }

        public abstract class BulkDataGraph : INotifyPropertyChanged
        {
            /// <summary>
            /// 注册事件
            /// </summary>
            public event Action<BulkDataGraph> RegistEvent;

            /// <summary>
            /// 通知界面已经更新了，重画界面
            /// </summary>
            /// <param name="obj"></param>
            public event Action<BulkDataGraph> UpdateEvent;

            #region 参数


            private int mix;
            /// <summary>
            /// 混合数
            /// </summary>
            public int Mix
            {
                get
                {
                    return mix;
                }
                set
                {
                    if (mix != value)
                    {
                        mix = value;

                        NotifyPropertyChanged("Mix");
                        NotifyRegistEvent();
                    }
                }
            }
            #endregion

            public abstract void CopyTo(BulkDataGraph g);
            public abstract void Update(object obj);
            public abstract bool IsEquals(object obj);

            protected void NotifyRegistEvent()
            {
                RegistEvent?.Invoke(this);
            }
            protected void NotifyUpdateEvent()
            {
                UpdateEvent?.Invoke(this);
            }

            #region INotifyPropertyChanged 成员
            protected void NotifyPropertyChanged(string PropertyName)
            {
                if (this.PropertyChanged != null)
                    this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(PropertyName));
            }
            public event PropertyChangedEventHandler PropertyChanged;
            #endregion
        }
        /// <summary>
        /// 横向扫描数据请求与结果
        /// </summary>
        public class BulkDataGraphFrame : BulkDataGraph
        {
            public override string ToString()
            {
                return "BM = " + BM.ToString()+"(" + BookMark.ToString() + ")";
            }
            public BulkDataGraphFrame()
            {
                //this.RegistEvent += new Action<BulkDataGraph>(delegate(BulkDataGraph obj) { Frame.Clear(); });
            }


            #region 参数
            private int bm;
            /// <summary>
            /// 标记, 当bm &gt;0 为bookmark，当bm &lt;=0 为往前面数
            /// </summary>
            public int BM
            {
                get
                {
                    return bm;
                }
                set
                {

                    if (bm != value)
                    {
                        bm = value;
                        NotifyPropertyChanged("BM");
                        NotifyRegistEvent();
                    }
                }
            }
            #endregion
            #region 返回结果
            private FR_DATA_TYPE type;
            /// <summary>
            /// 结果.数据是否有效
            /// </summary>
            public FR_DATA_TYPE Type
            {
                get
                {
                    return type;
                }
                set
                {
                    type = value;
                    NotifyPropertyChanged("Type");
                }
            }

            private int bookmark;
            /// <summary>
            /// 结果对应的 bookmark
            /// </summary>
            public int BookMark
            {
                get
                {
                    return bookmark;
                }
                set
                {
                    bookmark = value;
                    NotifyPropertyChanged("BookMark");
                    NotifyPropertyChanged("Info");
                }
            }
            private DateTime dt;
            /// <summary>
            /// 结果对应的 时间
            /// </summary>
            public DateTime TimeMark
            {
                get
                {
                    return dt;
                }
                set
                {
                    dt = value;
                    NotifyPropertyChanged("TimeMark");
                    NotifyPropertyChanged("Info");
                }
            }
            public string Info
            {
                get
                {
                    return "<" + BookMark.ToString() + "> " + TimeMark.ToShortTimeString();
                }
            }
            private ObservableCollection<int> frame = new ObservableCollection<int>();
            /// <summary>
            /// 会动态更新，界面只要绑定就好了
            /// </summary>
            public ObservableCollection<int> Frame
            {
                get
                {
                    return frame;
                }
            }
            #endregion
            /// <summary>
            /// 复制数据到 g
            /// </summary>
            /// <param name="g"></param>
            public override void CopyTo(BulkDataGraph g)
            {
                BulkDataGraphFrame graph = g as BulkDataGraphFrame;
                graph.BookMark = BookMark;
                graph.TimeMark = TimeMark;
                graph.Type = Type;
                graph.Frame.Clear();
                foreach (var i in Frame)
                {
                    graph.Frame.Add(i);
                }
                NotifyUpdateEvent();
            }

            public override bool IsEquals(object obj)
            {
                if (obj is BulkDataGraphFrame)
                {
                    BulkDataGraphFrame g = obj as BulkDataGraphFrame;

                    if ((g.BM == BM) && (g.Mix == Mix))
                    {
                        return true;
                    }
                    return false;
                }
                else if (obj is BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataReturn)
                {
                    BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataReturn g = obj as BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataReturn;
                    if ((g.bm == BM) && (g.mix == Mix))
                    {
                        return true;
                    }
                    return false;
                }
                return false;
            }
            public override void Update(object obj)
            {
                if (obj is BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataReturn)
                {
                    BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataReturn pack = obj as BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataReturn;

                    BookMark = pack.bookmark;//结果对应的 bookmark
                    TimeMark = pack.dt;//结果对应的 时间
                    Type = pack.type;//结果.数据是否有效
                    if (BookMark == 1) 
                    {
                    
                    }
                    if (BookMark != -1)
                    {
                        for (int i = Frame.Count - 1; i < pack.toBoltIndex; i++)
                        {
                            Frame.Add(Misc.MyBase.NULL_VALUE);
                        }
                        for (int i = 0; i < pack.result.Length; i++)
                        {
                            Frame[pack.fromBoltIndex + i] = pack.result[i];
                        }
                    }
                    else
                    {
                        Frame.Clear();
                    }
                    NotifyUpdateEvent();
                }
            }
        }


        /// <summary>
        /// 横向扫描数据请求与结果
        /// </summary>
        public class BulkDataGraphFrameMix : BulkDataGraph
        {
            public override string ToString()
            {
                return "BM = " + BM.ToString() + "(" + BookMark.ToString() + ")";
            }
            public BulkDataGraphFrameMix()
            {
                //this.RegistEvent += new Action<BulkDataGraph>(delegate(BulkDataGraph obj) { Frame.Clear(); });
            }


            #region 参数
            private int bm;
            /// <summary>
            /// 标记, 当bm &gt;0 为bookmark，当bm &lt;=0 为往前面数
            /// </summary>
            public int BM
            {
                get
                {
                    return bm;
                }
                set
                {

                    if (bm != value)
                    {
                        bm = value;
                        NotifyPropertyChanged("BM");
                        NotifyRegistEvent();
                    }
                }
            }

            private DateTime start_dt;
            /// <summary>
            /// 要求的开始时间
            /// </summary>
            public DateTime StartDT
            {
                get
                {
                    return start_dt;
                }
                set
                {
                    start_dt = value;
                    NotifyPropertyChanged("StartDT");
                    NotifyRegistEvent();
                }
            }




            #endregion
            #region 返回结果
            private FR_DATA_TYPE type;
            /// <summary>
            /// 结果.数据是否有效
            /// </summary>
            public FR_DATA_TYPE Type
            {
                get
                {
                    return type;
                }
                set
                {
                    type = value;
                    NotifyPropertyChanged("Type");
                }
            }

            private int bookmark;
            /// <summary>
            /// 结果对应的 bookmark
            /// </summary>
            public int BookMark
            {
                get
                {
                    return bookmark;
                }
                set
                {
                    bookmark = value;
                    NotifyPropertyChanged("BookMark");
                    NotifyPropertyChanged("Info");
                }
            }
            private DateTime dt;
            /// <summary>
            /// 结果对应的 时间
            /// </summary>
            public DateTime TimeMark
            {
                get
                {
                    return dt;
                }
                set
                {
                    dt = value;
                    NotifyPropertyChanged("TimeMark");
                    NotifyPropertyChanged("Info");
                }
            }
            private DateTime act_start_dt;
            /// <summary>
            /// 实际的开始时间
            /// </summary>
            public DateTime ActStartDT
            {
                get
                {
                    return act_start_dt;
                }
                set
                {
                    act_start_dt = value;
                    NotifyPropertyChanged("ActStartDT");
                    NotifyPropertyChanged("Info");
                }
            }
            public string Info
            {
                get
                {
                    if (ActStartDT != TimeMark)
                    {
                        return "<" + BookMark.ToString() + "> " + ActStartDT.ToShortTimeString() + "-" + TimeMark.ToShortTimeString();
                    }
                    else
                    {
                        return "<" + BookMark.ToString() + "> " + TimeMark.ToShortTimeString();
                    }
                }
            }
            private ObservableCollection<FrameDataCell> frame = new ObservableCollection<FrameDataCell>();
            /// <summary>
            /// 会动态更新，界面只要绑定就好了
            /// </summary>
            public ObservableCollection<FrameDataCell> Frame
            {
                get
                {
                    return frame;
                }
            }
            #endregion
            /// <summary>
            /// 复制数据到 g
            /// </summary>
            /// <param name="g"></param>
            public override void CopyTo(BulkDataGraph g)
            {
                BulkDataGraphFrameMix graph = g as BulkDataGraphFrameMix;
                graph.BookMark = BookMark;
                graph.TimeMark = TimeMark;
                graph.StartDT = StartDT;
                graph.ActStartDT = ActStartDT;
                graph.Type = Type;
                graph.Frame.Clear();
                foreach (var i in Frame)
                {
                    graph.Frame.Add(i);
                }
                NotifyUpdateEvent();
            }

            public override bool IsEquals(object obj)
            {
                if (obj is BulkDataGraphFrameMix)
                {
                    BulkDataGraphFrameMix g = obj as BulkDataGraphFrameMix;

                    if ((g.BM == BM) && (g.Mix == Mix) && (g.StartDT == StartDT))
                    {
                        return true;
                    }
                    return false;
                }
                else if (obj is Pack_CallGetFrameDataMixReponse)
                {
                    Pack_CallGetFrameDataMixReponse g = obj as Pack_CallGetFrameDataMixReponse;
                    if ((g.bm == BM) && (g.mix == Mix) && (g.start_dt == StartDT))
                    {
                        return true;
                    }
                    return false;
                }
                return false;
            }
            public override void Update(object obj)
            {
                if (obj is Pack_CallGetFrameDataMixReponse)
                {
                    Pack_CallGetFrameDataMixReponse pack = obj as Pack_CallGetFrameDataMixReponse;

                    BookMark = pack.bookmark;//结果对应的 bookmark
                    TimeMark = pack.dt;//结果对应的 时间
                    ActStartDT = pack.act_startDt;//结果对应的 实际开始时间
                    Type = pack.type;//结果.数据是否有效
                    if (BookMark == 1)
                    {

                    }
                    if (BookMark != -1)
                    {
                        for (int i = Frame.Count - 1; i < pack.toBoltIndex; i++)
                        {
                            Frame.Add(new FrameDataCell() { Avg = Misc.MyBase.NULL_VALUE, Sigma = Misc.MyBase.NULL_VALUE });
                        }
                        for (int i = 0; i < pack.result.Length; i++)
                        {
                            Frame[pack.fromBoltIndex + i] = pack.result[i];
                        }
                    }
                    else
                    {
                        Frame.Clear();
                    }
                    NotifyUpdateEvent();
                }
            }
        }
        /// <summary>
        /// 纵向扫描数据
        /// </summary>
        public class BulkDataGraphTrend : BulkDataGraph
        {
            public override string ToString()
            {
                return "[" + FromBoltNo.ToString() + "," + ToBoltNo.ToString() + "]";
            }
            public BulkDataGraphTrend()
            {
                this.RegistEvent += new Action<BulkDataGraph>(delegate(BulkDataGraph obj) { Frame.Clear(); });
            }


            #region 参数
            private int len = 120;
            /// <summary>
            /// 获取的长度， types最大体积保持在 len内
            /// </summary>
            public int Len
            {
                get
                {
                    return len;

                }
                set
                {

                    len = value;
                    NotifyPropertyChanged("Len");
                    NotifyRegistEvent();

                }

            }

            private int fromBoltNo;
            /// <summary>
            /// 开始分区no
            /// </summary>
            public int FromBoltNo
            {
                set
                {
                    if (fromBoltNo != value)
                    {
                        fromBoltNo = value;
                        NotifyPropertyChanged("FromBoltNo");

                        NotifyRegistEvent();
                    }
                }
                get
                {
                    return fromBoltNo;
                }
            }
            private int toBoltNo;
            /// <summary>
            /// /结束分区no
            /// </summary>
            public int ToBoltNo
            {
                set
                {
                    if (toBoltNo != value)
                    {
                        toBoltNo = value;
                        NotifyPropertyChanged("ToBoltIndex");
                        NotifyRegistEvent();
                    }
                }
                get
                {
                    return toBoltNo;
                }
            }
            #endregion
            #region 返回结果
            private ObservableCollection<TrendDataCell> frame = new ObservableCollection<TrendDataCell>();//
            /// <summary>
            /// 会动态更新，界面只要绑定就好了
            /// </summary>
            public ObservableCollection<TrendDataCell> Frame
            {
                get
                {
                    return frame;
                }
            }
            #endregion

            public override bool IsEquals(object obj)
            {
                if (obj is BulkDataGraphTrend)
                {
                    BulkDataGraphTrend g = obj as BulkDataGraphTrend;
                    if ((g.Mix == Mix) &&
                        (g.Len == Len))
                    {
                        if (((g.FromBoltNo == Misc.MyBase.NULL_VALUE) || (g.ToBoltNo == Misc.MyBase.NULL_VALUE)) &&
                            ((FromBoltNo == Misc.MyBase.NULL_VALUE) || (ToBoltNo == Misc.MyBase.NULL_VALUE)))
                        {
                            return true;
                        }

                        if ((g.FromBoltNo == FromBoltNo) &&
                            (g.ToBoltNo == ToBoltNo))
                        {
                            return true;
                        }
                        return false;
                    }

                    return false;
                }
                else if (obj is BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataReturn)
                {
                    BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataReturn g = obj as BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataReturn;
                    if ((g.mix == Mix) &&
                        (g.len == Len))
                    {
                        if (((g.fromBoltNo == Misc.MyBase.NULL_VALUE) || (g.toBoltNo == Misc.MyBase.NULL_VALUE)) &&
                            ((FromBoltNo == Misc.MyBase.NULL_VALUE) || (ToBoltNo == Misc.MyBase.NULL_VALUE)))
                        {
                            return true;
                        }

                        if ((g.fromBoltNo == FromBoltNo) &&
                            (g.toBoltNo == ToBoltNo))
                        {
                            return true;
                        }
                        return false;
                    }
                    return false;
                }
                return false;
            }
            public override void Update(object obj)
            {
                if (obj is BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataReturn)
                {
                    BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataReturn pack = obj as BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataReturn;
                    if(pack.result!=null)
                    {
                        //接收的数据是从后先前排的。 pack.result[0] 是最新的数据
                        //Frame 是从前向后排的，Frame.Last() 是最新的数据

                        //position pack.result 这数列放入 Frame 的位置
                        int position = Frame.Count - 1 - (pack.result.Length - 1 - pack.edit_position);
                        if (position < 0) position = 0;

                        int cnt = Frame.Count;

                        for (int i = position, j = 0; j < pack.result.Length; i++, j++)
                        {
                            int idx = pack.result.Length - 1 - j;
                            if (i < cnt)
                            {
                                Frame[i] = pack.result[idx];
                            }
                            else
                            {
                                Frame.Add(pack.result[idx]);
                            }
                        }

                        while (Frame.Count > Len)
                        {
                            Frame.RemoveAt(0);
                        }
                    }
                    else
                    {
                        Frame.Clear();
                    }
                    NotifyUpdateEvent();
                }
            }
            public override void CopyTo(BulkDataGraph g)
            {
                BulkDataGraphTrend graph = g as BulkDataGraphTrend;
                graph.Frame.Clear();
                foreach (var i in Frame)
                {
                    graph.Frame.Add(i);
                }
                NotifyUpdateEvent();
            }
        }
        /// <summary>
        /// 横向扫描数据请求与结果 最新数据
        /// </summary>
        public class BulkDataGraphNewFrame : BulkDataGraph
        {
            public override string ToString()
            {
                return "(" + BookMark.ToString() + ")";
            }
            public BulkDataGraphNewFrame()
            {
                //this.RegistEvent += new Action<BulkDataGraph>(delegate(BulkDataGraph obj) { Frame.Clear(); });
            }

            #region 参数

            #endregion
            #region 返回结果
            private FR_DATA_TYPE type;
            /// <summary>
            /// 结果.数据是否有效
            /// </summary>
            public FR_DATA_TYPE Type
            {
                get
                {
                    return type;
                }
                set
                {
                    type = value;
                    NotifyPropertyChanged("Type");
                }
            }

            private int bookmark;
            /// <summary>
            /// 结果对应的 bookmark
            /// </summary>
            public int BookMark
            {
                get
                {
                    return bookmark;
                }
                set
                {
                    bookmark = value;
                    NotifyPropertyChanged("BookMark");
                    NotifyPropertyChanged("Info");
                }
            }
            private DateTime dt;
            /// <summary>
            /// 结果对应的 时间
            /// </summary>
            public DateTime TimeMark
            {
                get
                {
                    return dt;
                }
                set
                {
                    dt = value;
                    NotifyPropertyChanged("TimeMark");
                    NotifyPropertyChanged("Info");
                }
            }
            public string Info
            {
                get
                {
                    return "<" + BookMark.ToString() + "> " + TimeMark.ToShortTimeString();
                }
            }
            private ObservableCollection<int> frame = new ObservableCollection<int>();
            /// <summary>
            /// 会动态更新，界面只要绑定就好了
            /// </summary>
            public ObservableCollection<int> Frame
            {
                get
                {
                    return frame;
                }
            }
            #endregion
            /// <summary>
            /// 复制数据到 g
            /// </summary>
            /// <param name="g"></param>
            public override void CopyTo(BulkDataGraph g)
            {
                BulkDataGraphNewFrame graph = g as BulkDataGraphNewFrame;
                graph.BookMark = BookMark;
                graph.TimeMark = TimeMark;
                graph.Type = Type;
                graph.Frame.Clear();
                foreach (var i in Frame)
                {
                    graph.Frame.Add(i);
                }
                NotifyUpdateEvent();
            }

            public override bool IsEquals(object obj)
            {
                if (obj is BulkDataGraphNewFrame)
                {
                    BulkDataGraphNewFrame g = obj as BulkDataGraphNewFrame;

                    if (g.Mix == Mix)
                    {
                        return true;
                    }
                    return false;
                }
                else if (obj is BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn)
                {
                    BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn g = obj as BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn;
                    if (g.mix == Mix)
                    {
                        return true;
                    }
                    return false;
                }
                return false;
            }
            public override void Update(object obj)
            {
                if (obj is BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn)
                {
                    BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn pack = obj as BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn;

                    BookMark = pack.bookmark;//结果对应的 bookmark
                    TimeMark = pack.dt;//结果对应的 时间
                    Type = pack.type;//结果.数据是否有效
                    if(pack.result!=null && pack.result.Length>0)
                   {
                        for (int i = 0; i < pack.result.Length; i++)
                        {
                            while (i >= Frame.Count())
                                Frame.Add(Misc.MyBase.NULL_VALUE);
                            
                            Frame[i] = pack.result[i];
                        }
                    }
                    else
                    {
                        Frame.Clear();
                    }
                    NotifyUpdateEvent();
                }
            }
        }
        ObservableCollection<BulkDataGraph> mGraphs = new ObservableCollection<BulkDataGraph>();

        void Regist(BulkDataGraph graph) 
        {
            if (graph is BulkDataGraphFrame) 
            {
                BulkDataGraphFrame graph_frame = graph as BulkDataGraphFrame;
                bulkdata.GetFrameData(
                    new BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataParam()
                    {
                        NeedPush = true,
                        bm = graph_frame.BM,
                        mix = graph_frame.Mix
                    },
                    delegate(object AsyncState, object retData)
                    {
                        BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataReturn reponse = retData as BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataReturn;
                        //找出所有graph,更新
                     
                        var gl = from g in mGraphs where g.IsEquals(reponse) select g;
                        if (gl.Count() == 0)
                        {
                            //接收到没有要求的推送，取消推送请求
                            UnRegist(
                            new BulkDataGraphFrame()
                            {
                                Mix = reponse.mix,
                                BM = reponse.bm
                            });
                        }
                        else
                        {
                            foreach (BulkDataGraphFrame g in gl)
                            {
                                g.Update(reponse);
                            }
                        }
                    }, this);
            }
            else if (graph is BulkDataGraphFrameMix)
            {
                BulkDataGraphFrameMix graph_frame = graph as BulkDataGraphFrameMix;
                bulkdata.GetFrameDataMix(
                    new Pack_CallGetFrameDataMixRequest()
                    {
                        NeedPush = true,
                        bm = graph_frame.BM,
                        mix = graph_frame.Mix,
                        start_dt = graph_frame.StartDT
                    },
                    delegate (object AsyncState, object retData)
                    {
                        Pack_CallGetFrameDataMixReponse reponse = retData as Pack_CallGetFrameDataMixReponse;
                        //找出所有graph,更新

                        var gl = from g in mGraphs where g.IsEquals(reponse) select g;
                        if (gl.Count() == 0)
                        {
                            //接收到没有要求的推送，取消推送请求
                            UnRegist(
                            new BulkDataGraphFrameMix()
                            {
                                Mix = reponse.mix,
                                BM = reponse.bm,
                                StartDT = reponse.start_dt
                            });
                        }
                        else
                        {
                            foreach (BulkDataGraphFrameMix g in gl)
                            {
                                g.Update(reponse);
                            }
                        }
                    }, this);
            }
            else if (graph is BulkDataGraphTrend) 
            {
                BulkDataGraphTrend graph_trend = graph as BulkDataGraphTrend;
                bulkdata.GetTrendData(
                    new BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataParam()
                    {
                        NeedPush = true,
                        len = graph_trend.Len,
                        mix = graph_trend.Mix,
                        fromBoltNo = graph_trend.FromBoltNo,
                        toBoltNo = graph_trend.ToBoltNo
                    },
                    delegate(object AsyncState, object retData)
                    {
                        BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataReturn reponse = retData as BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataReturn;
                        
                        //找出所有graph,更新
                        var gl = from g in mGraphs where g.IsEquals(reponse) select g;
                        if (gl.Count() == 0)
                        {
                            UnRegist(
                                //接收到没有要求的推送，取消推送请求
                            new BulkDataGraphTrend()
                            {
                                Mix = reponse.mix,
                                Len = reponse.len,
                                FromBoltNo = reponse.fromBoltNo,
                                ToBoltNo = reponse.toBoltNo
                            });
                        }
                        else
                        {
                            foreach (BulkDataGraphTrend g in gl)
                            {
                                g.Update(reponse);
                            }
                        }
                    }, this);
            }
            else if (graph is BulkDataGraphNewFrame)
            {
                BulkDataGraphNewFrame graph_frame = graph as BulkDataGraphNewFrame;
                bulkdata.PushNewFrameData(
                    new BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataParam()
                    {
                        mix = graph_frame.Mix
                    },
                    delegate(object AsyncState, object retData)
                    {
                        BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn reponse = retData as BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn;
                        //找出所有graph,更新

                        var gl = from g in mGraphs where g.IsEquals(reponse) select g;
                        if (gl.Count() == 0)
                        {
                            //接收到没有要求的推送，取消推送请求
                            UnRegist(
                            new BulkDataGraphNewFrame()
                            {
                                Mix = reponse.mix
                            });
                        }
                        else
                        {
                            foreach (BulkDataGraphNewFrame g in gl)
                            {
                                g.Update(reponse);
                            }
                        }
                    }, this);
            }
        }
        void UnRegist(BulkDataGraph graph) 
        {
            if (graph is BulkDataGraphFrame)
            {
                BulkDataGraphFrame graph_frame = graph as BulkDataGraphFrame;
                bulkdata.ClosePushFrameData(
                    new BULKDATA_OBJ_INTERFACE.Pack_CallClosePushFrameData()
                    {
                        bm = graph_frame.BM,
                        mix = graph_frame.Mix
                    },this);
            }
            else if (graph is BulkDataGraphFrameMix)
            {
                BulkDataGraphFrameMix graph_frame = graph as BulkDataGraphFrameMix;
                bulkdata.ClosePushFrameDataMix(
                    new Pack_CallClosePushFrameDataMixRequest()
                    {
                        bm = graph_frame.BM,
                        mix = graph_frame.Mix,
                        start_dt = graph_frame.StartDT
                    }, this);
            }
            else if (graph is BulkDataGraphTrend)
            {
                BulkDataGraphTrend graph_trend = graph as BulkDataGraphTrend;
                bulkdata.ClosePushTrendData(
                    new BULKDATA_OBJ_INTERFACE.Pack_CallClosePushTrendData()
                    {
                        mix = graph_trend.Mix,
                        fromBoltNo =graph_trend.FromBoltNo,
                        toBoltNo = graph_trend.ToBoltNo
                    }, this);
            }
            else if (graph is BulkDataGraphNewFrame)
            {
                BulkDataGraphNewFrame graph_trend = graph as BulkDataGraphNewFrame;
                bulkdata.ClosePushNewFrameData(
                    new BULKDATA_OBJ_INTERFACE.Pack_CallClosePushNewFrameData()
                    {
                        mix = graph_trend.Mix
                    }, this);
            }
        }
        void _Add(BulkDataGraph graph)
        {
            //检测列表中是否已经有一样的graph
            //有的话，直接把数据复制过来
            var gl = from g in mGraphs where g.IsEquals(graph) select g;

            if (gl.Count() > 0)
            {
                //有相同数据，直接把数据复制过来
                gl.ElementAt(0).CopyTo(graph);
                mGraphs.Add(graph);
            }
            else
            {
                mGraphs.Add(graph);

                //没有, 需要向服务器注册
                if (bulkdata.IsConnected)
                {
                    Regist(graph);
                }
            }
        }
        public void Add(BulkDataGraph graph)
        {
            _Add(graph);
            graph.RegistEvent +=new Action<BulkDataGraph>(graph_RegistEvent);
        }

        void graph_RegistEvent(BulkDataGraph obj)
        {
            //当数据被修改，应该重新注册
            //数据已被修改，没法找到原来的数据，只能接收到推送时，发现不存在，把它删除

            mGraphs.Remove(obj);
            _Add(obj);
        }

        public void Remove(BulkDataGraph graph)
        {
            //检测列表是否只有一个graph
            //当只有一个，需要向服务器解除注册
            var gl = from g in mGraphs where g.IsEquals(graph) select g;
            if (gl.Count() == 1)
            {
                if (bulkdata.IsConnected)
                {
                    UnRegist(graph);
                }
            }

            mGraphs.Remove(graph);
        }

        public void Clear()
        {
            bulkdata.Clear();
        }
    }
}
