using FLY.Thick.Base.IService;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Navigation;
using Unity;

namespace FLY.Thick.Base.UI
{
    /// <summary>
    /// Page_GetSample.xaml 的交互逻辑
    /// </summary>
    public partial class PgGetSample : Page
    {
        IGetSampleService getSampleService;
        IInitParamService initParamService;

        PgGetSampleVm viewModel;

        public PgGetSample()
        {
            InitializeComponent();
        }
        [InjectionMethod]
        public void Init(
            IGetSampleService getSampleService,
            IInitParamService initParamService,
            string infoName = null)
        {

            this.getSampleService = getSampleService;
            this.initParamService = initParamService;

            viewModel = new PgGetSampleVm();
            viewModel.Init(getSampleService, infoName);
            this.DataContext = viewModel;
            this.grid_initparam.DataContext = this.initParamService;
        }
    }

    public class PgGetSampleVm : INotifyPropertyChanged
    {
        #region Markno
        const int MARKNO_UPDATE_SAMPLE = 1;
        const int MARKNO_UPDATE_FEATURE = 2;

        #endregion
        #region 参数

        /// <summary>
        /// 参数:使能
        /// </summary>
        public bool Enable { get; set; }

        /// <summary>
        /// 参数:样品点范围
        /// </summary>
        public int SampleRange { get; set; }

        /// <summary>
        /// 参数:移动滤波 ,窗口值
        /// </summary>
        public int Window { get; set; }

        /// <summary>
        /// 使用%方式检查异常
        /// </summary>
        public bool IsCheckByPercent { get; set; }
        /// <summary>
        /// 异常%
        /// </summary>
        public double ErrPercent { get; set; }
        /// <summary>
        /// 异常值
        /// </summary>
        public int ErrValue { get; set; }

        /// <summary>
        /// 当前 样品X_AD/样品0_AD 与 上一次比较 差异比例 单位不是%
        /// </summary>
        public double CrossErrPercent { get; set; }
        
        /// <summary>
        /// 异常比较 时间间隔范围;
        /// 两次时间点比较, 时间点的间隔最大时长。 大于它无效,不能比较
        /// </summary>
        public int ErrIntervalMin { get; set; }

        /// <summary>
        /// 参数:样品点参数
        /// </summary>
        public SampleCellView[] Samples { get; set; }
        /// <summary>
        /// 参数:特征查找范围
        /// </summary>
        public int SearchRange { get; set; }
        /// <summary>
        /// 参数:特征参数
        /// </summary>
        public SampleFeatureView[] Features { get; set; }

        #endregion

        #region Command
        public RelayCommand ApplyCmd { get; private set; }
        public RelayCommand GetTempDataCmd { get; private set; }
        #endregion

        public event PropertyChangedEventHandler PropertyChanged;

        public List<List<TempFilterData>> TempData { get; private set; }
        public string InfoName { get; set; }

        IGetSampleService getSampleService;
        
        public PgGetSampleVm()
        {
            ApplyCmd = new RelayCommand(Apply);
            GetTempDataCmd = new RelayCommand(GetTempData);
        }



        public void Init(
            IGetSampleService getSampleService,
            string infoName)
        {
            InfoName = infoName;
            this.getSampleService = getSampleService;
            Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.Enable), this, nameof(Enable));
            Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.SampleRange), this, nameof(SampleRange));
            Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.Window), this, nameof(Window));
            Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.IsCheckByPercent), this, nameof(IsCheckByPercent));
            Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.ErrPercent), this, nameof(ErrPercent));
            Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.ErrValue), this, nameof(ErrValue));
            Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.CrossErrPercent), this, nameof(CrossErrPercent));
            Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.ErrIntervalMin), this, nameof(ErrIntervalMin));


            Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.SearchRange), this, nameof(SearchRange));
            
            Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.Samples), ()=> {
                FObjBase.PollModule.Current.Poll_JustOnce(updateSamples, this, MARKNO_UPDATE_SAMPLE);
            });

            Misc.BindingOperations.SetBinding(this.getSampleService, nameof(this.getSampleService.Features), () => {
                FObjBase.PollModule.Current.Poll_JustOnce(updateFeatures, this, MARKNO_UPDATE_FEATURE);
            });
        }

        void updateSamples() 
        {
            var samples = this.getSampleService.Samples;

            if (samples == null)
            {
                Samples = null;
            }
            else
            {
                var sampleViews = new SampleCellView[samples.Count()];
                for (int i = 0; i < sampleViews.Count(); i++)
                {
                    sampleViews[i] = new SampleCellView() { Name = i.ToString() };
                    var sampleView = sampleViews[i];
                    var sample = samples[i];
                    Misc.BindingOperations.SetBinding(sample, nameof(SampleCell.Enable), sampleView, nameof(SampleCellView.Enable));
                    Misc.BindingOperations.SetBinding(sample, nameof(SampleCell.JustForCheck), sampleView, nameof(SampleCellView.JustForCheck));
                    Misc.BindingOperations.SetBinding(sample, nameof(SampleCell.OrgAD), sampleView, nameof(SampleCellView.OrgAD));
                    Misc.BindingOperations.SetBinding(sample, nameof(SampleCell.Position), sampleView, nameof(SampleCellView.Position));

                    Misc.BindingOperations.SetBinding(sample, nameof(SampleCell.AD), sampleView, nameof(SampleCellView.AD));
                    Misc.BindingOperations.SetBinding(sample, nameof(SampleCell.SampleValue), sampleView, nameof(SampleCellView.SampleValue));
                }
                updateSampleCellViewVisible(sampleViews);

                Samples = sampleViews;
                
                for (int i = 0; i < Samples.Count(); i++)
                {
                    var sampleView = Samples[i];
                    sampleView.PropertyChanged += (s, e) =>
                    {
                        if (e.PropertyName == nameof(SampleCellView.Enable))
                        {
                            updateSampleCellViewVisible();
                        }
                    };
                }
            }
        }
        void updateFeatures() 
        {
            var features = this.getSampleService.Features;
            if (features == null)
            {
                Features = null;
            }
            else
            {
                int cnt = Math.Min(features.Count(), 2);
                var featureViews = new SampleFeatureView[cnt];
                for (int i = 0; i < featureViews.Count(); i++)
                {
                    featureViews[i] = new SampleFeatureView();
                    var featureView = featureViews[i];
                    if (i == 0)
                        featureView.Name = "正向";
                    else
                        featureView.Name = "反向";
                    var feature = features[i];
                    Misc.BindingOperations.SetBinding(feature, nameof(SampleFeature.Enable), featureView, nameof(SampleFeatureView.Enable));
                    Misc.BindingOperations.SetBinding(feature, nameof(SampleFeature.StartPos), featureView, nameof(SampleFeatureView.StartPos));
                    Misc.BindingOperations.SetBinding(feature, nameof(SampleFeature.EndPos), featureView, nameof(SampleFeatureView.EndPos));

                    Misc.BindingOperations.SetBinding(feature, nameof(SampleFeature.MaxRelevancy), featureView, nameof(SampleFeatureView.MaxRelevancy));
                    Misc.BindingOperations.SetBinding(feature, nameof(SampleFeature.MaxOffset), featureView, nameof(SampleFeatureView.MaxOffset));

                }
                Features = featureViews;
            }
        }
        protected void updateSampleCellViewVisible(SampleCellView[] sampleViews) 
        {
            if (sampleViews == null)
                return;

            for (int i = 0; i < sampleViews.Count(); i++) {
                if (i == 0)
                    sampleViews[i].IsVisible = true;
                else
                {
                    sampleViews[i].IsVisible = sampleViews[i-1].Enable;
                }
            }
        }
        protected void updateSampleCellViewVisible()
        {
            updateSampleCellViewVisible(Samples);
        }
        private void Apply()
        {
            if (!WdPassword.Authorize("GetSample"))
                return;



            this.getSampleService.Enable = this.Enable;
            this.getSampleService.SampleRange = this.SampleRange;
            this.getSampleService.Window = this.Window;
            this.getSampleService.IsCheckByPercent = this.IsCheckByPercent;
            this.getSampleService.ErrPercent = this.ErrPercent;
            this.getSampleService.ErrValue = this.ErrValue;
            this.getSampleService.CrossErrPercent = this.CrossErrPercent;
            this.getSampleService.ErrIntervalMin = this.ErrIntervalMin;

            for (int i = 0; i < Samples.Count(); i++)
            {
                var sample_src = this.Samples[i];
                var sample_desp = this.getSampleService.Samples[i];

                sample_desp.Enable = sample_src.Enable;
                sample_desp.JustForCheck = sample_src.JustForCheck;
                sample_desp.OrgAD = sample_src.OrgAD;
                sample_desp.Position = sample_src.Position;
            }
            this.getSampleService.SearchRange = this.SearchRange;
            for (int i = 0; i < Features.Count(); i++)
            {
                var feature_src = this.Features[i];
                var feature_desp = this.getSampleService.Features[i];


                feature_desp.Enable = feature_src.Enable;
                feature_desp.StartPos = feature_src.StartPos;
                feature_desp.EndPos = feature_src.EndPos;
            }

            getSampleService.Apply();
            FLY.ControlLibrary.Window_Tip.Show("应用成功",
                null,
                TimeSpan.FromSeconds(2));
        }

        private void GetTempData()
        {
            getSampleService.GetTempFilterDatas((asyncContext, retData) =>
            {
                var ll = retData as List<List<TempFilterData>>;
                TempData = ll;
                FLY.ControlLibrary.Window_Tip.Show("加载完成",
                    $"共加载{ll.Count()}列数据",
                    TimeSpan.FromSeconds(2));
            }, null);
        }
    }
    public class PgGetSampleVmUt : PgGetSampleVm
    {
        public PgGetSampleVmUt()
        {
            Samples = new SampleCellView[3];
            for (int i = 0; i < Samples.Count(); i++)
            {
                SampleCellView sampleCell = new SampleCellView() { Name = i.ToString() };
                Samples[i] = sampleCell;
            }
            
            Features = new SampleFeatureView[2];
            Features[0] = new SampleFeatureView() { Name = "正向" };
            Features[1] = new SampleFeatureView() { Name = "反向" };


            Enable = true;
            Samples[0].Enable = true;

            Features[0].Enable = true;

            updateSampleCellViewVisible();
        }
    }

    /// <summary>
    /// 样品点
    /// </summary>
    public class SampleCellView : INotifyPropertyChanged
    {
        /// <summary>
        /// 序号
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 显示出来
        /// </summary>
        public bool IsVisible { get; set; }

        /// <summary>
        /// 参数:使能
        /// </summary>
        public bool Enable { get; set; }

        /// <summary>
        /// 参数:只检查不标定
        /// </summary>
        public bool JustForCheck { get; set; }

        /// <summary>
        /// 参数:原始AD值
        /// </summary>
        public int OrgAD { get; set; }

        /// <summary>
        /// 参数:位置
        /// </summary>
        public int Position { get; set; }

        public int AD { get; set; }
        public double SampleValue { get; set; }


        #region INotifyPropertyChanged 成员

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

    }

    /// <summary>
    /// 样品正向校正特征
    /// </summary>
    public class SampleFeatureView : INotifyPropertyChanged
    {
        /// <summary>
        /// 序号
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 参数:使能
        /// </summary>
        public bool Enable { get; set; }


        /// <summary>
        /// 参数:开始位置
        /// </summary>
        public int StartPos { get; set; }


        /// <summary>
        /// 参数:结束位置
        /// </summary>
        public int EndPos { get; set; }

        public double MaxRelevancy { get; set; }
        public int MaxOffset { get; set; }
        #region INotifyPropertyChanged 成员

        public event PropertyChangedEventHandler PropertyChanged;


        #endregion
    }
}