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

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 FlyADServiceClient : FObj, IFlyADService
    {
        IFConn mConn;
        UInt32 mServerID;

        public FlyADServiceClient(UInt32 id)
        {
            mServerID = id;
        }

        #region IFlyAD接口

        private IPEndPoint ep = new IPEndPoint(IPAddress.Parse("192.168.251.10"), 20006);
        public IPEndPoint EP
        {
            get
            {
                return ep;
            }
            set
            {
                if (!IPEndPoint.Equals(ep, value))
                {
                    ep = value;
                    NotifyPropertyChanged("EP");
                }
            }
        }
        bool hascrc = false;
        public bool HasCRC
        {
            get
            {
                return hascrc;
            }
            set
            {
                if (hascrc != value)
                {
                    hascrc = value;
                    NotifyPropertyChanged("HasCRC");
                }
            }
        }

        private int gridsmooth = 0;
        /// <summary>
        /// grid数据平滑
        /// </summary>
        public int GridSmooth
        {
            get { return gridsmooth; }
            set
            {
                if (value < 0)
                    value = 0;
                if (gridsmooth != value)
                {
                    gridsmooth = value;
                    NotifyPropertyChanged("GridSmooth");
                }
            }
        }
        private int poslen;
        public int PosLen
        {
            get { return poslen; }
            set
            {
                if (poslen != value)
                {
                    poslen = value;
                    NotifyPropertyChanged("PosLen");
                }
            }
        }
        private MOTORTYPE motortype = MOTORTYPE.SERVO;
        public MOTORTYPE MotorType
        {
            get { return motortype; }
            set
            {
                if (motortype != value)
                {
                    motortype = value;
                    NotifyPropertyChanged("MotorType");
                }
            }
        }
        private int posofgrid;
        /// <summary>
        /// // 单位 pulse/grid
        /// </summary>
        public int PosOfGrid
        {
            get { return posofgrid; }
            set
            {
                if (posofgrid != value)
                {
                    posofgrid = value;
                    NotifyPropertyChanged("PosOfGrid");
                }
            }
        }
        private UInt16 ratio01;
        public UInt16 Ratio01
        {
            get { return ratio01; }
            set
            {
                if (ratio01 != value)
                {
                    ratio01 = value;
                    NotifyPropertyChanged("Ratio01");
                }
            }
        }
        private UInt16 ratio02;
        public UInt16 Ratio02
        {
            get { return ratio02; }
            set
            {
                if (ratio02 != value)
                {
                    ratio02 = value;
                    NotifyPropertyChanged("Ratio02");
                }
            }
        }
        private Int16 posoffset;
        public Int16 PosOffset
        {
            get
            {
                return posoffset;
            }
            set
            {
                if (posoffset != value)
                {
                    posoffset = value;
                    NotifyPropertyChanged("PosOffset");
                }
            }
        }//脉冲平移
        private UInt32 jogvelocity;
        public UInt32 JogVelocity
        {
            get
            {
                return jogvelocity;
            }
            set
            {
                if (jogvelocity != value)
                {
                    jogvelocity = value;
                    NotifyPropertyChanged("JogVelocity");
                }
            }
        }
        public void Apply() 
        {
            FLYAD_OBJ_INTERFACE.Pack_Params p = new FLYAD_OBJ_INTERFACE.Pack_Params()
            {
                ep = EP,
                posofgrid = (UInt16)PosOfGrid,
                motortype = MotorType,
                poslen = PosLen,
                ratio01 = Ratio01,
                ratio02 = Ratio02,
                posoffset = PosOffset,
                jogvelocity = JogVelocity,
                hasCRC = HasCRC,
                gridsmooth = GridSmooth
            };
            CurrObjSys.SetValueEx(mConn, mServerID, ID,
                FLYAD_OBJ_INTERFACE.SET_PARAMS,
                p.ToBytes());
        }
        /// <summary>
        /// 获取序列码
        /// </summary>
        /// <param name="AsyncDelegate">返回类型为 AccessInfo</param>
        /// <param name="AsyncState">可为null</param>
        public void GetAccessInfo(AsyncCBHandler AsyncDelegate, object AsyncState)
        {
            CurrObjSys.CallFunctionEx(mConn, mServerID, ID,
                FLYAD_OBJ_INTERFACE.CALL_GETACCESSINFO,
                null, AsyncDelegate, AsyncState);
        }
        /// <summary>
        /// 设置授权码
        /// </summary>
        /// <param name="access">授权码</param>
        /// <param name="AsyncDelegate">返回类型为 AccessInfo</param>
        /// <param name="AsyncState">可为null</param>
        public void SetAccess(byte[] access, AsyncCBHandler AsyncDelegate, object AsyncState)
        {
            CurrObjSys.CallFunctionEx(mConn, mServerID, ID,
                FLYAD_OBJ_INTERFACE.CALL_SETACCESS,
                new FLYAD_OBJ_INTERFACE.Pack_SetAccessRequest() { data = access }.ToBytes(),
                AsyncDelegate, AsyncState);
        }

        /// <summary>
        /// 获取grid
        /// </summary>
        /// <param name="direction">方向</param>
        /// <param name="AsyncDelegate">返回类型为 GridInfo</param>
        /// <param name="AsyncState">可为null</param>
        public void GetGrid(Misc.DIRECTION direction, AsyncCBHandler AsyncDelegate, object AsyncState) 
        {
            CurrObjSys.CallFunctionEx(mConn, mServerID, ID,
                FLYAD_OBJ_INTERFACE.CALL_GETGRID,
                new FLYAD_OBJ_INTERFACE.Pack_GetGridRequest() { direction = direction}.ToBytes(),
                AsyncDelegate, AsyncState);
        }


        
        #endregion


        public override void Dispose()
        {
            CurrObjSys.ObjRemove(
                this, mConn);
        }
        public override void ConnectNotify(IFConn from)
        {
            mConn = from;
            if (from.IsConnected)
            {
                //获取所有数据，设置推送
                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID,
                    FLYAD_OBJ_INTERFACE.GET_PARAMS);
                UInt32 sense_mask;
                sense_mask = Misc.MyBase.BIT(FLYAD_OBJ_INTERFACE.PUSH_PARAMS);


                CurrObjSys.SenseConfigEx(
                    mConn, mServerID, ID,
                    sense_mask,
                    SENSE_CONFIG.ADD);
            }
        }
        public override void PushGetValue(IFConn from, uint srcid, ushort memid, byte[] infodata)
        {
            switch (memid)
            {
                case FLYAD_OBJ_INTERFACE.GET_PARAMS:
                    {
                        FLYAD_OBJ_INTERFACE.Pack_Params p = new FLYAD_OBJ_INTERFACE.Pack_Params();

                        if (!p.TryParse(infodata))
                            return;
                        EP = p.ep;
                        
                        PosOffset = p.posoffset;
                        JogVelocity = p.jogvelocity;
                        PosLen = p.poslen;
                        PosOfGrid = p.posofgrid;
                        MotorType = p.motortype;
                        Ratio01 = p.ratio01;
                        Ratio02 = p.ratio02;
                        HasCRC = p.hasCRC;
                        GridSmooth = p.gridsmooth;
                    } break;
            }
        }
        public override void PushInfo(IFConn from, uint srcid, ushort infoid, byte[] infodata)
        {

                    PushGetValue(from, srcid, infoid, infodata);

            
        }
        public override void PushCallFunction(IFConn from, uint srcid, uint magic, ushort funcid, byte[] retdata, object AsyncDelegate, object AsyncState)
        {
            switch (funcid)
            {
                case FLYAD_OBJ_INTERFACE.CALL_GETACCESSINFO:
                    {
                        AccessInfo a = new AccessInfo();
                        if (!a.TryParse(retdata))
                            return;
                        ((AsyncCBHandler)AsyncDelegate)(AsyncState, a);
                    } break;
                case FLYAD_OBJ_INTERFACE.CALL_SETACCESS:
                    {
                        AccessInfo a = new AccessInfo();
                        if (!a.TryParse(retdata))
                            return;
                        ((AsyncCBHandler)AsyncDelegate)(AsyncState, a);
                    } break;
                case FLYAD_OBJ_INTERFACE.CALL_GETGRID:
                    {
                        GridInfo p = new GridInfo();
                        if (!p.TryParse(retdata))
                            return;
                        ((AsyncCBHandler)AsyncDelegate)(AsyncState, p);
                    }break;
            }
        }
        
        #region INotifyPropertyChanged 成员

        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(string propertyname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyname));
            }
        }
        #endregion
    }
}