using FLY.Thick.Base.Common;
using FLY.Thick.Base.IService;
using FlyADBase;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;

namespace FLY.Thick.Base.Server
{
    /// <summary>
    /// 膜位置检测
    /// 通过辊接近开关，或者编码器2
    /// </summary>
    public class FilmPositionDetect : IFilmPositionDetect
    {
        /// <summary>
        /// 线速度 m/min
        /// </summary>
        public double FilmVelocity { get; private set; }

        /// <summary>
        /// 膜位置， m
        /// </summary>
        public double FilmPosition { get; private set; }

        /// <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>
        /// 编码器2 放大
        /// </summary>
        public float Encoder2_comp { get; set; }

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

        public event PropertyChangedEventHandler PropertyChanged;

        private FlyAD7 mFlyAD;

        public void Init(FlyAD7 flyAD)
        {
            mFlyAD = flyAD;


            //------------------------------------------------------------------------------------------------------------------------------------
            //线速度------------------------------------------------------------------------------------------------------------------------------
            mFlyAD.PropertyChanged += (s, e) =>
            {
                if (FilmVSrc != FilmVSRC.EN2)
                    return;

                if (e.PropertyName == "Speed2")
                {
                    double speed = mFlyAD.Speed2 * Encoder2_mmpp;//mm/s
                    speed = speed * 60 / 1000;//m/min
                    FilmVelocity = speed;
                }
                else if (e.PropertyName == "Position2")
                {
                    if (FilmVSrc != FilmVSRC.EN2)
                        return;

                    double position2 = mFlyAD.Position2* Encoder2_mmpp;//mm
                    position2 /= 1000.0;
                    FilmPosition = position2 + BaseFilmPosition;
                }
            };

            //------------------------------------------------------------------------------------------------------------------------------------
            //辊信号生成线速度-----------------------------------------------------------------------------------------------------------------------------
            InitRoundFilmVelocity();
        }

        #region 辊信号生成 线速度
        DispatcherTimer round_t;
        DateTime dtRound;

        int RCnt = 0;
        double BaseFilmPosition = 0;
        void InitRoundFilmVelocity()
        {
            round_t = new DispatcherTimer();
            round_t.Interval = TimeSpan.FromSeconds(1);
            round_t.Tick += new EventHandler(round_t_Tick);
            mFlyAD.IStatusChangedEvent += new IStatusChangedEventHandler(mFlyAD_IStatusChangedEvent_round);
        }


        void mFlyAD_IStatusChangedEvent_round(object sender, IStatusChangedEventArgs e)
        {
            if (FilmVSrc != FilmVSRC.ROUND)
                return;

            if (!Misc.MyBase.CHECKBIT(e.IChanged, 11 - 1))
                return;
            
            if (Misc.MyBase.CHECKBIT(e.IStatus, 11 - 1))
                return;
            
            //1->0
            DateTime dt = e.Time;
            if (dt <= dtRound)
                return;
            if (dtRound != DateTime.MinValue)
            {
                double v = MmOfR / 1000.0 / (dt - dtRound).TotalMinutes;
                if (v < 2)//太慢了
                {
                    dt = DateTime.MinValue;
                    v = 0;
                }
                FilmVelocity = v;
                if (v > 0)
                {
                    RCnt++;
                    FilmPosition = RCnt * MmOfR / 1000.0 + BaseFilmPosition;
                }
            }

            dtRound = dt;

            if (dtRound != DateTime.MinValue)
            {
                if (!round_t.IsEnabled)
                    round_t.Start();
            }
        }

        void round_t_Tick(object sender, EventArgs e)
        {
            if (FilmVSrc != FilmVSRC.ROUND)
            {
                round_t.Stop();
                return;
            }

            if (dtRound == DateTime.MinValue)
            {
                round_t.Stop();
                return;
            }

            //1->0
            DateTime dt = DateTime.Now;
            if (dt <= dtRound)
                return;

            double v = MmOfR / 1000.0 / (dt - dtRound).TotalMinutes;

            if (v < (FilmVelocity - 1))
            {
                if (v < 2)
                {
                    dtRound = DateTime.MinValue;
                    v = 0;
                }
                FilmVelocity = v;
            }
            
            double p1 = RCnt * MmOfR / 1000.0;
            double p2 = (dt - dtRound).TotalMinutes * FilmVelocity;
            if (p2 > MmOfR / 1000.0)
                p2 = MmOfR / 1000.0;
            p1 += p2;
            if (FilmPosition < p1)
                FilmPosition = p1;
            
            if (dtRound == DateTime.MinValue)
            {
                round_t.Stop();
                return;
            }
        }
         
        #endregion


        /// <summary>
        /// 设置膜位置为某值
        /// </summary>
        /// <param name="filmPosition"></param>
        public void Reset(double filmPosition)
        {
            if (FilmVSrc == FilmVSRC.EN2)
            {
                mFlyAD.Position2 = 0;
            }
            else
            {
                RCnt = 0;
            }
            BaseFilmPosition = filmPosition;
            FilmPosition = BaseFilmPosition;
        }
        
        
    }

}
