using Misc;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace FlyADBase
{
    /// <summary>
    /// 客户端AD盒
    /// </summary>
    public interface IFlyADClient : IFlyAD 
    {
        /// <summary>
        /// 连接成功
        /// </summary>
        bool IsConnected { get; }

        /// <summary>
        /// 重连次数
        /// </summary>
        int ConnectCnt { get; }

        /// <summary>
        /// CRC 校正
        /// </summary>
        bool HasCRC { get; set; }

        /// <summary>
        /// 连接
        /// </summary>
        void Connect();

        /// <summary>
        /// 连接 ep
        /// </summary>
        /// <param name="ep"></param>
        void Connect(IPEndPoint ep);

        /// <summary>
        /// 重连
        /// </summary>
        void ReConnect();


        /// <summary>
        /// 用于同步, 最后一次 纵向信号 0->1 时,主轴脉冲
        /// </summary>
        int LastPos2At01 { get; }

        /// <summary>
        /// 当前在同步状态
        /// </summary>
        bool IsSync { get; }

        /// <summary>
        /// 同步列表,完成后,会删除
        /// </summary>
        ObservableCollection<SyncOrder> SyncOrders { get; }
    }

    /// <summary>
    /// 客户端AD盒附加的功能
    /// </summary>
    public interface IFlyADClientAdv : IFlyADClient
    {
        /// <summary>
        /// 通过脉冲计算速度,不使用AD盒的输出
        /// </summary>
        bool IsCalSpeed { get; set; }
        /// <summary>
        /// 机架修正
        /// </summary>
        CorrectADsHandler CorrectADs { get; set; }

        /// <summary>
        /// grid 滤波
        /// </summary>
        int GridSmooth { get; set; }

        /// <summary>
        /// 脉冲比例 Ratio02(编码器脉冲) / Ratio01(电机脉冲)
        /// </summary>
        double Speed1Scale { get; }

        /// <summary>
        /// 机架总长
        /// </summary>
        int PosLen { get; set; }

        /// <summary>
        /// Runto(0), 不同于 Backward
        /// </summary>
        void RuntoMin();
        /// <summary>
        /// Runto(PosLen), 不同于 Forward
        /// </summary>
        void RuntoMax();



        /// <summary>
        /// 设置输出
        /// </summary>
        /// <param name="index"></param>
        /// <param name="is1"></param>
        void SetOutputBit(int index, bool is1);

        /// <summary>
        /// 从正反缓存区, 获取grid数据
        /// </summary>
        /// <param name="direction">方向, 只有 正,反</param>
        /// <param name="grid_start">grid 开始位置</param>
        /// <param name="grid_len">grid 长度</param>
        /// <param name="dat">grid 数据</param>
        void GetGrid(DIRECTION direction, int grid_start, int grid_len, out int[] dat);

        /// <summary>
        /// 从正反缓存区, 获取全部grid数据
        /// </summary>
        /// <param name="direction">方向, 只有 正,反</param>
        /// <param name="dat">grid 数据</param>
        void GetGrid(DIRECTION direction, out int[] dat);


        /// <summary>
        /// 转为 grid 数据
        /// </summary>
        /// <param name="gridAdvUnits"></param>
        /// <param name="dat"></param>
        /// <param name="adLag">测试功能 ad值滞后</param>
        void ToGrid(IEnumerable<GridAdvUnit> gridAdvUnits, out int[] dat,int adLag);

        /// <summary>
        /// 动作完成
        /// </summary>
        bool IsFinish { get; }

        #region 滞后处理
        /// <summary>
        /// ad滞后修正  单位ms
        /// </summary>
        int ADLag { get; set; }
        /// <summary>
        /// 以timegrid 为单位,推送数据
        /// </summary>
        event TimeGridAdvEventHandler TimeGridAdvEvent;
        #endregion

        #region runto 推送 istatus 变化
        /// <summary>
        /// 添加 GridIStatusEvent 事件;
        /// 获取一整幅 grid 对应的 输入口状态 数据
        /// </summary>
        /// <param name="istatus_no"></param>
        /// <param name="func"></param>
        void GridIStatusEventAdd(int istatus_no, GridIStatusEventHander func);
        /// <summary>
        /// 删除 GridIStatusEvent 事件
        /// </summary>
        /// <param name="istatus_no"></param>
        /// <param name="func"></param>
        void GridIStatusEventDel(int istatus_no, GridIStatusEventHander func);
        #endregion

    }

    /// <summary>
    /// 机架修正
    /// </summary>
    /// <param name="direction"></param>
    /// <param name="start_grid"></param>
    /// <param name="dat"></param>
    public delegate void CorrectADsHandler(Misc.DIRECTION direction, int start_grid, int[] dat);
}