using FlyADBase;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FlyAd2021.Inc
{
    /// <summary>
    /// AD盒2021版 , 核心模块 
    /// 实现AD盒2021版 基本接口  
    /// </summary>
    public interface IFlyAd2021Core : INotifyPropertyChanged
    {
        #region 测量速度
        bool IsMeasuring { get; }

        /// <summary>
        ///  通讯速度 byte/s
        /// </summary>
        double CommSpeed { get; }

        /// <summary>
        /// 传输速度 单位 pack/s
        /// </summary>
        double PackSpeed { get; }

        /// <summary>
        /// 开始测量速度
        /// </summary>
        void StartMeasure();

        /// <summary>
        ///结束测量速度
        /// </summary>
        void StopMeasure();
        #endregion

        /// <summary>
        /// 包出错次数
        /// </summary>
        int ErrCnt { get; }

        /// <summary>
        /// 连接成功；
        /// 当命令多次发送失败，IsConnected = false
        /// </summary>
        bool IsConnected { get; }

        

        #region 模块运行接口
        /// <summary>
        /// 超时判断，长时间收不到数据，会触发，0.5s调用一次
        /// </summary>
        void OnPoll_TimeOut();

        /// <summary>
        /// 在接收事件中调用；
        /// 全部接收事件 及 超时事件也是在这里触发
        /// </summary>
        /// <param name="recBuf"></param>
        void RecMsg(byte[] recBuf);
        /// <summary>
        /// 获取 发送队列 第1条msg
        /// </summary>
        /// <returns></returns>
        byte[] GetSendMsg();
        /// <summary>
        /// 有数据需要发送
        /// </summary>
        /// <param name="sender"></param>
        event SendMsgEventHander SendMsgEvent;

        /// <summary>
        /// 复位全部状态，通常由于通讯模块检测到连接断开导致的
        /// </summary>
        void ResetMsg();
        #endregion

        #region AD盒 功能
        /// <summary>
        /// 数据推送事件
        /// </summary>
        event PushDataEventHandler PushDataEvent;
        /// <summary>
        /// 运行状态推送事件
        /// </summary>
        event PushRunResultEventHandler PushRunResultEvent;
        #region IOComm IO指令

        [CallBack(typeof(UInt16))]
        void GetIn(CallBackHandler asyncDelegate, object asyncContext);


        [CallBack(typeof(UInt16))]
        void GetOut(CallBackHandler asyncDelegate, object asyncContext);

        [CallBack(typeof(Int32))]
        void GetEnc1(CallBackHandler asyncDelegate, object asyncContext);

        [CallBack(typeof(Int32))]
        void GetEnc2(CallBackHandler asyncDelegate, object asyncContext);

        [CallBack(typeof(GetEncAll_Reponse))]
        void GetEncAll(CallBackHandler asyncDelegate, object asyncContext);

        void SetOutPorts(UInt16 mask, UInt16 value, CallBackHandler asyncDelegate, object asyncContext);
        #endregion

        #region RunComm 运行指令 SetRunParam

        void SetRunParam_V(UInt32 velocity, CallBackHandler asyncDelegate, object asyncContext);

        void SetRunParam_SV(UInt32 sv, CallBackHandler asyncDelegate, object asyncContext);

        void SetRunParam_AccTime(UInt32 accTime, CallBackHandler asyncDelegate, object asyncContext);

        void SetRunParam_DecTime(UInt32 decTime, CallBackHandler asyncDelegate, object asyncContext);

        void SetRunParam_HSpd1(UInt32 homespd1, CallBackHandler asyncDelegate, object asyncContext);

        void SetRunParam_HSpd2(UInt32 homespd2, CallBackHandler asyncDelegate, object asyncContext);
        #endregion

        #region RunComm 运行指令 GetRunParam
        void GetRunParam_V(CallBackHandler asyncDelegate, object asyncContext);

        void GetRunParam_SV(CallBackHandler asyncDelegate, object asyncContext);

        void GetRunParam_AccTime(CallBackHandler asyncDelegate, object asyncContext);

        void GetRunParam_DecTime(CallBackHandler asyncDelegate, object asyncContext);

        void GetRunParam_HSpd1(CallBackHandler asyncDelegate, object asyncContext);

        void GetRunParam_HSpd2(CallBackHandler asyncDelegate, object asyncContext);

        #endregion

        #region RunComm 运行指令

        [CallBack(typeof(GetRunResult_Reponse))]
        void GetRunResult(CallBackHandler asyncDelegate, object asyncContext);

        void Forw(Int32 serial, CallBackHandler asyncDelegate, object asyncContext);

        void Backw(Int32 serial, CallBackHandler asyncDelegate, object asyncContext);
        void Org(Int32 serial, CallBackHandler asyncDelegate, object asyncContext);

        void RunTo(Int32 serial, int targetPos, CallBackHandler asyncDelegate, object asyncContext);
        
        void Stop(CallBackHandler asyncDelegate, object asyncContext);

        void EStop(CallBackHandler asyncDelegate, object asyncContext);
        #endregion

        #region 同步运行指令
        void SyncRun_SetHShift(int hShift, CallBackHandler asyncDelegate, object asyncContext);
        void SyncRun_SetVShift(int vOShift, CallBackHandler asyncDelegate, object asyncContext);

        void SyncRun_Start(CallBackHandler asyncDelegate, object asyncContext);
        void SyncRun_Stop(CallBackHandler asyncDelegate, object asyncContext);
        void SyncRun_Clear(CallBackHandler asyncDelegate, object asyncContext);

        /// <summary>
        /// 同步扫描至;
        /// D+0xE0+开始主轴位置+结束主轴位置+结束横向脉冲位置（逻辑位置）+脉冲开关（1B）+命令识标号（4B）
        /// </summary>
        /// <param name="pos2_begin"></param>
        /// <param name="pos2_end"></param>
        /// <param name="pos1lc"></param>
        /// <param name="hasDataGrid"></param>
        /// <param name="marker"></param>
        void SyncRun_RunAtLC(int pos2_begin, int pos2_end, int pos1lc, UInt32 serial, CallBackHandler asyncDelegate, object asyncContext);


        /// <summary>
        /// 位于队列头时运行，归零；
        /// D+0xE1+命令识标号（4B）
        /// </summary>
        /// <param name="marker"></param>
        void SyncRun_Origin(UInt32 serial, CallBackHandler asyncDelegate, object asyncContext);


        /// <summary>
        /// 位于队列头时运行，以速度运行至物理位置；
        /// D+0xE2+横向脉冲位置（4B：int32，物理位置）+速度（4B：int32）+脉冲开关（1B）+命令识标号（4B）
        /// </summary>
        /// <param name="pos1"></param>
        /// <param name="velocity"></param>
        /// <param name="hasDataGrid"></param>
        /// <param name="marker"></param>
        void SyncRun_RunTo(int pos1, UInt32 velocity, UInt32 serial, CallBackHandler asyncDelegate, object asyncContext);


        /// <summary>
        /// 位于队列头时运行，以速度运行至逻辑位置；
        /// D+0xE3+横向脉冲位置（4B：int32，逻辑位置）+速度（4B：int32）+脉冲开关（1B）+命令识标号（4B）
        /// </summary>
        /// <param name="pos1lc"></param>
        /// <param name="velocity"></param>
        /// <param name="hasDataGrid"></param>
        /// <param name="marker"></param>
        void SyncRun_RunToLC(int pos1lc, UInt32 velocity, UInt32 serial, CallBackHandler asyncDelegate, object asyncContext);


        /// <summary>
        /// 获取队列长度
        /// </summary>
        /// <param name="asyncDelegate"></param>
        /// <param name="asyncContext"></param>
        void SyncRun_GetListCount(CallBackHandler asyncDelegate, object asyncContext);
        #endregion

        #region SysParamComm 系统参数指令

        /// <summary>
        /// 获取系统当前Tick
        /// </summary>
        [CallBack(typeof(UInt32))]
        void GetSysTick(CallBackHandler asyncDelegate, object asyncContext);

        /// <summary>
        /// 初始化系统信息区
        /// </summary>
        /// <param name="asyncDelegate"></param>
        /// <param name="asyncContext"></param>
        [CallBack(typeof(bool))]
        void InitArea(CallBackHandler asyncDelegate, object asyncContext);

        /// <summary>
        /// 输入系统授权码
        /// </summary>
        /// <param name="access"></param>
        /// <param name="asyncDelegate"></param>
        /// <param name="asyncContext"></param>
        [CallBack(typeof(AREA_ERR))]
        void CheckAccessCode(byte[] access, CallBackHandler asyncDelegate, object asyncContext);

        /// <summary>
        /// 获取系统授权信息
        /// </summary>
        /// <param name="asyncDelegate"></param>
        /// <param name="asyncContext"></param>
        [CallBack(typeof(GetAccess_Reponse))]
        void GetAccess(CallBackHandler asyncDelegate, object asyncContext);

        /// <summary>
        /// 系统运行时间+1
        /// </summary>
        /// <param name="asyncDelegate"></param>
        /// <param name="asyncContext"></param>
        void AddAccess(CallBackHandler asyncDelegate, object asyncContext);
        #endregion
        #region GetSysParam 读运行参数
        [CallBack(typeof(MOTORTYPE))]
        void GetSysParam_MotorType(CallBackHandler asyncDelegate, object asyncContext);

        [CallBack(typeof(UInt16))]
        void GetSysParam_Ratio01(CallBackHandler asyncDelegate, object asyncContext);

        [CallBack(typeof(UInt16))]
        void GetSysParam_Ratio02(CallBackHandler asyncDelegate, object asyncContext);

        [CallBack(typeof(Int16))]
        void GetSysParam_Zero(CallBackHandler asyncDelegate, object asyncContext);

        [CallBack(typeof(UInt32))]
        void GetSysParam_Jog(CallBackHandler asyncDelegate, object asyncContext);
        #endregion

        #region SetSysParam 设置运行参数
        void SetSysParam_MotorType(MOTORTYPE motorType, CallBackHandler asyncDelegate, object asyncContext);


        void SetSysParam_Ratio01(UInt16 ratio01, CallBackHandler asyncDelegate, object asyncContext);

        void SetSysParam_Ratio02(UInt16 ratio02, CallBackHandler asyncDelegate, object asyncContext);

        void SetSysParam_Zero(Int16 zero, CallBackHandler asyncDelegate, object asyncContext);

        void SetSysParam_Jog(UInt32 jog, CallBackHandler asyncDelegate, object asyncContext);
        #endregion
        #endregion
    }


    public class PushDataEventArgs : EventArgs
    {
        public byte SysTick { get; set; }
        public UInt16 AD { get; set; }
        public UInt16? ENC1 { get; set; }
        public UInt16? ENC2 { get; set; }
        public UInt16? In { get; set; }
        public UInt16? InChange { get; set; }
        public UInt16? Out { get; set; }

        public PushDataEventArgs()
        {

        }
    }
    public delegate void PushDataEventHandler(object sender, PushDataEventArgs e);

    public class PushRunResultEventArgs : EventArgs
    {
        public byte SysTick { get; set; }
        /// <summary>
        /// 运行序号
        /// </summary>
        public UInt32 Serial { get; set; }

        /// <summary>
        /// 运行状态
        /// </summary>
        public DRIVE_MAN_STATUS Status { get; set; }
    }
    public delegate void PushRunResultEventHandler(object sender, PushRunResultEventArgs e);
    /// <summary>
    /// 异常不回复
    /// </summary>
    /// <param name="asyncContext"></param>
    /// <param name="retData"></param>
    public delegate void CallBackHandler(object asyncContext, object retData);


    public class CallBackAttribute : Attribute
    {
        public Type RetType;
        public CallBackAttribute(Type type) 
        {
            RetType = type;
        }
    }

    /// <summary>
    /// 有数据需要发送
    /// </summary>
    /// <param name="sender"></param>
    public delegate void SendMsgEventHander(object sender);


    public class GetEncAll_Reponse
    {
        public int pos1;
        public int pos2;
    }
    
    public class GetRunResult_Reponse
    {
        public DRIVE_MAN_STATUS result;
        public UInt32 serial;
    }

    public class GetAccess_Reponse
    {
        public AREA_STATUS status;
        public AREA_ERR ret;
        public byte[] code = new byte[6];
        public UInt16 surplus;
        public byte[] access = new byte[8];
    }
}
