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

using System.ComponentModel;
using System.Collections.ObjectModel;

using FObjBase;
using FLY.Thick.Base.IService;
using FLY.Thick.Base.OBJ_INTERFACE;
using FLY.Thick.Base.Common;

namespace FLY.Thick.Base.Client
{
    public class ScanCorrServiceClient : FObj,IScanCorrService
    {
        UInt32 mServerID;
        IFConn mConn;

        public ScanCorrServiceClient(UInt32 id)
        {
            mServerID = id;
            this.PropertyChanged += new PropertyChangedEventHandler(ScanCorrService_PropertyChanged);
        }

        void ScanCorrService_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Enable") 
            {
                CurrObjSys.SetValueEx(
                   mConn, mServerID, ID, 
                   SCANCORR_OBJ_INTERFACE.SET_ENABLE,
                   new SCANCORR_OBJ_INTERFACE.Pack_Enable() { enable = Enable }.ToBytes()
                   );
            }
        }

        #region private成员变量
        private bool enable;
        private int progress;
        private bool ing;
        private int scantimer;
        private int smoothfactor;
        
        #endregion
        #region IScanCorrService 成员

        
        public bool Enable { get; set; }
        
        public int Progress { get; set; }
        

        public bool Ing { get; set; }
        
        public int ScanTimer { get; set; }

        public int SmoothFactor { get; set; }
        
        /// <summary>
        /// 有效范围.开始，单位脉冲
        /// </summary>
        public int ValidBegin { get; set; }
        
        
        /// <summary>
        /// 有效范围.结束，单位脉冲
        /// </summary>
        public int ValidEnd { get; set; } = 8000;
        

        
        public int PosOfGrid { get; set; } = 10;
        
        public int PosLen { get; set; } = 8000;
        

        public IScanCorrGroup Group0 { get; } = new ScanCorrGroup();
        
        public IScanCorrGroup Group1 { get; } = new ScanCorrGroup();
        #endregion
        public void Smooth(int groupindex) 
        {
            CurrObjSys.CallFunctionEx(
               mConn, mServerID, ID, 
               SCANCORR_OBJ_INTERFACE.CALL_SMOOTH,
               new SCANCORR_OBJ_INTERFACE.Pack_CallStart() { 
                   groupindex = groupindex, 
                   smoothfactor = SmoothFactor }.ToBytes());
                   
        }
        public void Start(int groupindex) 
        {

            CurrObjSys.CallFunctionEx(
                mConn, mServerID, ID, 
                SCANCORR_OBJ_INTERFACE.CALL_START,
                new SCANCORR_OBJ_INTERFACE.Pack_CallStart() { 
                    scantimer = ScanTimer, 
                    groupindex = groupindex, 
                    smoothfactor = SmoothFactor }.ToBytes());
        }
        public void Clear(int groupindex) 
        {
            CurrObjSys.CallFunctionEx(
               mConn, mServerID, ID, 
               SCANCORR_OBJ_INTERFACE.CALL_CLEAR,
               BitConverter.GetBytes(groupindex)
               );    
        }
        public void Apply() 
        {
            SCANCORR_OBJ_INTERFACE.Pack_ValidRange p = new SCANCORR_OBJ_INTERFACE.Pack_ValidRange();
            p.begin = ValidBegin;
            p.end = ValidEnd;
            CurrObjSys.SetValueEx(
                mConn, mServerID, ID, 
                SCANCORR_OBJ_INTERFACE.SET_VALIDRANGE,
                p.ToBytes());
        }
        public override void Dispose()
        {
            CurrObjSys.ObjRemove(
                this, mConn);
        }
        public override void ConnectNotify(IFConn from)
        {
            mConn = from;
            if (from.IsConnected) 
            {
                CurrObjSys.SenseConfigEx(
                    mConn, mServerID, ID, 0xffffffff, SENSE_CONFIG.ADD);

                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID, 
                    SCANCORR_OBJ_INTERFACE.GET_PROGRESS);


                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID, 
                    SCANCORR_OBJ_INTERFACE.GET_ENABLE);


                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID, 
                    SCANCORR_OBJ_INTERFACE.GET_START_PARAMS);


                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID, 
                    SCANCORR_OBJ_INTERFACE.GET_GROUP_PARAMS);


                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID, 
                    SCANCORR_OBJ_INTERFACE. GET_GROUP0_FORW);


                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID, 
                    SCANCORR_OBJ_INTERFACE.GET_GROUP0_BACKW);


                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID, 
                    SCANCORR_OBJ_INTERFACE.GET_GROUP1_FORW);


                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID, 
                    SCANCORR_OBJ_INTERFACE.GET_GROUP1_BACKW);

                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID,
                    SCANCORR_OBJ_INTERFACE.GET_VALIDRANGE);
            }
        }
        public override void PushGetValue(IFConn from, uint srcid, ushort memid, byte[] infodata)
        {
            PushInfo(from, srcid, memid, infodata);
        }
        public override void PushInfo(IFConn from, uint srcid, ushort infoid, byte[] infodata)
        {
            switch (infoid) 
            {
                case SCANCORR_OBJ_INTERFACE.PUSH_PROGRESS: 
                    {
                        SCANCORR_OBJ_INTERFACE.Pack_GetState p = new SCANCORR_OBJ_INTERFACE.Pack_GetState();
                        p.TryParse(infodata);
                        Progress = p.progress;
                        Ing = p.ing;
                    }break;
                case SCANCORR_OBJ_INTERFACE.PUSH_ENABLE:
                    {
                        SCANCORR_OBJ_INTERFACE.Pack_Enable p = new SCANCORR_OBJ_INTERFACE.Pack_Enable();
                        p.TryParse(infodata);
                        Enable = p.enable;

                    }break;
                case SCANCORR_OBJ_INTERFACE.PUSH_START_PARAMS:
                    {
                        SCANCORR_OBJ_INTERFACE.Pack_StartParams p = new SCANCORR_OBJ_INTERFACE.Pack_StartParams();
                        p.TryParse(infodata);
                        SmoothFactor = p.smoothfactor;
                        ScanTimer = p.scantimer;
                        PosOfGrid = p.posofgrid;
                        PosLen = p.poslen;
                    }break;
                case SCANCORR_OBJ_INTERFACE.GET_GROUP_PARAMS:
                    {
                        SCANCORR_OBJ_INTERFACE.Pack_GroupParams p = new SCANCORR_OBJ_INTERFACE.Pack_GroupParams();
                        p.TryParse(infodata);
                        Group0.AvgAD = p.avgad0;
                        Group1.AvgAD = p.avgad1;

                    }break;
                case SCANCORR_OBJ_INTERFACE.PUSH_GROUP0_FORW:
                    {
                        SCANCORR_OBJ_INTERFACE.Pack_Data p = new SCANCORR_OBJ_INTERFACE.Pack_Data();
                        if (p.TryParse(infodata))
                        {
                            ((ScanCorrGroup)Group0).UpdateForwDatas(p.data);
                        }
                    }break;
                case SCANCORR_OBJ_INTERFACE.PUSH_GROUP0_BACKW:
                    {
                        SCANCORR_OBJ_INTERFACE.Pack_Data p = new SCANCORR_OBJ_INTERFACE.Pack_Data();
                        if (p.TryParse(infodata))
                        {
                            ((ScanCorrGroup)Group0).UpdateBackwDatas(p.data);
                        }
                    } break;
                case SCANCORR_OBJ_INTERFACE.PUSH_GROUP1_FORW:
                    {
                        SCANCORR_OBJ_INTERFACE.Pack_Data p = new SCANCORR_OBJ_INTERFACE.Pack_Data();
                        if (p.TryParse(infodata))
                        {
                            ((ScanCorrGroup)Group1).UpdateForwDatas(p.data);
                        }
                    } break;
                case SCANCORR_OBJ_INTERFACE.PUSH_GROUP1_BACKW:
                    {
                        SCANCORR_OBJ_INTERFACE.Pack_Data p = new SCANCORR_OBJ_INTERFACE.Pack_Data();
                        if (p.TryParse(infodata))
                        {
                            ((ScanCorrGroup)Group1).UpdateBackwDatas(p.data);
                        }
                    } break;
                case SCANCORR_OBJ_INTERFACE.PUSH_VALIDRANGE:
                    {
                        SCANCORR_OBJ_INTERFACE.Pack_ValidRange p = new SCANCORR_OBJ_INTERFACE.Pack_ValidRange();
                        if (p.TryParse(infodata))
                        {
                            ValidBegin = p.begin;
                            ValidEnd = p.end;
                        }
                    }break;
            }
        }
        #region INotifyPropertyChanged 成员
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion




    }
    public class ScanCorrGroup :IScanCorrGroup
    {
        private int _avgad = -1;
        /// <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; }
        }
        public void UpdateForwDatas(List<int> data)
        {
            ForwDatas.Clear();
            ForwDatas.AddRange(data);

            NotifyPropertyChanged("ForwDatas");
        }
        public void UpdateBackwDatas(List<int> data) 
        {
            BackwDatas.Clear();
            BackwDatas.AddRange(data);
            NotifyPropertyChanged("BackwDatas");
        }
        private List<int> backwdatas = new List<int>();

        /// <summary>
        /// 反方向机架AD值数据, grid数据
        /// </summary>
        public List<int> BackwDatas { get { return backwdatas; } }
        public ScanCorrGroup() 
        {

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

        #endregion


    }
    
}
