using CommunityToolkit.Mvvm.Input;
using FLY.OBJComponents.IService;
using FLY.Thick.Base.Common;
using FLY.Thick.Base.IService;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Threading;
using Unity;

namespace FLY.Thick.Base.UI
{
    /// <summary>
    /// UcMicroGage.xaml 的交互逻辑
    /// </summary>
    public partial class CtMicroGage : UserControl
    {
        CtMicroGageVm viewModel;
        /// <summary>
        /// 
        /// </summary>
        public CtMicroGage()
        {
            InitializeComponent();

            viewModel = new CtMicroGageVm();
            this.DataContext = viewModel;

            if (System.ComponentModel.LicenseManager.UsageMode != System.ComponentModel.LicenseUsageMode.Runtime)
                return;

            this.Loaded += Page_Loaded;
            this.Unloaded += Page_Unloaded;



        }
        private void Page_Unloaded(object sender, RoutedEventArgs e)
        {
            viewModel.DisposeBinding();
        }

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            viewModel.SetBinding();
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="container">容器</param>
        [InjectionMethod]
        public void Init(IUnityContainer container)
        {
            
            container.BuildUp(viewModel);
            
        }
    }


    class CtMicroGageVm : INotifyPropertyChanged
    {
        #region 延时推送 MARKNO
        const int MARKNO_UPDATEERROR = 1;
        #endregion

        public event PropertyChangedEventHandler PropertyChanged;


        public double Thick { get; set; }
        public int AD { get; set; }
        public int ADMax { get; set; }
        public bool IsIOShowNo { get; set; }
        public int Position { get; set; }
        public int PosLength { get; set; }

        public double PosMm { get; set; }
        public double Velocity { get; set; }
        public double FilmVelocity { get; set; }
        public string ControllerState { get; set; }

        public UInt16 OStatus { get; set; }
        public UInt16 IStatus { get; set; }

        public bool IsError { get; set; }
        /// <summary>
        /// 异常消息
        /// </summary>
        public string ErrMsg { get; set; }

        public RelayCommand StopCmd { get; private set; }

        public RelayCommand ForwCmd { get; private set; }

        public RelayCommand BackwCmd { get; private set; }

        public RelayCommand OrgCmd { get; private set; }


        DynArea dynArea;
        ITDGageService gageService;
        IInitParamService initParam;
        IWarningSystem2Service warningSystem;
        DispatcherTimer timer_error;
        private int reason_list_index = -1;

        Dictionary<object, List<Misc.BindingOperations.PropertyChangedEventContexts>> bindingConexts = new Dictionary<object, List<Misc.BindingOperations.PropertyChangedEventContexts>>();

        /// <summary>
        /// 数据已经绑定了
        /// </summary>
        bool isBinding;

        public CtMicroGageVm()
        {
            StopCmd = new RelayCommand(() =>
            {
                gageService.StartP2(STARTP2_MODE.STOP);
            });
            OrgCmd = new RelayCommand(() =>
            {
                gageService.StartP2(STARTP2_MODE.ORG);
            });
            ForwCmd = new RelayCommand(() =>
            {
                gageService.StartP2(STARTP2_MODE.FORW);
            });
            BackwCmd = new RelayCommand(() =>
            {
                gageService.StartP2(STARTP2_MODE.BACKW);
            });
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="initParam"></param>
        /// <param name="gageService"></param>
        /// <param name="warningSystem"></param>
        [InjectionMethod]
        public void Init(
            IInitParamService initParam,
            ITDGageService gageService,
            IWarningSystem2Service warningSystem)
        {

            this.gageService = gageService;
            dynArea = gageService.DynArea;
            this.initParam = initParam;
            this.warningSystem = warningSystem;

            timer_error = new DispatcherTimer();
            timer_error.Interval = TimeSpan.FromSeconds(3);

            //参数绑定
            SetBinding();

        }

        /// <summary>
        /// 参数绑定
        /// </summary>
        public void SetBinding()
        {
            if (isBinding)//已经绑定了
                return;
            isBinding = true;
            //下面全部event保存在bindingConexts
            Misc.BindingOperations.StartMarkdownEvents(bindingConexts);

            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.Thk), this, nameof(Thick));
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.AD), this, nameof(AD));
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.ADMax), this, nameof(ADMax));
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.Position), this, nameof(Position));
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.PosMm), this, nameof(PosMm));
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.Velocity), this, nameof(Velocity));
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.FilmVelocity), this, nameof(FilmVelocity));
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.ControllerState), this, () =>
            {
                FLY.Thick.Base.UI.Converter.ControllerStateConverter converter = new FLY.Thick.Base.UI.Converter.ControllerStateConverter();
                ControllerState = (string)converter.Convert(dynArea.ControllerState, typeof(string), null, null);
            });

            Misc.BindingOperations.SetBinding(this.initParam, nameof(initParam.PosLength), this, nameof(PosLength));
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.IsIOShowNo), this, nameof(IsIOShowNo));
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.OStatus), this, nameof(OStatus));
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.IStatus), this, nameof(IStatus));

            Misc.BindingOperations.SetBinding(gageService, nameof(FObjBase.FObjServiceClient.IsConnected), this, UpdateError);

            //备份event完毕, 必须关闭记录
            Misc.BindingOperations.StopMarkdownEvents();

            //报警原因轮流显示
            timer_error.Tick += Timer_error_Tick;
            warningSystem.PropertyChanged += WarningSystem_PropertyChanged;
        }
        /// <summary>
        /// 解除绑定
        /// </summary>
        public void DisposeBinding()
        {
            if (!isBinding)//已经解除绑定了
                return;
            isBinding = false;
            Misc.BindingOperations.DisposeEventTargetObject(bindingConexts);

            warningSystem.PropertyChanged -= WarningSystem_PropertyChanged;
            timer_error.Stop();
            timer_error.Tick -= Timer_error_Tick;
            
        }
        private void Timer_error_Tick(object sender, EventArgs e)
        {
            reason_list_index--;
            if (reason_list_index < 0)
            {
                if (warningSystem.ReasonList != null && warningSystem.ReasonList.Count() > 0)
                    reason_list_index = warningSystem.ReasonList.Count() - 1;
                else
                    reason_list_index = -1;
            }
            UpdateError();
        }


        private void WarningSystem_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(warningSystem.ReasonList))
            {
                if (warningSystem.ReasonList != null && warningSystem.ReasonList.Count() > 0)
                    reason_list_index = warningSystem.ReasonList.Count() - 1;
                else
                    reason_list_index = -1;

                UpdateError();
            }
        }

        void UpdateError()
        {
            if (this.gageService is FObjBase.FObjServiceClient)
            {
                var client = this.gageService as FObjBase.FObjServiceClient;
                string errMsg = (string)Application.Current.TryFindResource("str.CtMicroGage.ServerDisconnected");
                if (errMsg == null) {
                    errMsg = "服务器连接断开";
                }

                if (!client.IsConnected)
                {
                    ErrMsg = errMsg;
                    IsError = true;
                    reason_list_index = -1;
                    timer_error.Stop();
                    return;
                }
            }

            if (warningSystem.ReasonList != null && warningSystem.ReasonList.Count() > 0)
            {
                if (reason_list_index >= warningSystem.ReasonList.Count())
                    reason_list_index = warningSystem.ReasonList.Count() - 1;
                else if (reason_list_index < 0)
                    reason_list_index = 0;


                ErrMsg = warningSystem.ReasonList[reason_list_index].Description;
                IsError = true;
                timer_error.Start();
            }
            else
            {
                IsError = false;
                ErrMsg = "";
                reason_list_index = -1;
                timer_error.Stop();
            }
        }
    }

    class CtMircoGageVmUt : CtMicroGageVm
    {

    }

    /// <summary>
    /// 
    /// </summary>
    public class IO2BitColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            //ResourceDictionary resourceDictionary = new ResourceDictionary() { Source = new Uri("pack://application:,,,/FLY.Thick.Base.UI;component/CtMicroGage/CtMicroGageStyle.xaml") };
            //var onColor = resourceDictionary["Brushes.IO.ON"] as SolidColorBrush;
            //var offColor = resourceDictionary["Brushes.IO.OFF"] as SolidColorBrush;
            //if (onColor == null || offColor == null)
            //{
            //    onColor = new SolidColorBrush(Colors.WhiteSmoke);
            //    offColor = new SolidColorBrush(Colors.Black);
            //}
            var onColor = new SolidColorBrush(Colors.WhiteSmoke);
            var offColor = new SolidColorBrush(Color.FromArgb(0xFF, 0x3B, 0x3B, 0x3B));


            try
            {
                UInt16 io = (UInt16)value;
                string str = (string)parameter;
                int bitno = int.Parse(str);
                if (Misc.MyBase.CHECKBIT(io, bitno))
                    return offColor;
                else
                    return onColor;
            }
            catch
            {
                return offColor;
            }

        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public class IONumberConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool isIOShowNo = true;
            int idx = 0;
            if (value is bool)
            {
                isIOShowNo = (bool)value;
            }
            if (!(parameter is string))
            {
                return null;
            }
            if (!int.TryParse((string)parameter, out idx))
            {
                return null;
            }
            if (isIOShowNo)
            {
                return (idx + 1).ToString();
            }
            else
            {
                return (idx).ToString();
            }
        }

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