using FLY.Thick.Base.Common;
using FLY.Thick.Base.IService;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
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.Shapes;
using Unity;

namespace FLY.Thick.Base.UI
{
    /// <summary>
    /// WdIOTip.xaml 的交互逻辑
    /// </summary>
    public partial class WdIOTip : FLY.ControlLibrary.WindowBigClose   
    {
        WdIoTipVm viewModel;

        public WdIOTip()
        {
            InitializeComponent();

            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();
        }


        [InjectionMethod]
        public void Init(IFlyAdIoDefineService iODefineService, ITDGageService gageService, IFlyADService flyADService) {

            viewModel = new WdIoTipVm();
            viewModel.Init(iODefineService, gageService.DynArea, flyADService);
            this.DataContext = viewModel;
        }

    }

    public class WdIoTipVm : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        IFlyAdIoDefineService iODefineService;

        DynArea dynArea;
        IFlyADService flyAdService;
        public ObservableCollection<FlyAdIoStatus> IStatus { get; } = new ObservableCollection<FlyAdIoStatus>();
        public ObservableCollection<FlyAdIoStatus> OStatus { get; } = new ObservableCollection<FlyAdIoStatus>();


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

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

        public WdIoTipVm() { 
        
        }

        public void Init(IFlyAdIoDefineService iODefineService, DynArea dynArea, IFlyADService flyADService)
        {
            this.dynArea = dynArea;
            this.iODefineService = iODefineService;
            this.flyAdService = flyADService;
            //参数绑定
            SetBinding();

        }

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


            Misc.BindingOperations.SetBinding(flyAdService, new string[] { nameof(flyAdService.HardwareVersion), nameof(flyAdService.HardwareVersionMinor) }, this, update);
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.IStatus), this, updateIsOn_In);
            Misc.BindingOperations.SetBinding(dynArea, nameof(dynArea.OStatus), this, updateIsOn_Out);

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

            if (this.iODefineService is FObjBase.FObjServiceClient)
            {
                var client = this.iODefineService as FObjBase.FObjServiceClient;
                client.PropertyChanged += Client_PropertyChanged;
            }
        }
        /// <summary>
        /// 解除绑定
        /// </summary>
        public void DisposeBinding()
        {
            if (!isBinding)//已经解除绑定了
                return;
            isBinding = false;
            Misc.BindingOperations.DisposeEventTargetObject(bindingConexts);

            if (this.iODefineService is FObjBase.FObjServiceClient)
            {
                var client = this.iODefineService as FObjBase.FObjServiceClient;
                client.PropertyChanged -= Client_PropertyChanged;
            }

        }

        void updateIsOn_In() 
        {
            for (int i = 0; i < IStatus.Count(); i++)
            {
                IStatus[i].IsOn = !Misc.MyBase.CHECKBIT(dynArea.IStatus, i);
            }
        }
        void updateIsOn_Out()
        {
            for (int i = 0; i < OStatus.Count(); i++)
            {
                OStatus[i].IsOn = !Misc.MyBase.CHECKBIT(dynArea.OStatus, i);
            }
        }
        private void Client_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            var client = this.iODefineService as FObjBase.FObjServiceClient;
            if (e.PropertyName == nameof(FObjBase.FObjServiceClient.IsConnected))
            {
                if (client.IsConnected)
                {
                    update();
                }
            }
        }

        void update()
        {
            iODefineService.GetIODefine((asyncContext, retData) => {

                var response = retData as IODefineCollection;
                if (response == null) {
                    return;
                }
                var list = response.List;
                if (list == null || list.Count() == 0)
                    return;

                if (flyAdService.HardwareVersion == 3)
                {
                    update(IODefine.IOTYPE.Input, IStatus, (i)=>$"X{i}", 16, list);
                    update(IODefine.IOTYPE.Output, OStatus, (i) => $"Y{i}", 8, list);
                }
                else 
                {
                    if (flyAdService.HardwareVersionMinor == 1)
                    {
                        update(IODefine.IOTYPE.Input, IStatus, (i) => $"X{i}", 12, list);
                        update(IODefine.IOTYPE.Output, OStatus, (i) => $"Y{i}", 4, list);
                    }
                    else 
                    {
                        update(IODefine.IOTYPE.Input, IStatus, (i) => $"i{i+1}", 12, list);
                        update(IODefine.IOTYPE.Output, OStatus, (i) => $"o{i+1}", 4, list);
                    }
                }



                updateIsOn_In();
                updateIsOn_Out();
            }, this);
        }

        void update(
            IODefine.IOTYPE ioType,
            ObservableCollection<FlyAdIoStatus> ioStatus,
            Func<int,string> numberStr,
            int ioCnt,
            List<IODefine> list) 
        {
            ioStatus.Clear();
            for (int i = 0; i < ioCnt; i++) {
                ioStatus.Add(new FlyAdIoStatus()
                {
                    Number = numberStr(i)
                });
            }

            //获取中文
            string[] iostatus_desps = new string[ioCnt];

            for (int i = 0; i < list.Count(); i++)
            {
                var ioDefine = list[i];
                if (ioDefine.IoType == ioType)
                {
                    if (ioDefine.Index < iostatus_desps.Count())
                    {
                        //描述翻译
                        string resourceName = $"str.FlyADIODefine.{ioDefine.Description}";
                        string state_msg = (string)Application.Current.TryFindResource(resourceName);
                        if (state_msg == null)
                        {
                            state_msg = ioDefine.Description;
                        }

                        iostatus_desps[ioDefine.Index] = state_msg;
                    }
                }
            }

            //填入
            for (int i = 0; i < iostatus_desps.Count(); i++)
            {
                if (string.IsNullOrEmpty(iostatus_desps[i]))
                {
                    ioStatus[i].Desp = "";
                }
                else
                {
                    ioStatus[i].Desp = iostatus_desps[i];
                }
            }
        }
    }
    public class FlyAdIoStatus : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 编号
        /// </summary>
        public string Number { get; set; }

        /// <summary>
        /// 描述
        /// </summary>
        public string Desp { get; set; }

        /// <summary>
        /// 状态
        /// </summary>
        public bool IsOn { get; set; }

    }

    public class WdIoTipVmUt : WdIoTipVm
    {
        public WdIoTipVmUt()
        {

            for (int i = 0; i < 16; i++)
            {
                IStatus.Add(new FlyAdIoStatus()
                {
                    Number = $"X{i}"
                });
            };
            for (int i = 0; i < 8; i++)
            {
                OStatus.Add(new FlyAdIoStatus()
                {
                    Number = $"Y{i}"
                });
            };

            IStatus[2-1].IsOn = true;
            IStatus[4-1].IsOn = true;

            IStatus[11 - 1].IsOn = true;

            OStatus[4 - 1].IsOn = true;


            IStatus[2 - 1].Desp = "归零信号";
            IStatus[3 - 1].Desp = "正向限位";
            IStatus[4 - 1].Desp = "反向限位";
            IStatus[7 - 1].Desp = "急停|手动正转";
            IStatus[8 - 1].Desp = "急停|手动反转";

            OStatus[4 - 1].Desp = "报警信号";



        }
    }
}
