using AutoMapper;
using FLY.Thick.Base.Common;
using FLY.Thick.Base.IService;
using FLY.Thick.Base.OBJ_INTERFACE;
using FObjBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FLY.Thick.Base.Client
{
    /// <summary>
    /// 
    /// </summary>
    public class FilmPositionDetectServiceClient : FObjServiceClient, IFilmPositionDetectService
    {

        static Mapper Mapper { get; } = new AutoMapper.Mapper(new MapperConfiguration(c =>
        {
            c.CreateMap<FilmPositionDetectServiceClient, FILMPOS_OBJ_INTERFACE.Pack_Params>();
        }));

        /// <summary>
        /// AD 曲线服务 客户端代理
        /// </summary>
        /// <param name="id"></param>
        public FilmPositionDetectServiceClient(UInt32 id) : base(id) { }

        /// <summary>
        /// AD 曲线服务 客户端代理
        /// </summary>
        /// <param name="serviceId">服务id</param>
        /// <param name="connName">连接器</param>
        public FilmPositionDetectServiceClient(UInt32 serviceId, string connName) : base(serviceId, connName) { }



        #region 状态
        /// <summary>
        /// 线速度 m/min
        /// </summary>
        public double FilmVelocity { get; protected set; }
        /// <summary>
        /// 膜位置， m
        /// </summary>
        public double FilmPosition { get; protected set; }

        /// <summary>
        /// 工作中
        /// </summary>
        public bool IsRunning { get; protected set; }

        /// <summary>
        /// 当前正在使用的 与机头测厚仪偏移，单位m
        /// </summary>
        public double VDistanceWithHeaderInUsed { get; protected set; }

        /// <summary>
        /// 当前正在使用的 激光探头与 X光的偏移，单位m
        /// </summary>
        public double VSensorOffsetInUsed { get; protected set; }

        /// <summary>
        /// 已经重新开始测量
        /// </summary>
        public bool HasReset { get; protected set; }
        #endregion

        #region 参数
        /// <summary>
        /// 线速度阀值，低于阀值，速度直接变为0
        /// </summary>
        public double FilmVThreshold { get; set; }

        /// <summary>
        /// 线速度来源
        /// </summary>
        public FilmVSRC FilmVSrc { get; set; }

        /// <summary>
        /// 线速度:编码器2 mm/pulse
        /// </summary>
        public double Encoder2_mmpp { get; set; }

        /// <summary>
        /// 线速度:1圈多少mm
        /// </summary>
        public double MmOfR { get; set; }

        /// <summary>
        /// 本测厚仪探头与机头测厚仪探头距离单位m
        /// </summary>
        public double VDistanceWithHeader { get; set; }

        /// <summary>
        /// 纵向光纤传感器与本测厚仪探头距离 单位m;
        /// 修改此值，会改变纵向偏移
        /// </summary>
        public double VSensorOffset { get; set; }

        #endregion

        /// <summary>
        /// 主轴激光传感器检测到 1->0 变化 事件
        /// </summary>
        public event FilmPosAt01EventHandler FilmPosAt01Event;

        /// <summary>
        /// 设置膜位置为某值
        /// </summary>
        /// <param name="filmPos">极片位置m</param>
        public void Reset(double filmPos) 
        {
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(filmPos);
            CurrObjSys.CallFunctionEx(
                mConn, mServerID, ID,
                FILMPOS_OBJ_INTERFACE.CALL_RESET, Misc.Converter.StringToBytes(json));
        }

        /// <summary>
        /// 把膜位置设置为 -VDistanceWithHeader
        /// </summary>
        public void Reset()
        {
            CurrObjSys.CallFunctionEx(
                mConn, mServerID, ID,
                FILMPOS_OBJ_INTERFACE.CALL_RESET_2, null);
        }

        /// <summary>
        /// 清除 hasReset标志位
        /// </summary>
        public void ClearResetState()
        {
            CurrObjSys.CallFunctionEx(
                mConn, mServerID, ID,
                FILMPOS_OBJ_INTERFACE.CALL_CLEAR_RESET, null);
        }


        /// <summary>
        /// 服务器 从 机头得到的 0->1 事件，给机尾
        /// </summary>
        /// <param name="filmPos">极片位置m</param>
        public void SetFilmPosAt01(double filmPos)
        {
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(filmPos);
            CurrObjSys.CallFunctionEx(
                mConn, mServerID, ID,
                FILMPOS_OBJ_INTERFACE.CALL_SET_FILMPOS_AT01, Misc.Converter.StringToBytes(json));
        }

        /// <summary>
        /// 停止测量
        /// </summary>
        public void Stop() 
        {
            CurrObjSys.CallFunctionEx(
                mConn, mServerID, ID,
                FILMPOS_OBJ_INTERFACE.CALL_STOP, null);
        }

        /// <summary>
        /// 启动测量
        /// </summary>
        public void Start() 
        {
            CurrObjSys.CallFunctionEx(
            mConn, mServerID, ID,
            FILMPOS_OBJ_INTERFACE.CALL_START, null);
        }

        public void Apply()
        {
            var p = Mapper.Map<FILMPOS_OBJ_INTERFACE.Pack_Params>(this);
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(p);
            CurrObjSys.SetValueEx(
                mConn, mServerID, ID,
                FILMPOS_OBJ_INTERFACE.SET_PARAMS, Misc.Converter.StringToBytes(json));

        }

        public override void ConnectNotify(IFConn from)
        {
            base.ConnectNotify(from);
            if (from.IsConnected)
            {
                //获取所有数据，设置推送
                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID,
                    FILMPOS_OBJ_INTERFACE.GET_PARAMS);

                CurrObjSys.GetValueEx(
                    mConn, mServerID, ID,
                    FILMPOS_OBJ_INTERFACE.GET_STATE);

                CurrObjSys.SenseConfigEx(
                    mConn, mServerID, ID, 0xffffffff,
                    SENSE_CONFIG.ADD);
            }
        }
        public override void PushGetValue(IFConn from, uint srcid, ushort memid, byte[] infodata)
        {
            switch (memid)
            {
                case FILMPOS_OBJ_INTERFACE.GET_PARAMS:
                    {
                        string json = Misc.Converter.BytesToString(infodata);
                        Newtonsoft.Json.JsonConvert.PopulateObject(json, this);
                    }
                    break;
                case FILMPOS_OBJ_INTERFACE.GET_STATE:
                    {
                        string json = Misc.Converter.BytesToString(infodata);
                        Newtonsoft.Json.JsonConvert.PopulateObject(json, this);
                    }
                    break;
            }
        }
        public override void PushInfo(IFConn from, uint srcid, ushort infoid, byte[] infodata)
        {
            switch (infoid) 
            {
                case FILMPOS_OBJ_INTERFACE.PUSH_FilmPosAt01Event:
                    {
                        string json = Misc.Converter.BytesToString(infodata);
                        var p = Newtonsoft.Json.JsonConvert.DeserializeObject<FilmPosAt01EventArgs>(json);
                        FilmPosAt01Event?.Invoke(this, p);
                    }
                    break;
                default:
                    PushGetValue(from, srcid, infoid, infodata);
                    break;
            }
            
        }
    }
}
