using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
using System.Net;
using System.Diagnostics;
using System.ComponentModel;
using Misc;
using FObjBase;
using FlyADBase;
using FLY.Thick.BulkDataModule;
using FLY.Thick.RemoteHistory;
using FLY.Thick.Base.Common;
using FLY.Thick.Base.Server;
using FLY.Thick.Base.IService;
using FLY.Thick.BlowingScan.IService;
using System.Windows.Threading;
using FLY.Thick.BlowingScan.Server.Model;
using FLY.Thick.Blowing.Server.Model;



using OrgDbModel = FLY.Thick.BlowingScan.Server.Model.OrgDbModel;
using HistoryDb = FLY.Thick.BlowingScan.Server.Model.HistoryDb;
using ScanWarning = FLY.Thick.Blowing.Server.ScanWarning;

namespace FLY.Thick.BlowingScan.Server
{

    public class TDGage : ITDGageService
    {
        #region 延时推送 MARKNO
        const int MARKNO_UPDATEV = 1;
        const int MARKNO_INITHISTORY = 2;
        const int MARKNO_PUSH_ACCESS = 3;
        #endregion
        #region 参数--------------------------------------------------------------------
        #region 初始化------------------------------------------------------------------
        /// <summary>
        /// 参数目录 m_path;数据文件的 根目录默认是 "Gage1", 不能有 @"\"
        /// 目前也是对外的服务器目录
        /// </summary>
        public string mParamDirectory;
        /// <summary>
        /// 名字 如:gage0
        /// </summary>
        public string mName;
        #endregion

        #region 数据--------------------------------------------------------------------

        /// <summary>
        /// 当前基本简单参数
        /// </summary>
        public DynArea mDynArea;

        /// <summary>
        /// 设备参数
        /// </summary>
        public InitParam mInitParam;

        /// <summary>
        /// 运行参数
        /// </summary>
        public BlowingProfile mProfile;

        /// <summary>
        /// 边界查找,由 boltmap 独立出来的功能
        /// </summary>
        public BorderSearch mBorderSearch;

        /// <summary>
        /// AD曲线
        /// </summary>
        public CurveCollection mCurve;

        /// <summary>
        /// 报警系统
        /// </summary>
        public FLY.OBJComponents.Server.WarningSystem mWarning;

        /// <summary>
        /// 密码系统,只提供给客户端,在服务器没用。。。
        /// </summary>
        public Password mPassword;

        #region 运行模式

        /// <summary>
        /// AD卡
        /// </summary>
        public FlyADBase.FlyAD7 mFlyAD;
        /// <summary>
        /// 样品修正
        /// </summary>
        public GSample mGetSample;
        /// <summary>
        /// GM管理器
        /// </summary>
        GageModeManager mGMManager;
        /// <summary>
        /// 断开连接
        /// </summary>
        GM_Disconnected mGMDisconnected;

        /// <summary>
        /// 暂停扫描
        /// </summary>
        GM_Pause mGMPause;
        /// <summary>
        /// 自动启动扫描
        /// </summary>
        GM_AutoScan mGMAutoScan;

        /// <summary>
        /// 前进
        /// </summary>
        GM_Forward mGMForw;
        /// <summary>
        /// 后退
        /// </summary>
        GM_Backward mGMBackw;
        /// <summary>
        /// 归零
        /// </summary>
        GM_Origin mGMOrg;
        /// <summary>
        /// 停止
        /// </summary>
        GM_Stop mGMStop;
        /// <summary>
        /// 运行到目标位置
        /// </summary>
        GM_Goto mGMRunto;
        /// <summary>
        /// 机架校正模式,参数
        /// </summary>
        public GM_ScanCorr mGMScanCorr;
        /// <summary>
        /// 扫描模式
        /// </summary>
        public GM_Scan mGMScan;
        /// <summary>
        /// 定点模式
        /// </summary>
        public GM_Fix mGMFix;

        /// <summary>
        /// 吹膜测厚模式.扫描
        /// </summary>
        public GM_BlowingScan mGMRenZiJiaScan;

        /// <summary>
        /// 扫描报警系统
        /// </summary>
        public ScanWarning mScanWarning;

        /// <summary>
        /// 机架信息,不同于机架校正
        /// </summary>
        public GM_GageInfo mGMGageInfo;
        #endregion

        /// <summary>
        /// 系统参数
        /// </summary>
        public SysParam mSysParam;


        #region BULKDATA
        /// <summary>
        /// N幅历史数据缓存
        /// </summary>
        public BulkDataService mBulk;
        /// <summary>
        /// 
        /// </summary>
        public BulkDataServiceClientAdv mBulkClient;

        /// <summary>
        /// 数据库对象
        /// </summary>
        DbModel mDbModel;
        /// <summary>
        /// 原始数据 数据库对象
        /// </summary>
        OrgDbModel mOrgDbModel;
        /// <summary>
        /// 数据库写操作
        /// </summary>
        public HistoryDb mHistoryDb;
        /// <summary>
        /// 本地数据库
        /// </summary>
        LocalDb mLocalDb;
        /// <summary>
        /// 数据库读操作
        /// </summary>
        public BulkDb mBulkDb;

        #endregion

        #endregion

        #endregion

        public TDGage(string nam)
        {
            mName = nam;
            mParamDirectory = mName;// @"D:\" + m_name;

            if (!System.IO.Directory.Exists(mParamDirectory))
            {
                System.IO.Directory.CreateDirectory(mParamDirectory);
            }
            System.Environment.CurrentDirectory = mParamDirectory;

            #region 提取保存的数据

            mSysParam = new SysParam(null);//系统参数

            mInitParam = new InitParam(null);
            mInitParam.HasHold = false;

            mProfile = new BlowingProfile(null);//运行配置参数

            mBorderSearch = new BorderSearchPlastic(null);//边界查找

            mCurve = new CurveCollection(null);//AD转thick
            
            mPassword = new Password(null);

            mDbModel = new DbModel();
            mDbModel.Init();

            mOrgDbModel = new OrgDbModel();
            mOrgDbModel.Init();

            mLocalDb = new LocalDb();

            mHistoryDb = new HistoryDb();
            mHistoryDb.Init(mDbModel, mOrgDbModel, mLocalDb);
            mHistoryDb.KeepDBSize(mInitParam.DBKeepMonth);
            mHistoryDb.KeepOrgDbSize(3);

            PollModule.Current.Poll_Config(PollModule.POLL_CONFIG.ADD, () =>
            {
                //避免1个月都不关程序,每天检查一次
                mHistoryDb.KeepOrgDbSize(3);
            }, TimeSpan.FromDays(1));

            mBulkDb = new BulkDb();
            mBulkDb.Init(mHistoryDb, mLocalDb, mDbModel);

            #endregion
            //---------------------------------------------------------------------------------------------------------------
            //小托辊
            Misc.BindingOperations.SetBinding(mInitParam, new string[] { "HasHold", "PosLength" },
                delegate ()
                {
                    if (!mInitParam.HasHold)
                    {
                        mBorderSearch.Valid.Begin = 0;
                        mBorderSearch.Valid.End = mInitParam.PosLength - 1;
                    }
                });


            #region 动态数据

            mDynArea = new DynArea();
            mDynArea.Version = Version;
            Misc.BindingOperations.SetBinding(mProfile.Param, "PName", mDynArea, "ProductName");
            Misc.BindingOperations.SetBinding(mProfile.Param, "Target", () =>
            {
                mDynArea.Target = (int)(mProfile.Param.Target * 100);
            });
            Misc.BindingOperations.SetBinding(mProfile.Param, new string[] { "Target", "TolerancePercent" }, () =>
            {
                mDynArea.Alarm = (int)(mProfile.Param.Target * mProfile.Param.TolerancePercent * 100);
            });
            Misc.BindingOperations.SetBinding(mProfile.Param, "K", mDynArea, "Comp");



            Misc.BindingOperations.SetBinding(mBorderSearch, new string[] { "Width" },
                delegate()
                {
                    mDynArea.Width = mBorderSearch.Width * mInitParam.Encoder1_mmpp;
                });

            mInitParam.PropertyChanged += (s, e) =>
            {
                if (e.PropertyName == "Encoder1_mmpp")
                {
                    mDynArea.Width = mBorderSearch.Width * mInitParam.Encoder1_mmpp;
                }
            };
            mDynArea.PropertyChanged += new PropertyChangedEventHandler(mDynArea_PropertyChanged);


            //---------------------------------------------------------------------------------------------------------------
            //GageModeManager_Create
            mGMManager = new GageModeManager();
            Misc.BindingOperations.SetBinding(mGMManager, "State", mDynArea, "ControllerState");

            //---------------------------------------------------------------------------------------------------------------
            //FlyAD7_Create
            mFlyAD = new FlyAD7();
            //TODO
            mFlyAD.Connect(mSysParam.FLYAD7EP);
            Misc.BindingOperations.SetBinding(mFlyAD, "LocalEP", mSysParam, "FLYAD7EP");

            Misc.BindingOperations.SetBinding(mInitParam, "PosLength", mFlyAD, "PosLen");

            Misc.BindingOperations.SetBinding(mFlyAD, "IStatus", mDynArea, "IStatus");
            Misc.BindingOperations.SetBinding(mFlyAD, "OStatus", mDynArea, "OStatus");
            Misc.BindingOperations.SetBinding(mFlyAD, "Position", mDynArea, "Position");
            Misc.BindingOperations.SetBinding(mFlyAD, "Position2", mDynArea, "Position2");
            Misc.BindingOperations.SetBinding(mFlyAD, "Surplus", mDynArea, "Hrs");
            Misc.BindingOperations.SetBinding(mFlyAD, "IsConnected", mDynArea, "FLYADIsConnect");

            Misc.BindingOperations.SetBinding(mFlyAD, "PosOfGrid", mInitParam, "PosOfGrid");

            //------------------------------------------------------------------------------------------------------------------------------------
            //速度------------------------------------------------------------------------------------------------------------------------------
            mFlyAD.PropertyChanged += (s, e) =>
            {
                if (e.PropertyName == "Speed")
                {
                    double speed = mFlyAD.Speed * mInitParam.Encoder1_mmpp;//mm/s
                    speed = speed * 60 / 1000;//m/min
                    mDynArea.Velocity = speed;
                }
            };

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

                    double speed = mFlyAD.Speed2 * mInitParam.Encoder2_mmpp;//mm/s
                    speed = speed * 60 / 1000;//m/min
                    mDynArea.FilmVelocity = speed;
                }
            };

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


            //------------------------------------------------------------------------------------------------------------------------------------
            //数据有效-----------------------------------------------------------------------------------------------------------------------------
            mFlyAD.IStatusChangedEvent += (s, e) =>
            {
                if (mInitParam.DataValidSrc != DATAVALIDSRC.BYINPUT)
                    return;

                if (Misc.MyBase.CHECKBIT(e.IChanged, 6 - 1))
                {
                    if (!Misc.MyBase.CHECKBIT(e.IStatus, 6 - 1))
                        mDynArea.DataValid = false;
                    else
                        mDynArea.DataValid = true;
                }
            };

            Misc.BindingOperations.SetBinding(mInitParam, new string[] { "DataValidSrc" }, update_datavalid);


            Misc.BindingOperations.SetBinding(mFlyAD, new string[] { "Ratio02", "Ratio01" },
                delegate()
                {
                    mInitParam.Speed1Scale = (double)mFlyAD.Ratio02 / mFlyAD.Ratio01;
                });

            Misc.BindingOperations.SetBinding(mInitParam, new string[] { "SVelocity", "ATime", "DTime", "HVelocity1", "HVelocity2" },
                delegate()
                {
                    PollModule.Current.Poll_JustOnce(delegate()
                    {
                        mFlyAD.SetPosParam(0xffffffff, mInitParam.SVelocity, mInitParam.ATime, mInitParam.DTime, mInitParam.HVelocity1, mInitParam.HVelocity2);

                    }, this, MARKNO_UPDATEV);
                });

            Misc.BindingOperations.SetBinding(mFlyAD, new string[] { "IsConnected" },
                delegate()
                {
                    if (mFlyAD.IsConnected == true)
                    {
                        //还需要在flyad 重新连接上时,设置!!!!!
                        PollModule.Current.Poll_JustOnce(delegate()
                        {
                            mFlyAD.SetPosParam(0xffffffff, mInitParam.SVelocity, mInitParam.ATime, mInitParam.DTime, mInitParam.HVelocity1, mInitParam.HVelocity2);

                        }, this, MARKNO_UPDATEV);
                    }
                });



            //---------------------------------------------------------------------------------------------------------------
            //Warning_Create
            mWarning = new OBJComponents.Server.WarningSystem(mHistoryDb.ErrorBuffer);

            Misc.BindingOperations.SetBinding(mWarning, "IsRinging", () =>
            {
                if (mWarning.IsRinging)
                {
                    mFlyAD.SetOutput(
                        (UInt16)Misc.MyBase.BIT(4 - 1),
                        (UInt16)~Misc.MyBase.BIT(4 - 1));
                }
                else
                {
                    mFlyAD.SetOutput(
                        (UInt16)Misc.MyBase.BIT(4 - 1),
                        (UInt16)Misc.MyBase.BIT(4 - 1));
                }
            });

            //---------------------------------------------------------------------------------------------------------------
            //ScanWarning_Create
            mScanWarning = new ScanWarning();
            mScanWarning.Init(mWarning, mHistoryDb);


            //---------------------------------------------------------------------------------------------------------------
            //GM_Fix_Create
            mGMFix = new GM_Fix(mFlyAD);
            mGMFix.Init(mDynArea, AD2Thick);
            mGMManager.AddGM(mGMFix);


            //---------------------------------------------------------------------------------------------------------------
            //GM_AutoScan_Create
            mGMAutoScan = new GM_AutoScan(mFlyAD);
            mGMAutoScan.Init(StartP1);
            Misc.BindingOperations.SetBinding(mGMAutoScan, "Counter", mDynArea, "AutoScanCounter");
            mGMManager.AddGM(mGMAutoScan);

            //---------------------------------------------------------------------------------------------------------------
            //GM_Disconnected_Create
            mGMDisconnected = new GM_Disconnected(mFlyAD);
            mGMDisconnected.Init(mDynArea, mGMAutoScan);
            mGMManager.AddGM(mGMDisconnected);

            //---------------------------------------------------------------------------------------------------------------
            //GM_Pause_Create
            mGMPause = new GM_Pause(mFlyAD);
            mGMPause.Init(mDynArea, mGMAutoScan);
            Misc.BindingOperations.SetBinding(mInitParam, "ReStartDelay", mGMPause, "Delay");
            Misc.BindingOperations.SetBinding(mInitParam, "AutoF1F3", mGMPause, "Enable");
            mGMManager.AddGM(mGMPause);

            //---------------------------------------------------------------------------------------------------------------
            //GM_Forward_Create
            mGMForw = new GM_Forward(mFlyAD);
            Misc.BindingOperations.SetBinding(mInitParam, "VJOG", mGMForw, "Velocity");
            mGMManager.AddGM(mGMForw);

            //---------------------------------------------------------------------------------------------------------------
            //GM_Backward_Create
            mGMBackw = new GM_Backward(mFlyAD);
            Misc.BindingOperations.SetBinding(mInitParam, "VJOG", mGMBackw, "Velocity");
            mGMManager.AddGM(mGMBackw);

            //---------------------------------------------------------------------------------------------------------------
            //GM_Goto_Create
            mGMRunto = new GM_Goto(mFlyAD);
            Misc.BindingOperations.SetBinding(mInitParam, "VJOG", mGMRunto, "Velocity");
            mGMManager.AddGM(mGMRunto);

            //---------------------------------------------------------------------------------------------------------------
            //GM_Origin_Create
            mGMOrg = new GM_Origin(mFlyAD);
            mGMManager.AddGM(mGMOrg);

            //---------------------------------------------------------------------------------------------------------------
            //GM_Stop_Create
            mGMStop = new GM_Stop(mFlyAD);
            mGMManager.AddGM(mGMStop);

            //---------------------------------------------------------------------------------------------------------------
            //GM_GageInfo_Create
            mGMGageInfo = new GM_GageInfo(mFlyAD);
            Misc.BindingOperations.SetBinding(mInitParam, "VAccuracy", mGMGageInfo, "Velocity");
            mGMManager.AddGM(mGMGageInfo);

            //---------------------------------------------------------------------------------------------------------------
            //GM_ScanCorr_Create
            mGMScanCorr = new GM_ScanCorr(mFlyAD);
            mGMManager.AddGM(mGMScanCorr);
            mFlyAD.CorrectADs = new FlyADBase.CorrectADsHandler(mGMScanCorr.CorrectADs);
            Misc.BindingOperations.SetBinding(mInitParam, "VAccuracy", mGMScanCorr, "Velocity");

            Misc.BindingOperations.SetBinding(mBorderSearch.Valid, "Begin", mGMScanCorr, "ValidBegin", BindingOperations.BindingMode.TwoWay);
            Misc.BindingOperations.SetBinding(mBorderSearch.Valid, "End", mGMScanCorr, "ValidEnd", BindingOperations.BindingMode.TwoWay);
            


            //---------------------------------------------------------------------------------------------------------------
            //GSample_Create
            mGetSample = new GSample(mFlyAD, mGMGageInfo);
            Misc.BindingOperations.SetBinding(mGetSample.Samples[0], "AD", mBorderSearch, "CurrTempAD");
            Misc.BindingOperations.SetBinding(mInitParam, "VAccuracy", mGetSample, "Velocity");
            mGetSample.SampleChangedEvent += new SampleChangedEventHandler(getSample_SampleChangedEvent);

            //---------------------------------------------------------------------------------------------------------------
            //GM_RenZiJiaScan_Create
            mGMRenZiJiaScan = new GM_BlowingScan(mFlyAD, mGetSample);
            mGMManager.AddGM(mGMRenZiJiaScan);

            //---------------------------------------------------------------------------------------------------------------
            //Bulkdata_Create
            mBulk = new BulkDataService(mGMRenZiJiaScan.NBolts, 1, 400);
            mBulkClient = new BulkDataServiceClientAdv(mBulk);



            Misc.BindingOperations.SetBinding(mInitParam, "AutoOrgInterval", mGMRenZiJiaScan, "OrgInterval");
            Misc.BindingOperations.SetBinding(mInitParam, "VScan", mGMRenZiJiaScan, "Velocity");

            Misc.BindingOperations.SetBinding(mGMRenZiJiaScan, "FilmVelocity", mDynArea, "FilmVelocity");

            mDynArea.NBolts = mGMRenZiJiaScan.NBolts;
            mDynArea.FirstBoltNo = 1;
            mDynArea.DataBoltNoBegin = 1;
            mDynArea.DataBoltNoEnd = mGMRenZiJiaScan.NBolts;
            mDynArea.ScanBoltNoBegin = 1;
            mDynArea.ScanBoltNoEnd = mGMRenZiJiaScan.NBolts;

            mGMRenZiJiaScan.Init(
                mBulk,
                mBorderSearch,
                mDynArea, new AD2ThickHandler(AD2Thick),
                mProfile.Param, mHistoryDb, mBulkDb);

            mGMRenZiJiaScan.PropertyChanged += (s, e) =>
            {
                if (e.PropertyName == "NBolts")
                {
                    mBulk.NBolts = mGMRenZiJiaScan.NBolts;

                    mDynArea.NBolts = mGMRenZiJiaScan.NBolts;
                    mDynArea.FirstBoltNo = 1;

                    mDynArea.DataBoltNoBegin = 1;
                    mDynArea.DataBoltNoEnd = mGMRenZiJiaScan.NBolts;
                    mDynArea.ScanBoltNoBegin = 1;
                    mDynArea.ScanBoltNoEnd = mGMRenZiJiaScan.NBolts;
                }
            };



        
            ErrNoForCheckInit();


            #endregion
            mGMFix.Start();
        }


        class ErrNoForCheckItem
        {
            public FLY.OBJComponents.Common.ERRNO errno;
            public Func<bool> conditional;
            /// <summary>
            /// 持续时间,单位s
            /// </summary>
            public int cnt;

            int timer = -1;
            public FLY.OBJComponents.Server.WarningSystem mWarning;
            public void Clear()
            {
                if (timer == 0)
                {
                    mWarning.Add(
                        errno.Code,
                        errno.Descrption,
                        FLY.OBJComponents.Common.ERR_STATE.OFF);
                }
                timer = -1;
            }
            public void OnPoll()
            {
                if (conditional())
                {
                    if (timer < 0)
                        timer = cnt;
                    else
                    {
                        if (timer > 0)
                            timer--;

                        if (timer == 0)
                        {
                            mWarning.Add(
                                errno.Code,
                                errno.Descrption,
                                FLY.OBJComponents.Common.ERR_STATE.ON);
                        }
                    }
                }
                else
                {
                    Clear();
                }
            }
        }

        List<ErrNoForCheckItem> ErrNoForCheckItems = new List<ErrNoForCheckItem>();
        void ErrNoForCheckInit()
        {

            ErrNoForCheckItems.Add(//AD值太小
                new ErrNoForCheckItem()
                {
                    errno = FLY.Thick.BlowingScan.Common.ERRNOs.BASE_ERRNO_AD_MIN,
                    cnt = 20,
                    conditional = delegate ()
                    {
                        return mDynArea.AD < (mDynArea.ADMax * 0.01);
                    }
                });

            ErrNoForCheckItems.Add(//AD值太大
                new ErrNoForCheckItem()
                {
                    errno = FLY.Thick.BlowingScan.Common.ERRNOs.BASE_ERRNO_AD_MAX,
                    cnt = 20,
                    conditional = delegate ()
                    {
                        return (mDynArea.AD > (mDynArea.ADMax * 0.98));
                    }
                });

            foreach (ErrNoForCheckItem item in ErrNoForCheckItems)
            {
                item.mWarning = mWarning;
            }

            FObjBase.PollModule.Current.Poll_Config(
                FObjBase.PollModule.POLL_CONFIG.ADD,
                onpoll_checkErrNo, TimeSpan.FromSeconds(1));
        }

        bool isInit_onpoll_checkErrNo;
        void onpoll_checkErrNo() //1秒执行一次
        {
            if (!isInit_onpoll_checkErrNo)
            {
                isInit_onpoll_checkErrNo = true;
                checkDynAreaError();
            }

            if (!mDynArea.FLYADIsConnect)
            {
                foreach (ErrNoForCheckItem item in ErrNoForCheckItems)
                    item.Clear();
            }
            else
            {
                foreach (ErrNoForCheckItem item in ErrNoForCheckItems)
                    item.OnPoll();
            }
        }


        #region 辊信号生成 线速度
        DispatcherTimer round_t;
        DateTime dtRound = DateTime.MinValue;
        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 (mInitParam.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 = mInitParam.MmOfR / 1000.0 / (dt - dtRound).TotalMinutes;

                if (v < 1)
                {
                    dt = DateTime.MinValue;
                    v = 0;
                }
                mDynArea.FilmVelocity = v;
            }

            dtRound = dt;

            if (dtRound != DateTime.MinValue)
            {
                if (!round_t.IsEnabled)
                    round_t.Start();
            }
        }
        void round_t_Tick(object sender, EventArgs e)
        {
            if (mInitParam.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 = mInitParam.MmOfR / 1000.0 / (dt - dtRound).TotalMinutes;

            if (v < (mDynArea.FilmVelocity - 1))
            {
                if (v < 2)
                {
                    dtRound = DateTime.MinValue;
                    v = 0;
                }
                mDynArea.FilmVelocity = v;
            }

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

        #endregion
        void mDynArea_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "FilmVelocity")
            {
                update_datavalid();
            }
            else if (e.PropertyName == "Hrs")
            {
                if (mDynArea.Hrs < 48 && mDynArea.Hrs > 0)//授权限制提醒
                {

                    mWarning.Add(
                        FLY.Thick.Blowing.Common.ERRNOs.BASE_ERRNO_LICENSE_TIP.Code,
                        FLY.Thick.Blowing.Common.ERRNOs.BASE_ERRNO_LICENSE_TIP.Descrption,
                        OBJComponents.Common.ERR_STATE.ON);
                }
            }
            else if (e.PropertyName == "SecuteLock") //授权限制
            {
                if (mDynArea.SecuteLock)
                {
                    mWarning.Add(
                        FLY.Thick.Blowing.Common.ERRNOs.BASE_ERRNO_LICENSE.Code,
                        FLY.Thick.Blowing.Common.ERRNOs.BASE_ERRNO_LICENSE.Descrption,
                        OBJComponents.Common.ERR_STATE.ON);
                }
                else
                {
                    mWarning.Add(
                        FLY.Thick.Blowing.Common.ERRNOs.BASE_ERRNO_LICENSE.Code,
                        FLY.Thick.Blowing.Common.ERRNOs.BASE_ERRNO_LICENSE.Descrption,
                        OBJComponents.Common.ERR_STATE.ON);
                }
            }
            else if (e.PropertyName == "FLYADIsConnect")//连接断开
            {
                if (!mDynArea.FLYADIsConnect)
                {
                    mWarning.Add(
                        FLY.Thick.Blowing.Common.ERRNOs.BASE_ERRNO_FLYAD7DISCONNECTED.Code,
                        FLY.Thick.Blowing.Common.ERRNOs.BASE_ERRNO_FLYAD7DISCONNECTED.Descrption,
                        OBJComponents.Common.ERR_STATE.ON);

                }
                else
                {
                    mWarning.Add(
                        FLY.Thick.Blowing.Common.ERRNOs.BASE_ERRNO_FLYAD7DISCONNECTED.Code,
                        FLY.Thick.Blowing.Common.ERRNOs.BASE_ERRNO_FLYAD7DISCONNECTED.Descrption,
                        OBJComponents.Common.ERR_STATE.OFF);
                }
            }

        }

        void checkDynAreaError()
        {
            if (mDynArea.Hrs < 48 && mDynArea.Hrs > 0)//授权限制提醒
            {
                mWarning.Add(
                    Common.ERRNOs.BASE_ERRNO_LICENSE_TIP.Code,
                    Common.ERRNOs.BASE_ERRNO_LICENSE_TIP.Descrption,
                    OBJComponents.Common.ERR_STATE.ON);
            }
            if (mDynArea.SecuteLock)
            {
                mWarning.Add(
                    Common.ERRNOs.BASE_ERRNO_LICENSE.Code,
                    Common.ERRNOs.BASE_ERRNO_LICENSE.Descrption,
                    OBJComponents.Common.ERR_STATE.ON);
            }
            if (!mDynArea.FLYADIsConnect)
            {
                mWarning.Add(
                    Common.ERRNOs.BASE_ERRNO_FLYAD7DISCONNECTED.Code,
                    Common.ERRNOs.BASE_ERRNO_FLYAD7DISCONNECTED.Descrption,
                    OBJComponents.Common.ERR_STATE.ON);
            }

        }

        void update_datavalid()
        {
            switch (mInitParam.DataValidSrc)
            {
                case DATAVALIDSRC.VALID:
                    mDynArea.DataValid = true;
                    break;
                case DATAVALIDSRC.INVALID:
                    mDynArea.DataValid = false;
                    break;
                case DATAVALIDSRC.BYEN2:
                    {
                        if (mDynArea.FilmVelocity < 2)
                            mDynArea.DataValid = false;
                        else
                            mDynArea.DataValid = true;
                    } break;
                case DATAVALIDSRC.BYINPUT:
                    {
                        if (!Misc.MyBase.CHECKBIT(mFlyAD.IStatus, 6 - 1))
                            mDynArea.DataValid = false;
                        else
                            mDynArea.DataValid = true;
                    } break;
            }
        }


        

        #region 数据改变----------------------------------------------------------------




        #endregion

        #region AD卡密码操作,主机版本号操作--------------------------------------------------------
        public string Version//获取版本号
        {
            get
            {
                System.Reflection.Assembly ma = System.Reflection.Assembly.GetEntryAssembly();
                FileInfo fi = new FileInfo(ma.Location);
                FileVersionInfo mfv = FileVersionInfo.GetVersionInfo(ma.Location);
                return mfv.FileVersion;
            }

        }
        #endregion

        public int AD2Thick(int ad)
        {
            int thick = Misc.MyBase.NULL_VALUE;

            if (Misc.MyBase.ISVALIDATA(ad))
            {

                if (mGetSample.Enable)//动态温修
                    thick = mCurve.AD2Value(ad, AD2ValueFlag.Revised);
                else
                    thick = mCurve.AD2Value(ad, AD2ValueFlag.NoRevised);
                
                thick = (int)(thick * mProfile.Param.K);
            }
            return thick;
        }




        void getSample_SampleChangedEvent(object sender)
        {

            CurveCollection pCurve = mCurve;
            GSample gsample = mGetSample;


            for (int i = 0; i < gsample.Samples.Count(); i++)
            {
                mDynArea.SampleAD[i] = gsample.Samples[i].AD;
            }

            if (gsample.OK())
            {
                List<CurveCollection.ExChange> list = new List<CurveCollection.ExChange>();
                for (int i = 0; i < gsample.Samples.Count(); i++)
                {
                    ISampleCell sample = gsample.Samples[i];
                    if ((sample.Enable) && (!sample.JustForCheck) && (sample.AD > 0))
                    {
                        list.Add(new CurveCollection.ExChange() { OrgAD = sample.OrgAD, CurrAD = sample.AD });
                    }
                }
                pCurve.ModifyExChange(list);
                pCurve.ReviseCurve();
                
                for (int i = 0; i < gsample.Samples.Count(); i++)
                {
                    ISampleCell sample = gsample.Samples[i];
                    if ((sample.Enable) && (sample.AD > 0))
                    {
                        sample.SampleValue = mCurve.AD2Value(sample.AD, AD2ValueFlag.Revised);
                    }
                }
                
                //历史数据保存
                var sampleads = from sample in gsample.Samples where sample.Enable select sample.AD;
                if (sampleads.Count() > 0)
                {
                    mHistoryDb.AddSampleData(
                        new Lc_Sample()
                        {
                            Time = DateTime.Now,
                            SampleADs = sampleads.ToArray()
                        });
                }

            }
        }


        #region ITDGageService

        /// <summary>
        /// 
        /// </summary>
        public void StartP1()
        {
            mGMRenZiJiaScan.Start();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mode"></param>
        public void StartP2(STARTP2_MODE mode)
        {
            StartP2(mode, 0);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mode"></param>
        /// <param name="targetpos"></param>
        public void StartP2(STARTP2_MODE mode, int targetpos)
        {
            switch (mode)
            {
                case STARTP2_MODE.ORG:
                    mGMOrg.Start();
                    break;
                case STARTP2_MODE.STOP:
                    mGMStop.Start();
                    break;
                case STARTP2_MODE.FORW:
                case STARTP2_MODE.FORW_UNTIL_STOP:
                    mGMForw.Start();
                    break;
                case STARTP2_MODE.BACKW:
                case STARTP2_MODE.BACKW_UNTIL_STOP:
                    mGMBackw.Start();
                    break;
                case STARTP2_MODE.RUNTO:
                    mGMRunto.Start(targetpos);
                    break;
            }
        }

        #endregion
    }
}