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

namespace FLY.Simulation.Blowing
{
    public class HMI:INotifyPropertyChanged
    {
        const int ADDR_M_HasElectricCurrent = 0;//bit 三相电 电流
        const int ADDR_M_HasFan = 1;//bit 风机启动
        
        const int ADDR_D_ChannelCnt = 0;
        const int ADDR_D_HeatUpdate = 1;
        const int ADDR_D_CurrUpdate = 2;
        
        const UInt16 ADDR_D_Heats = 100;
        const UInt16 ADDR_D_Currs = 300;

        public UInt16 HeatUpdate { get; set; }

        public UInt16 CurrUpdate { get; set; }


        /// <summary>
        /// 当前电流 有没？
        /// </summary>
        public bool HasElectricCurrent { get; set; }

        /// <summary>
        /// 风机是否启动？
        /// </summary>
        public bool HasFan { get; set; } = true;

        UInt16 heatupdate = 1;
        UInt16 currupdate = 1;
        UInt16 heatupdate_last = 1;
        UInt16[] heats;
        bool[] Bads;
        public Blowing.AirRing mAirRing;
        FLY.ModbusModule.ClientTCP mbclient;



        public HMI() 
        {
            mbclient = new FLY.ModbusModule.ClientTCP(IPAddress.Parse("127.0.0.1"));

            heats = new UInt16[100];
            Bads = new bool[100];
            Array.Clear(heats, 0, 100);
            Array.Clear(Bads, 0, 100);

            Bads[2] = true;
            Bads[30] = true;
            heatupdate = 1;
            heatupdate_last = 1;
            currupdate = 1;

            mbclient.PropertyChanged += new PropertyChangedEventHandler(mbclient_PropertyChanged);

            //每1秒读取一次
            FObjBase.PollModule.Current.Poll_Config(FObjBase.PollModule.POLL_CONFIG.ADD, 
                new FObjBase.PollModule.PollHandler(OnPoll),TimeSpan.FromMilliseconds(200) );
        }

        void mbclient_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsConnected") 
            {
                if (mbclient.IsConnected)
                {
                    step = 0;
                }
                else 
                {
                    step = -1;
                }

            }
        }
        int step = -1;
        void OnPoll() 
        {
            switch (step)
            {
                case 0:
                    mbclient.Do_03(ADDR_D_HeatUpdate, 1, delegate(UInt16[] datas, object AsyncState)
                    {
                        HeatUpdate = datas[0];
                        step = 2;
                    }, null);
                    step = 1;
                    break;
                case 2:
                    mbclient.Do_03(ADDR_D_Heats, 100, delegate(UInt16[] datas, object AsyncState)
                    {
                        Array.Copy(datas, heats, 100);                        
                        step = 4;
                    }, null);
                    step = 3;
                    break;
                case 4:
                    OnPoll_send();
                    step = 0;
                    break;
            }
        }
        
        void SendHeats() 
        {
            mbclient.Do_10(ADDR_D_Currs,heats); 
        }
        void SendUpdate() 
        {
            mbclient.Do_10(ADDR_D_CurrUpdate, new ushort[]{ CurrUpdate});
        }
        void SendStatue() 
        {
            mbclient.Do_0F(ADDR_M_HasElectricCurrent, new bool[] { HasElectricCurrent, HasFan });
        }
        void OnPoll_send() 
        {
            if (heatupdate_last != HeatUpdate) 
            {
                heatupdate_last = HeatUpdate;

                for (int i = 0; i < mAirRing.ChannelCnt; i++) 
                {
                    mAirRing.Heats[i] = heats[i];
                }
                mAirRing.HeatApply();
                SendHeats();

                bool current = false;
                for (int i = 0; i < mAirRing.ChannelCnt; i++)
                {
                    if ( (Bads[i]==false) &&  (mAirRing.Heats[i]>0))
                    {
                        current = true;
                        break;
                    }
                }
                HasElectricCurrent = current;
                CurrUpdate++;
                SendUpdate();

            }
            SendStatue();
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
