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 System.ComponentModel;
using System.Net;
using FLY.ModbusMapper;
using System.Reflection;

namespace WpfApplication_ModbusMapper_Client
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        ClientTCP clienttcp;
        ModbusMapper_Client mapper;
        ABC abc;
        public MainWindow()
        {
            InitializeComponent();
            Init();
        }
        void Init() 
        {
            abc = new ABC();
            clienttcp = new FLY.ModbusMapper.ClientTCP(new IPEndPoint(IPAddress.Parse("192.168.1.21"), 502));
            mapper = new FLY.ModbusMapper.ModbusMapper_Client(clienttcp);
            
            
            //建立关系表
            mapper.MapDataToRegs(PLCAddressArea.Register, 0, REG_TYPE.FLOAT, 1, 
                abc, "A");

            mapper.MapDataToRegs(PLCAddressArea.Register, 0, REG_TYPE.BOOL, 1,
                abc, "B");

            mapper.MapDataToRegs(PLCAddressArea.Register, 2, REG_TYPE.UINT16, 1,
                abc, "C");

            

            abc.PropertyChanged += new PropertyChangedEventHandler(abc_PropertyChanged);

            mapper.NameDataChanged += new NameDataChangedEventHandler(mapper_NameDataChanged);

            this.DataContext = abc;
            this.textblock_connect.DataContext = clienttcp;

            FObjBase.PollModule.Current.Start();

            mapper.PlanAdd(this, mapper.FindDataMap(abc, "A"));
            mapper.PlanAdd(this, mapper.FindDataMap(abc, "B"));
            mapper.PlanAdd(this, mapper.FindDataMap(abc, "C"));
            mapper.PlanMake();

        }

        void mapper_NameDataChanged(object sender, NameDataChangedEventArgs e)
        {
            if (e.Owener != abc)
                return;

            //这是从HMI 更新过来的，不需要向HMI写入
            abc.PropertyChanged -= abc_PropertyChanged;

            Type t = abc.GetType();
            PropertyInfo pt = t.GetProperty(e.PropertyName);
            pt.SetValue(abc, mapper.GetNameData(abc, e.PropertyName),null);
            abc.PropertyChanged += abc_PropertyChanged;
        }

        void abc_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            Type t = sender.GetType();
            PropertyInfo pt = t.GetProperty(e.PropertyName);
            object val = pt.GetValue(sender, null);
            mapper.SetNameData(sender, e.PropertyName, val);
        }

    }
    public class ABC:INotifyPropertyChanged
    {
        private float a;
        public float A 
        {
            get {
                return a;
            }
            set {
                if (a != value)
                {
                    a = value;
                    NotifyPropertyChanged("A");
                }
            }
        }

        private bool b;
        public bool B
        {
            get
            {
                return b;
            }
            set
            {
                if (b != value)
                {
                    b = value;
                    NotifyPropertyChanged("B");
                }
            }
        }

        private UInt16 c;
        public UInt16 C
        {
            get
            {
                return c;
            }
            set
            {
                if (c != value)
                {
                    c = value;
                    NotifyPropertyChanged("C");
                }
            }
        }

        protected void NotifyPropertyChanged(string propertyname) 
        {
            if (PropertyChanged != null) {
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyname));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
}
