using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLY.Thick.BulkDataModule;
using FLY.Thick.Base.Common;
using System.ComponentModel;
using FLY.Thick.Base.IService;


namespace FLY.Thick.Base.Server
{
    public class ScanWarning: Misc.ISaveToXml, INotifyPropertyChanged,IScanWarningService
    {
        private IWarningServiceSimple mWarning;
        private IBulkDataService mBulkData;


        private int mBookmark;
        private bool enable;
        public bool Enable{
            get {
                return enable;
            }
            set {
                if (enable != value) 
                {
                    enable = value;
                    NotifyPropertyChanged("Enable");
                }
            }
        }
        int target;
        /// <summary>
        /// 目标值，绑定 dynarea.Target
        /// </summary>
        public int Target
        {
            get
            {
                return target;
            }
            protected set
            {
                if (target != value)
                {
                    target = value;
                    NotifyPropertyChanged("Target");
                }
            }
        }
	    int alarm;
        /// <summary>
        /// 产品公差，绑定 dynarea.Alarm
        /// </summary>
        public int Alarm
        {
            get
            {
                return alarm;
            }
            protected set
            {
                if (alarm != value)
                {
                    alarm = value;
                    NotifyPropertyChanged("Alarm");
                }
            }
        }
        
        double alarmline;
        /// <summary>
        /// 报警线 = 产品公差 * AlarmLine
        /// </summary>
	    public double AlarmLine
        {
            get
            {
                return alarmline;
            }
            set
            {
                if (alarmline != value)
                {
                    alarmline = value;
                    NotifyPropertyChanged("AlarmLine");
                }
            }
        }

        int alarmcnt;
        /// <summary>
        /// 连续多少个点，才算报警
        /// </summary>
        public int AlarmCnt
        {
            get
            {
                return alarmcnt;
            }
            set
            {
                if (alarmcnt != value)
                {
                    alarmcnt = value;
                    NotifyPropertyChanged("AlarmCnt");
                }
            }
        }



        int mix;
        /// <summary>
        /// 混合数
        /// </summary>
        public int Mix
        {
            get
            {
                return mix;
            }
            set
            {
                if (mix != value)
                {
                    mix = value;
                    NotifyPropertyChanged("Mix");
                }
            }
        }
        bool Check(int[] data) 
        {
            int cnt = 0;
            for (int i = 0; i < data.Length; i++) 
            {
                int d = data[i];
                if(!Misc.MyBase.ISVALIDATA(d))
                {
                    cnt=0;
                }
                else
                {
                    int delta = Math.Abs(d - Target);
                    if (delta > AlarmLine * Alarm)
                    {
                        //触发
                        cnt++;
                        if (cnt >= AlarmCnt) 
                        {
                            //需要报警
                            return true;
                        }
                    }
                    else 
                    {
                        cnt = 0;
                    }
                }
            }
            return false;
        }
        public void Apply() {
            Save();
        }
        public ScanWarning() 
        {
            Mix = 6;
            AlarmCnt = 5;
            AlarmLine = 1;
            Enable = false;
            Load();
        }
        int curr_frame_mix;
        public void Init(IWarningServiceSimple warning, DynArea dynarea, IBulkDataService bulkdata) 
        {
            mWarning = warning;
            mBulkData = bulkdata;
            Misc.BindingOperations.SetBinding( dynarea, "Target", this, "Target");
            Misc.BindingOperations.SetBinding( dynarea, "Alarm", this, "Alarm");
            this.PropertyChanged += new PropertyChangedEventHandler(ScanWarning_PropertyChanged);
            FObjBase.PollModule.Current.Poll_JustOnce(
                delegate()
                {
                    curr_frame_mix = Mix;
                    mBulkData.PushNewFrameData(
                        new BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataParam
                        {
                            mix = Mix
                        }, GetFrameDataCB, this);
                }, this, 1);
        }
        void GetFrameDataCB(object AyncState, object retData) 
        {
            BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn reponse = retData as BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataReturn;
            if (Enable)
            {
                if (Check(reponse.result))
                {
                    //报警
                    mWarning.Add( 
                        ERRNOs.SCAN_ERRNO_OVERRUN.Type,
                        ERRNOs.SCAN_ERRNO_OVERRUN.Code,
                        ERRNOs.SCAN_ERRNO_OVERRUN.Descrption,
                        ERR_STATE.ONCE);
                }
            }
        }
        void ScanWarning_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Mix") 
            {
                mBulkData.ClosePushNewFrameData(
                        new BULKDATA_OBJ_INTERFACE.Pack_CallClosePushNewFrameData()
                        {
                            mix = curr_frame_mix
                        }, this);

                curr_frame_mix = Mix;

                mBulkData.PushNewFrameData(
                    new BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataParam()
                    {
                        mix = curr_frame_mix
                    }, GetFrameDataCB, this);
            }
        }
        public void Save() 
        {
            Misc.SaveToXmlHepler.Save("scanwarning.xml", this);
        }
        public bool Load() 
        {
            return Misc.SaveToXmlHepler.Load("scanwarning.xml", this);
        }
        #region INotifyPropertyChanged 成员
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion




        public string[] GetSavePropertyNames()
        {
            return new string[]{
                "Enable","Mix","AlarmLine","AlarmCnt"};
        }
    }
}
