using EasyModbus;
using IOB_UT_NEXT;
using IOB_UT_NEXT.Config;
using System;
using System.Linq;

namespace IOB_WIN_MBUS.IobModbusTCP
{
    /* --------------------------------------------------------------------------------
    * Controlli ModBusTCP Helpi
    * - protocollo ModBus TCP
    * - specifico comportamento impianti confezionatrici Helpi
    *
    * NRicetta          UINT        16bit 41060 W
    * ApplicaRicetta    UINT        16bit 41061 R/W
    * IDOrdine          STRING [30] 41062 W
    * Lotto             STRING [30] 41078 W
    * CodiceAllarmi_1   DWORD 32bit 41094 R
    * CodiceAllarmi_2   DWORD 32bit 41096 R
    * NPacchi           UDINT 32bit 41098 W
    * NPacchiFatti      UDINT 32bit 41100 R
    * EpochStart        UDINT 32bit 41102 R
    * EpochStop         UDINT 32bit 41104 R
    * PPM               REAL 32bit  41106 R
    * StatusLavoro      UINT 16bit  41108 R
    *
    * StatusLavoro indica lo stato della macchina:
    * 0. macchina completamente ferma
    * 1. macchina in riscaldamento
    * 2. macchina pronta
    * 3. macchina in manuale
    * 4. macchina in ciclo
    *
    * G:\Drive condivisi\30_Clienti\Cereria Finassi\PLC Helpi
    *
    * -------------------------------------------------------------------------------- */

    public class ModbusTCPHelpi : ModbusTCP
    {
        #region Public Constructors

        /// <summary>
        /// Classe base con i metodi x ModBusTCP
        /// </summary>
        /// <param name="caller">Form chiamante</param>
        /// <param name="IOBConf">Configurazione (legacy)</param>
        /// <param name="IobConfFull">Configurazione (v 4.x)</param>
        public ModbusTCPHelpi(AdapterFormNext caller, IobConfTree IobConfFull) : base(caller, IobConfFull)
        {
            lgInfo("NEW IOB ModBus TCP Helpi");

            // provo lettura una prima volta i dati DYN
            if (currPLC != null && currPLC.Connected)
            {
                try
                {
                    processDynData();
                }
                catch (Exception exc)
                {
                    lgError($"Eccezione in processDynData iniziale x ModBus TCP Helpi:{Environment.NewLine}{exc}");
                }
            }

            //// test lettura
            //testCncConn();
            //testBlockRead(401001, 20);
        }

        #endregion Public Constructors

        #region Protected Properties

        /// <summary>
        /// Restituisce status di emergenza, hard coded dall'area di allarmi
        /// </summary>
        protected bool EStop
        {
            get
            {
                bool answ = false;
                int currStatus = 0;
                // hard coded
                int statusReg = 41094;
                // deve avere allarmi (è un allarme EStop)
                if (hasAlarms())
                {
                    int[] listInt = new int[2];
                    listInt = HoldingRegisterLUT[statusReg];
                    currStatus = ModbusClient.ConvertRegistersToInt(listInt);
                    // hard coded il 5° bit
                    answ = ((currStatus & (1 << 4)) > 0);
                }
                return answ;
            }
        }

        /// <summary>
        /// Restituisce status di lavorazione, hard coded dall'area di memoria 41108
        /// </summary>
        protected int StatusLavoro
        {
            get
            {
                int answ = 0;
                // hard coded
                int statusReg = 41108;
                if (HoldingRegisterLUT.ContainsKey(statusReg))
                {
                    int[] listInt = new int[2];
                    listInt = HoldingRegisterLUT[statusReg];
                    var dataList = listInt.ToList();
                    dataList.Reverse();
                    listInt = dataList.ToArray();
                    answ = ModbusClient.ConvertRegistersToInt(listInt);
                }
                return answ;
            }
        }

        #endregion Protected Properties

        #region Protected Methods

        /// <summary>
        /// Effettua decodifica aree memoria alla bitmap usata x MAPO
        /// </summary>
        protected override void decodeToBaseBitmap()
        {
            // init a zero...
            B_input = 0;

            /* -----------------------------------------------------
             * bitmap MAPO STANDARD, tipo 60 con warm up /cool down
             * B0: POWER_ON
             * B1: RUN
             * B2: pzCount
             * B3: allarme
             * B4: manuale
             * B5: TC Lento
             * B6: WarmUp/CoolDown
             * B7: Emergenza armata
             *
             ----------------------------------------------------- */

            var MemInt = new byte[2];

            int byteSignals = 0;
            // bit 0 (poweron) imposto a 1 SE connected...
            if (currPLC.Connected)
            {
                byteSignals += (1 << 0);
            }

            // processo dagli stati + gravi...
            if (!EStop)
            {
                byteSignals += (1 << 7);
            }
            if (hasAlarms())
            {
                byteSignals += (1 << 3);
            }

            // verifico gli stati specifici x decodificare... 41108
            switch (StatusLavoro)
            {
                // resta FERMA (pronta)
                case 0:
                default:
                    break;

                case 1:
                    byteSignals += (1 << 6);
                    break;

                // spostato 2 in lavora
                //case 2:
                case 3:
                    byteSignals += (1 << 4);
                    break;

                case 2:
                case 4:
                    byteSignals += (1 << 1);
                    break;
            }

            // salvo!
            B_input = byteSignals;
        }

        #endregion Protected Methods
    }
}