using IOB_UT_NEXT;
using IOB_UT_NEXT.Config;
using System;
using System.Collections.Generic;

namespace IOB_WIN_BECKHOFF.IobBeckhoff
{
    public class Beckhoff : Iob.GenericNext
    {
        #region Public Fields

        public List<string> dataVal = new List<string>();

        #endregion Public Fields

        #region Public Constructors

        /// <summary>
        /// Estende l'init della classe base
        /// </summary>
        /// <param name="caller">Form chiamante</param>
        /// <param name="IobConfFull">Configurazione (v 4.x)</param>
        public Beckhoff(AdapterFormNext caller, IobConfTree IobConfFull) : base(caller, IobConfFull)
        {
            lgInfo("NEW IobBeckhoff Adapter");
            // gestione invio ritardato contapezzi
            
            // init datetime counters
            DateTime adesso = DateTime.Now;
            lastPzCountSend = adesso;
            lastWarnODL = adesso;
            vetoCheckStatus = adesso;

            // ora leggo il file di conf specifico....
            loadMemConf();
        }

        #endregion Public Constructors

        #region Public Methods

        /// <summary>
        /// Recupero dati dinamici...
        /// </summary>
        public override Dictionary<string, string> getDynData()
        {
            // valore non presente in vers default... se gestito fare override
            Dictionary<string, string> outVal = new Dictionary<string, string>();
            if (utils.CRB("enableTSVC"))
            {
                try
                {
                    // processo x ogni valore configurato...
                    if (memMap.mMapRead.Count > 0)
                    {
                        // inizializzo i valori
                        string valString = "";
                        // procedo x ogni valore configurato......
                        foreach (var item in memMap.mMapRead)
                        {
                            // leggo
                            valString = AdsCli.ReadVariabile(item.Value.memAddr).ToString();
                            outVal.Add(item.Value.name, valString);
                        }
                    }
                    else
                    {
                        lgInfo($"getDynData: {memMap.mMapRead.Count} record in mMapRead");
                    }
                }
                catch (Exception exc)
                {
                    lgError(exc, "Errore in getDynData x BeckHoff PLC");
                }
            }
            else
            {
                lgInfo($"Non processo getDynData: enableTSVC = false");
            }
            if (periodicLog || outVal.Count > 0)
            {
                lgInfo($"Esito getDynData: {outVal.Count} valori VALIDI in outVal");
            }
            return outVal;
        }

        /// <summary>
        /// Leggo le variabili correnti (status, contapezzi)
        /// </summary>
        public virtual void readCurrVal()
        {
        }

        public virtual void setEventHandler()
        {
            if (AdsCli != null)
            {
                AdsCli.ValueChanged += AdsCli_ValueChanged;
            }
        }

        /// <summary>
        /// Override connessione
        /// </summary>
        public override void tryConnect()
        {
            if (!connectionOk)
            {
                int port = 851;
                int.TryParse(IOBConfFull.Device.Connect.Port, out port);
                string addr = !string.IsNullOrEmpty(IOBConfFull.Device.Connect.IpAddr) ? IOBConfFull.Device.Connect.IpAddr : "local";
                lgInfo($"Parametri TC client | addr: {addr} | port: {port}");
                // predispongo dataVal
                foreach (var item in memMap.mMapRead)
                {
                    dataVal.Add(item.Value.memAddr);
                }

                // vera connessione!
                AdsCli = new TcAdsClient(dataVal, addr, port);

                connectionOk = AdsCli.Connected;
                if (connectionOk)
                {
                    setEventHandler();
                    readCurrVal();
                    queueInEnabCurr = true;
                }
                lgInfo($"Connected: {connectionOk}");
            }
        }

        /// <summary>
        /// Override disconnessione
        /// </summary>
        public override void tryDisconnect()
        {
            lgInfo("Richiesta disconnessione adapter");
            if (AdsCli != null)
            {
                AdsCli.dispose();
            }
            connectionOk = false;
            queueInEnabCurr = false;
        }

        #endregion Public Methods

        #region Protected Fields

        protected TcAdsClient AdsCli;

        /// <summary>
        /// Veto controllo status x log...
        /// </summary>
        protected DateTime vetoCheckStatus = DateTime.Now;

        #endregion Protected Fields

        #region Protected Methods

        protected void AdsCli_ValueChanged(TcAdsClient sender, string key, string value)
        {
            lgInfo($"Monitored Value changed | sender: {sender} | key: {key} | value: {value}");
        }

        #endregion Protected Methods
    }
}