using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using FLY.FilmCasting.AutoDie.Common;
using System.Net;
using FLY.Thick.Base.UI;
using FLY.FilmCasting.AutoDie.IService;
using System.ComponentModel;
using Unity;
using GalaSoft.MvvmLight.Command;

namespace FLY.FilmCasting.AutoDie.UI.Client
{
    /// <summary>
    /// Page_Setup.xaml 的交互逻辑
    /// </summary>
    public partial class PgSetup : Page
    {
        PgSetupVm viewModel;
        public PgSetup()
        {
            InitializeComponent();
        }

        [InjectionMethod]
        public void Init(
            IUnityContainer container,
            IFeedbackHeatService feedback,
            IHeatBufService heatBuf,
            IHeatCellService heatCell)
        {
            viewModel = new PgSetupVm();
            viewModel.Init(container,feedback, heatBuf, heatCell);
            this.DataContext = viewModel;
        }

    }

    public class PgSetupVm : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        #region 参数
        public double ThresholdHeatSigma { get; set; }
        public int Step { get; set; }
        public bool HasCheckFilmVelocity { get; set; }
        public bool HasCheck { get; set; }
        public int Delay { get; set; }
        public int ThresholdSigmaMax { get; set; }

        public int StableRange { get; set; }
        public int[] HeatEffectCurve { get; set; }
        public bool IsForbidUpDown { get; set; }

        public int CtrlLine { get; set; }
        public double Kp { get; set; }

        /// <summary>
        /// 对位模式, 加热与厚度相关性阀值, 相关性 >=0.7
        /// </summary>
        public double ThresholdR { get; set; }

        /// <summary>
        /// 最大功率
        /// </summary>
        public int MaxHeat { get; set; }

        /// <summary>
        /// 混合数
        /// </summary>
        public int Mix { get; set; }

        /// <summary>
        /// 膜距离
        /// </summary>
        public double FilmLength { get; set; } = 20;
        #endregion

        #region Command
        public RelayCommand SmoothCmd { get; }
        public RelayCommand ApplyCmd { get; }

        #endregion

        public IFeedbackHeatService Feedback{ get; private set; }
        public IHeatBufService HeatBuf { get; private set; }
        public IHeatCellService HeatCell { get; private set; }

        IUnityContainer container;
        public PgSetupVm() 
        {
            SmoothCmd = new RelayCommand(() => { 
                HeatCell.ThresholdHeatSigma = this.ThresholdHeatSigma; 
                HeatCell.Smooth(); 
            });
            ApplyCmd = new RelayCommand(Apply);


        }
        [InjectionMethod]
        public void Init(
            IUnityContainer container,
            IFeedbackHeatService feedback,
            IHeatBufService heatBuf,
            IHeatCellService heatCell)
        {
            this.container = container;
            this.Feedback = feedback;
            this.HeatBuf = heatBuf;
            this.HeatCell = heatCell;

            //参数绑定
            #region 参数
            Misc.BindingOperations.SetBinding(this.HeatCell, nameof(IHeatCellService.ThresholdHeatSigma), this, nameof(ThresholdHeatSigma));
            Misc.BindingOperations.SetBinding(this.HeatCell, nameof(IHeatCellService.IsForbidUpDown), this, nameof(IsForbidUpDown));
            Misc.BindingOperations.SetBinding(this.HeatCell, nameof(IHeatCellService.CtrlLine), this, nameof(CtrlLine));
            Misc.BindingOperations.SetBinding(this.HeatCell, nameof(IHeatCellService.Kp), this, nameof(Kp));
            Misc.BindingOperations.SetBinding(this.HeatCell, nameof(IHeatCellService.MaxHeat), this, nameof(MaxHeat));

            Misc.BindingOperations.SetBinding(this.Feedback, nameof(IFeedbackHeatService.Step), this, nameof(Step));
            Misc.BindingOperations.SetBinding(this.Feedback, nameof(IFeedbackHeatService.HasCheck), this, nameof(HasCheck));
            Misc.BindingOperations.SetBinding(this.Feedback, nameof(IFeedbackHeatService.Delay), this, nameof(Delay));
            Misc.BindingOperations.SetBinding(this.Feedback, nameof(IFeedbackHeatService.HasCheckFilmVelocity), this, nameof(HasCheckFilmVelocity));
            Misc.BindingOperations.SetBinding(this.Feedback, nameof(IFeedbackHeatService.FilmLength), this, nameof(FilmLength));
            Misc.BindingOperations.SetBinding(this.Feedback, nameof(IFeedbackHeatService.Mix), this, nameof(Mix));


            Misc.BindingOperations.SetBinding(this.HeatBuf, nameof(IHeatBufService.ThresholdSigmaMax), this, nameof(ThresholdSigmaMax));
            Misc.BindingOperations.SetBinding(this.HeatBuf, nameof(IHeatBufService.StableRange), this, nameof(StableRange));
            Misc.BindingOperations.SetBinding(this.HeatBuf, nameof(IHeatBufService.HeatEffectCurve), () =>
            {
                if (this.HeatBuf.HeatEffectCurve != null)
                    HeatEffectCurve = (int[])this.HeatBuf.HeatEffectCurve.Clone();
                else
                    HeatEffectCurve = null;
            });
            Misc.BindingOperations.SetBinding(this.HeatBuf, nameof(IHeatBufService.ThresholdR), this, nameof(ThresholdR));




            #endregion
        }

        bool CheckValid_HeatEffectCurve()
        {
            int[] list = HeatEffectCurve;

            if ((list == null) || (list.Count() == 0))
            {
                FLY.ControlLibrary.Window_WarningTip.Show(
                    "参数异常", "加热效果为空", TimeSpan.FromSeconds(2));
                return false;
            }
            int cnt = list.Count();
            if ((int)(cnt / 2) * 2 == cnt)
            {
                FLY.ControlLibrary.Window_WarningTip.Show(
                    "参数异常", "加热效果格式出错，应该如2,5,8,5,2", TimeSpan.FromSeconds(2));
                return false;
            }
            for (int i = 0; i < list.Count() / 2; i++)
            {
                int idx0 = i;
                int idx_0 = list.Count() - 1 - idx0;
                if (list[idx0] != list[idx_0])
                {
                    FLY.ControlLibrary.Window_WarningTip.Show(
                        "参数异常", "加热效果格式出错，应该如2,5,8,5,2", TimeSpan.FromSeconds(2));
                    return false;
                }
                int idx1 = idx0 + 1;
                if (list[idx0] > list[idx1])
                {
                    FLY.ControlLibrary.Window_WarningTip.Show(
                        "参数异常", "加热效果格式出错，应该如2,5,8,5,2", TimeSpan.FromSeconds(2));
                    return false;
                }
            }
            return true;
        }
        bool CheckValid()
        {
            if (CheckValid_HeatEffectCurve() == false)
                return false;

            if (Mix < 2) {
                FLY.ControlLibrary.Window_WarningTip.Show(
                    "参数异常", "混合数<2", TimeSpan.FromSeconds(2));
                return false;
            }

            if (FilmLength < 2)
            {
                FLY.ControlLibrary.Window_WarningTip.Show(
                    "参数异常", "模头到测厚仪距离<2m", TimeSpan.FromSeconds(2));
                return false;
            }
            return true;
        }

        private void Apply()
        {
            if (!WdPassword.Authorize("AutoDie"))
                return;

            if (!CheckValid())
                return;

            //参数设置
            HeatCell.ThresholdHeatSigma=this.ThresholdHeatSigma;
            HeatCell.IsForbidUpDown = this.IsForbidUpDown;
            HeatCell.CtrlLine = this.CtrlLine;
            HeatCell.Kp = this.Kp;
            HeatCell.MaxHeat = this.MaxHeat;


            Feedback.Step=this.Step;
            Feedback.HasCheckFilmVelocity=this.HasCheckFilmVelocity;
            Feedback.HasCheck=this.HasCheck;
            Feedback.Delay=this.Delay;
            Feedback.FilmLength = FilmLength;
            Feedback.Mix = Mix;




            HeatBuf.ThresholdSigmaMax=this.ThresholdSigmaMax;
            HeatBuf.StableRange=this.StableRange;
            HeatBuf.HeatEffectCurve=this.HeatEffectCurve;
            HeatBuf.ThresholdR = this.ThresholdR;

            HeatCell.Apply();
            HeatBuf.Apply();
            Feedback.Apply();
            FLY.ControlLibrary.Window_Tip.Show("参数设置", "成功", TimeSpan.FromSeconds(2));
        }
    }

    public class HeatEffectConverter : IValueConverter
    {
        #region IValueConverter 成员

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var list = value as int[];
            if (list == null)
            {
                return null;
            }
            string str = "";
            for (int i = 0; i < list.Count(); i++)
            {
                if (i == 0)
                    str += list[i].ToString();
                else
                    str += "," + list[i].ToString();
            }
            return str;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string str = value as string;
            if (string.IsNullOrEmpty(str))
            {
                //不合法
                return null;
            }
            string[] ss = str.Split(',');
            List<int> list = new List<int>();
            for (int i = 0; i < ss.Length; i++)
            {
                int num;
                if (int.TryParse(ss[i], out num))
                {
                    list.Add(num);
                }
            }
            return list.ToArray();
        }

        #endregion
    }
    public class TimeSpan2SecondConverter : IValueConverter
    {
        #region IValueConverter 成员

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (!(value is TimeSpan))
                return null;


            TimeSpan ts = (TimeSpan)value;
            return (int)(ts.TotalSeconds);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }

        #endregion
    }
    public class StableConverter : IValueConverter
    {
        #region IValueConverter 成员

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            STABILITY stable = (STABILITY)value;
            switch (stable)
            {
                case STABILITY.IDLE:
                    return "等待";
                case STABILITY.ERROR_NO_ARRIVE:
                    return "等待:加热点还没到达测厚仪";
                case STABILITY.ERROR_POSITION_NOTSURE:
                    return "等待:位置不能确定";
                case STABILITY.ERROR_SIGMA_OVERSIZE:
                    return "等待:2σ太大 ";
                case STABILITY.ERROR_ROTATE_CHANGED:
                    return "等待:旋转速度波动大 ";
                case STABILITY.ERROR_PARAM_CHANGED:
                    return "等待:膜距离旋转角度被改变";
                case STABILITY.ERROR_THICK_CHANGED:
                    return "等待:厚度均值波动大";
                case STABILITY.ERROR_CORREL:
                    return "等待:相关性不够";
                case STABILITY.OK_CORREL:
                    return "稳定:相关性高";
                case STABILITY.OK_HEAT_AND_THICK_CORREL:
                    return "稳定:加热相关性高";
                default:
                    return "???";
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }

        #endregion
    }
    public class MaxR2VisConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (!(value is double))
                return null;
            double maxR = (double)value;
            if (maxR < 0)
            {
                return Visibility.Collapsed;
            }
            else
            {
                return Visibility.Visible;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class Id2VisConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (!(value is long))
                return null;
            long id = (long)value;
            if (id < 0)
            {
                return Visibility.Collapsed;
            }
            else
            {
                return Visibility.Visible;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

}
