using PlcCom;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using PlcUiForm;
namespace PlcComponent
{
    public partial class PlcMessageBox : Component, ISingleOutputComponent
    {
        public PlcMessageBox()
        {
            InitializeComponent();
        }
        public PlcMessageBox(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }

        [Category("PLC")]
        [Description("PLC读地址，必须为Bool类型")]
        [Editor(typeof(NodeTypeEditor), typeof(UITypeEditor))]
        public Node ReadNode { get; set; }

        [Category("PLC")]
        [Description("PLC写地址，当窗体关闭时写入的数据，必须为Bool类型")]
        [Editor(typeof(NodeTypeEditor), typeof(UITypeEditor))]
        public Node WriteNode { get; set; }


        [Category("PLC")]
        [Description("当窗体关闭时写入的值")]
        [DefaultValue(false)]
        public bool WriteValue { get; set; } = false;


        [Category("PLC")]
        [Description("窗体名称")]
        public string FormCaption { get; set; }

        [Category("PLC")]
        [Description("消息字符串")]
        public string Message { get; set; }

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public IPlcComProtocol Protocol { get; set; }

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public object State
        {
            get => state;
            set
            {
                if (!object.Equals(state, value))
                {
                    state = value;
                    OnPLCRegisterValueChanged?.Invoke(this, ReadNode, state);
                }
                if (value is bool b)
                {
                    if (b)
                    {
                        if (messageBoxForm == null || messageBoxForm.IsDisposed)
                            ShowForm();
                    }
                    else
                    {
                        if (messageBoxForm != null && !messageBoxForm.IsDisposed)
                            messageBoxForm.Close();
                    }
                }
            }
        }
        public bool SupportMultiNodes { get; } = false;

        private object state;

        PlcBaseForm messageBoxForm;
        void ShowForm()
        {
            messageBoxForm = new PlcBaseForm();
            Label label = new Label();
            label.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            label.Dock = DockStyle.Fill;
            label.Text = Message;
            label.Font = new System.Drawing.Font("宋体", 20);
            messageBoxForm.Controls.Add(label);
            messageBoxForm.FormClosing += MessageBoxForm_FormClosing;

            messageBoxForm.TopMost = true;
            messageBoxForm.Text = FormCaption;
            messageBoxForm.Width = 400;
            messageBoxForm.Height = 200;
            messageBoxForm.MaximizeBox = false;
            messageBoxForm.MinimizeBox = false;
            messageBoxForm.Show();
        }

        private void MessageBoxForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (WriteNode != null)
            {
                uint result = 0;
                var rt = Protocol.WriteValue(WriteNode.Value, WriteValue, ref result);
            }
        }

        public event RegisterValueChangedHandler OnPLCRegisterValueChanged;
        public event ReadRegisterFailedHandler OnReadRegisterFailed;
        public event UpdateComponentStateFailedHandler OnUpdateComponentStateFailed;

        public object Read()
        {
            if (Protocol != null && ReadNode != null)
            {
                object result;
                var rt = Protocol.ReadValue(ReadNode.Value, out result);
                if (rt == 0)
                {
                    UpdateValue(result);
                    return result;
                }
                else
                {
                    OnReadRegisterFailed?.Invoke(this, ReadNode, rt);
                }
            }
            return null;
        }

        public void UpdateValue(object value)
        {
            if (value is bool)
                State = value;
            else
                OnUpdateComponentStateFailed?.Invoke(this, ReadNode, value, "读取到的值不是Bool类型");
        }

        public void UpdateValues(object value)
        {
            throw new NotImplementedException();
        }
    }

}