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 : FObjServiceClient, IFlyADService
    {

        public FlyADServiceClient(UInt32 serviceId) : base(serviceId) { }
        public FlyADServiceClient(UInt32 serviceId, string connName) : base(serviceId, connName) { }
        #region IFlyAD接口


        public IPEndPoint EP { get; set; } = new IPEndPoint(IPAddress.Parse("192.168.251.10"), 20006);

        public bool HasCRC { get; set; }


        private int gridsmooth = 0;
        /// <summary>
        /// grid数据平滑
        /// </summary>
        public int GridSmooth
        {
            get { return gridsmooth; }
            set
            {
                if (value < 0)
                    value = 0;
                if (gridsmooth != value)
                {
                    gridsmooth = value;
                }
            }
        }
        /// <summary>
        /// 通过脉冲计算速度，不使用AD盒的输出
        /// </summary>
        public bool IsCalSpeed { get; set; }

        public int PosLen { get; set; }

        public MOTORTYPE MotorType { get; set; }

        /// <summary>
        /// // 单位 pulse/grid
        /// </summary>
        public int PosOfGrid { get; set; }

        public UInt16 Ratio01 { get; set; }
 

        public UInt16 Ratio02 { get; set; }


        public Int16 PosOffset { get; set; }


        /// <summary>
        /// 脉冲平移
        /// </summary>
        public UInt32 JogVelocity { get; set; }

        /// <summary>
        /// 参数应用
        /// </summary>
        public void Apply() 
        {
            FLYAD_OBJ_INTERFACE.Pack_Params p = new FLYAD_OBJ_INTERFACE.Pack_Params()
            {
                ep = EP.ToString(),
                posofgrid = (UInt16)PosOfGrid,
                motortype = MotorType,
                poslen = PosLen,
                ratio01 = Ratio01,
                ratio02 = Ratio02,
                posoffset = PosOffset,
                jogvelocity = JogVelocity,
                hasCRC = HasCRC,
                gridsmooth = GridSmooth,
                IsCalSpeed = IsCalSpeed
            };
            
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(p);

            CurrObjSys.SetValueEx(mConn, mServerID, ID,
                FLYAD_OBJ_INTERFACE.SET_PARAMS,
                Misc.Converter.StringToBytes(json));
        }
        /// <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)
        {
            var p = new FLYAD_OBJ_INTERFACE.Pack_SetAccessRequest() { data = access };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(p);


            CurrObjSys.CallFunctionEx(mConn, mServerID, ID,
                FLYAD_OBJ_INTERFACE.CALL_SETACCESS,
                Misc.Converter.StringToBytes(json),
                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) 
        {
            var p = new FLYAD_OBJ_INTERFACE.Pack_GetGridRequest() { direction = direction };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(p);

            CurrObjSys.CallFunctionEx(mConn, mServerID, ID,
                FLYAD_OBJ_INTERFACE.CALL_GETGRID,
                Misc.Converter.StringToBytes(json),
                AsyncDelegate, AsyncState);
        }


        /// <summary>
        /// 向AD盒获取数据
        /// </summary>
        public void UpdateParam()
        {
            CurrObjSys.CallFunctionEx(mConn, mServerID, ID,
                FLYAD_OBJ_INTERFACE.CALL_UPDATEPARAM,null);
        }
        #endregion



        public override void ConnectNotify(IFConn from)
        {
            base.ConnectNotify(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:
                    {
                        string json = Misc.Converter.BytesToString(infodata);
                        var p = Newtonsoft.Json.JsonConvert.DeserializeObject<FLYAD_OBJ_INTERFACE.Pack_Params>(json);

                        EP = Misc.StringConverter.ToIPEndPoint(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;
                        IsCalSpeed = p.IsCalSpeed;
                    } 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:
                    {
                        string json = Misc.Converter.BytesToString(retdata);
                        AccessInfo a = Newtonsoft.Json.JsonConvert.DeserializeObject<AccessInfo>(json);
                        
                        ((AsyncCBHandler)AsyncDelegate)(AsyncState, a);
                    } break;
                case FLYAD_OBJ_INTERFACE.CALL_SETACCESS:
                    {
                        string json = Misc.Converter.BytesToString(retdata);
                        AccessInfo a = Newtonsoft.Json.JsonConvert.DeserializeObject<AccessInfo>(json);

                        ((AsyncCBHandler)AsyncDelegate)(AsyncState, a);
                    } break;
                case FLYAD_OBJ_INTERFACE.CALL_GETGRID:
                    {
                        string json = Misc.Converter.BytesToString(retdata);
                        GridInfo p = Newtonsoft.Json.JsonConvert.DeserializeObject<GridInfo>(json);

                        ((AsyncCBHandler)AsyncDelegate)(AsyncState, p);
                    }break;
            }
        }

    }
}