using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Net;

namespace FLY.Simulation.Coating
{
    public class HMI : INotifyPropertyChanged
    {
        const UInt16 ADDR_D_PumpSet=0;//泵速设置 & 泵速显示, float
  
        const UInt16 ADDR_D_LeftSet=10;//uint16  65535-> 6553.5
        const UInt16 ADDR_D_Left=12;

        const UInt16 ADDR_D_RightSet=14;//uint16  65535-> 6553.5
        const UInt16 ADDR_D_Right=16;


        const UInt16 ADDR_D_FilmVelocity=6;//float
        const UInt16 ADDR_C_STATE = 0;//涂布状态 bit 0


        CoatingCtrl mCoatingCtrl;

        FLY.ModbusModule.ServerTCP mbServer;
        FLY.ModbusModule.PLCRegister mPLCRegister;

        Dictionary<UInt16, string> Addrs = new Dictionary<ushort, string>();


        public double PumpSet 
        {
            get {
                float p = mPLCRegister.GetFloat(ADDR_D_PumpSet);
                return p;
            }
            set {
                if (PumpSet != value)
                {
                    mPLCRegister.SetFloat(ADDR_D_PumpSet, (float)value);
                    NotifyPropertyChanged("PumpSet");
                }
            }
        }
        public double LeftSet
        {
            get
            {
                UInt16 p = mPLCRegister.GetUInt16(ADDR_D_LeftSet);
                return p / 10.0;
            }
            set
            {
                if (LeftSet != value)
                {
                    mPLCRegister.SetUInt16(ADDR_D_LeftSet, (UInt16)(value * 10));
                    NotifyPropertyChanged("LeftSet");
                }
            }
        }
        public double Left
        {
            get
            {
                UInt16 p = mPLCRegister.GetUInt16(ADDR_D_Left);
                return p / 10.0;
            }
            set
            {
                if (Left != value)
                {
                    mPLCRegister.SetUInt16(ADDR_D_Left, (UInt16)(value * 10));
                    NotifyPropertyChanged("Left");
                }
            }
        }
        public double RightSet
        {
            get
            {
                UInt16 p = mPLCRegister.GetUInt16(ADDR_D_RightSet);
                return p / 10.0;
            }
            set
            {
                if (RightSet != value)
                {
                    mPLCRegister.SetUInt16(ADDR_D_RightSet, (UInt16)(value * 10));
                    NotifyPropertyChanged("RightSet");
                }
            }
        }
        public double Right
        {
            get
            {
                UInt16 p = mPLCRegister.GetUInt16(ADDR_D_Right);
                return p / 10.0;
            }
            set
            {
                if (Right != value)
                {
                    mPLCRegister.SetUInt16(ADDR_D_Right, (UInt16)(value * 10));
                    NotifyPropertyChanged("Right");
                }
            }
        }

        public double FilmVelocity
        {
            get
            {
                float p = mPLCRegister.GetFloat(ADDR_D_FilmVelocity);
                return p;
            }
            set
            {
                if (FilmVelocity != value)
                {
                    mPLCRegister.SetFloat(ADDR_D_FilmVelocity, (float)value );
                    NotifyPropertyChanged("FilmVelocity");
                }
            }
        }


        public bool State
        {
            get
            {
                return mPLCRegister.GetBool(ADDR_C_STATE);
            }
            set
            {
                if (State != value)
                {
                    mPLCRegister.SetBool(ADDR_C_STATE, value);
                    NotifyPropertyChanged("State");
                }
            }
        }

        public HMI(Coating coating, CoatingCtrl cc, int port)
        {
            mCoatingCtrl = cc;
           
            mPLCRegister = new ModbusModule.PLCRegister(200, 200);
            mbServer = new FLY.ModbusModule.ServerTCP(mPLCRegister, (UInt16)port);

            mPLCRegister.RegChanged += new ModbusModule.PLCRegister.RegChangedEventHandler(plcregister_RegChanged);

            Addrs.Add(ADDR_D_PumpSet, "PumpSet");
            Addrs.Add(ADDR_D_LeftSet, "LeftSet");
            Addrs.Add(ADDR_D_Left, "Left");
            Addrs.Add(ADDR_D_RightSet, "RightSet");
            Addrs.Add(ADDR_D_Right, "Right");
            Addrs.Add(ADDR_D_FilmVelocity, "FilmVelocity");

            Misc.BindingOperations.SetBinding(cc.NowCtrl, "Pump", this, "PumpSet", Misc.BindingOperations.BindingMode.TwoWay);
            Misc.BindingOperations.SetBinding(cc.NowCtrl, "LeftDis", this, "Left");
            Misc.BindingOperations.SetBinding(cc.NowCtrl, "RightDis", this, "Right");
            Misc.BindingOperations.SetBinding(coating, "FilmVelocity", this, "FilmVelocity");
            Misc.BindingOperations.SetBinding(coating, "DeviceState", this, "State");


            LeftSet = Left;
            RightSet = Right;
            this.PropertyChanged += new PropertyChangedEventHandler(HMI_PropertyChanged);
        }

        void HMI_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if ((e.PropertyName == "PumpSet") || (e.PropertyName == "LeftSet") || (e.PropertyName == "RightSet"))
            {
                mCoatingCtrl.SetCoatingCtrl(PumpSet, LeftSet, RightSet);
            }
        }

        void plcregister_RegChanged(object sender, ModbusModule.PLCRegister.RegChangedEventArgs e)
        {
            if (e.RegType == ModbusModule.PLCRegister.RegChangedEventArgs.REG_TYPE.REG)
            {
                foreach (UInt16 key in Addrs.Keys)
                {
                    if (e.IsCover(key))
                    {
                        NotifyPropertyChanged(Addrs[key]);
                    }
                }
            }
            else 
            {
                if (e.IsCover(ADDR_C_STATE)) 
                {
                    NotifyPropertyChanged("State");
                }
            }
        }

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