using DevExpress.XtraEditors;
using LFP_Manager.DataStructure;
using LFP_Manager.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace LFP_Manager.Controls
{
    public partial class UcFaultAlarmGroup : DevExpress.XtraEditors.XtraUserControl
    {
        #region CONSTANTS
        private const int FAULT_ALARM_COUNT = 14;

        private enum eAlarmComp
        {
            MODULE_OV = 0,
            CELL_OV = 1,
            MODULE_UV = 2,
            CELL_UV = 3,
            CHG_OC = 4,
            DCH_OC = 5,
            CHG_OT = 6,
            CHG_UT = 7,
            DCH_OT = 8,
            DCH_UT = 9,
            LOW_SOC = 10,
            MOS_OT = 11,
            SC = 12,
            CB_OFF = 13,
        }
        #endregion

        #region VARIABLES
        private CommConfig Config;

        private UcFaultAlarm[] FaultAlarm;
        #endregion

        #region CONSTRUCTORS
        public UcFaultAlarmGroup()
        {
            InitializeComponent();

            CreateAlarmComponent();
        }
        #endregion

        #region COMPONENTS

        private void CreateAlarmComponent()
        {
            FaultAlarm = new UcFaultAlarm[FAULT_ALARM_COUNT];

            void Bind(eAlarmComp comp, UcFaultAlarm control, int displayNo, string title)
            {
                FaultAlarm[(int)comp] = control;
                FaultAlarm[(int)comp].SetFaultName(displayNo, title);
            }

            Bind(eAlarmComp.MODULE_OV , ucFaultAlarm1 ,  1, "Module OV");
            Bind(eAlarmComp.CELL_OV   , ucFaultAlarm3 ,  3, "Cell OV");
            Bind(eAlarmComp.MODULE_UV , ucFaultAlarm2 ,  2, "Module UV");
            Bind(eAlarmComp.CELL_UV   , ucFaultAlarm4 ,  4, "Cell UV");
            Bind(eAlarmComp.CHG_OC    , ucFaultAlarm5 ,  5, "Chg OC");
            Bind(eAlarmComp.DCH_OC    , ucFaultAlarm6 ,  6, "Dch OC");
            Bind(eAlarmComp.CHG_OT    , ucFaultAlarm7 ,  7, "Chg OT");
            Bind(eAlarmComp.CHG_UT    , ucFaultAlarm8 ,  8, "Chg UT");
            Bind(eAlarmComp.DCH_OT    , ucFaultAlarm9 ,  9, "Dch OT");
            Bind(eAlarmComp.DCH_UT    , ucFaultAlarm10, 10, "Dch UT");
            Bind(eAlarmComp.LOW_SOC   , ucFaultAlarm11, 11, "Low SOC");
            Bind(eAlarmComp.MOS_OT    , ucFaultAlarm12, 12, "Mos OT");
            Bind(eAlarmComp.SC        , ucFaultAlarm13, 13, "S-C");
            Bind(eAlarmComp.CB_OFF    , ucFaultAlarm14, 14, "CB Off");
        }        
        #endregion

        #region PUBLIC METHODS
        public void SetData(CommConfig aConfig, CsDeviceData.DeviceModuleData rModuleData)
        {
            DisplayAlarm(rModuleData);
            //switch (aConfig.CommType)
            //{
            //    case csConstData.CommType.COMM_UART:
            //        DisplayAlarmDeltaIndUart(rModuleData);
            //        break;
            //    case csConstData.CommType.COMM_RS485:
            //        DisplayAlarmDeltaInd485(rModuleData);
            //        break;
            //    case csConstData.CommType.COMM_SNMP:
            //        DisplayAlarmSnmp(rModuleData);
            //        break;
            //    default:
            //        break;
            //}
        }
        #endregion

        #region DISPLAY FUNCTION

        private void DisplayAlarm(CsDeviceData.DeviceModuleData rModuleData)
        {
            bool[] aProtect = csUtils.UInt16ToBitArray(rModuleData.StatusData.protect);
            bool[] aWarning = csUtils.UInt16ToBitArray(rModuleData.StatusData.warning);

            // 공통 헬퍼: protect 비트가 우선, 없으면 warning, 둘 다 없으면 정상
            void SetByBits(eAlarmComp comp, int? protectBit, int? warningBit)
            {
                int idx = (int)comp;
                if (protectBit.HasValue && aProtect[protectBit.Value])      { FaultAlarm[idx].SetFault(1); return; }
                if (warningBit.HasValue && aWarning[warningBit.Value])      { FaultAlarm[idx].SetFault(2); return; }
                                                                              FaultAlarm[idx].SetFault(3);
            }

            // 1) OV/UV/OC (양쪽에 동일 인덱스 존재)
            SetByBits(eAlarmComp.MODULE_OV, (int)CsAlarmDefine.eGuiProtectBit.PACK_OV, (int)CsAlarmDefine.eGuiWarningBit.PACK_OV);
            SetByBits(eAlarmComp.CELL_OV  , (int)CsAlarmDefine.eGuiProtectBit.CELL_OV, (int)CsAlarmDefine.eGuiWarningBit.CELL_OV);
            SetByBits(eAlarmComp.MODULE_UV, (int)CsAlarmDefine.eGuiProtectBit.PACK_UV, (int)CsAlarmDefine.eGuiWarningBit.PACK_UV);
            SetByBits(eAlarmComp.CELL_UV  , (int)CsAlarmDefine.eGuiProtectBit.CELL_UV, (int)CsAlarmDefine.eGuiWarningBit.CELL_UV);
            SetByBits(eAlarmComp.CHG_OC   , (int)CsAlarmDefine.eGuiProtectBit.CHG_OC , (int)CsAlarmDefine.eGuiWarningBit.CHG_OC );
            SetByBits(eAlarmComp.DCH_OC   , (int)CsAlarmDefine.eGuiProtectBit.DCH_OC , (int)CsAlarmDefine.eGuiWarningBit.DCH_OC );

            // 2) 온도류
            SetByBits(eAlarmComp.CHG_OT   , (int)CsAlarmDefine.eGuiProtectBit.CHG_OT , (int)CsAlarmDefine.eGuiWarningBit.CHG_OT );
            SetByBits(eAlarmComp.CHG_UT   , (int)CsAlarmDefine.eGuiProtectBit.CHG_UT , (int)CsAlarmDefine.eGuiWarningBit.CHG_UT );
            SetByBits(eAlarmComp.DCH_OT   , (int)CsAlarmDefine.eGuiProtectBit.DCH_OT , (int)CsAlarmDefine.eGuiWarningBit.DCH_OT );
            SetByBits(eAlarmComp.DCH_UT   , (int)CsAlarmDefine.eGuiProtectBit.DCH_UT , (int)CsAlarmDefine.eGuiWarningBit.DCH_UT );

            // 3) Low SOC : 경고 전용
            SetByBits(eAlarmComp.LOW_SOC  , null                                   , (int)CsAlarmDefine.eGuiWarningBit.LOW_SOC);

            // 4) MOS OT : 보호/경고 모두 사용
            SetByBits(eAlarmComp.MOS_OT   , (int)CsAlarmDefine.eGuiProtectBit.MOS_OT, (int)CsAlarmDefine.eGuiWarningBit.MOS_OT);

            // 5) SC(단락) : 보호 전용
            SetByBits(eAlarmComp.SC       , (int)CsAlarmDefine.eGuiProtectBit.SC    , null);

            // 6) DIFF_VOLT : 경고 전용
            SetByBits(eAlarmComp.CB_OFF   , null                                    , (int)CsAlarmDefine.eGuiWarningBit.CB_OFF);
        }

        private void DisplayAlarmDeltaIndUart(CsDeviceData.DeviceModuleData rModuleData)
        {
            bool[] aProtect = csUtils.UInt16ToBitArray(rModuleData.StatusData.protect);
            bool[] aWarning = csUtils.UInt16ToBitArray(rModuleData.StatusData.warning);
            bool[] error = csUtils.UInt16ToBitArray(rModuleData.StatusData.errorCode);

            for (int i = 0; i < 6; i++)
            {
                if (aProtect[i] == true)      { FaultAlarm[i].SetFault(1); }
                else if (aWarning[i] == true) { FaultAlarm[i].SetFault(2); }
                else                          { FaultAlarm[i].SetFault(3); }
            }

            // Charge over temperature warning / protect
            int aComp = 6;
            int alarmID = (int)CsAlarmDefine.eGuiWarningBit.CHG_OT;
            if (aProtect[alarmID] == true)      { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else                                { FaultAlarm[aComp].SetFault(3); }

            // Charge under temperature warning / protect
            aComp = 7;
            alarmID = (int)CsAlarmDefine.eGuiWarningBit.CHG_UT;
            if (aProtect[alarmID] == true) { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else { FaultAlarm[aComp].SetFault(3); }

            // Discharge over temperature warning / protect
            aComp = 8;
            alarmID = (int)CsAlarmDefine.eGuiWarningBit.DCH_OT;
            if (aProtect[alarmID] == true)      { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else                                { FaultAlarm[aComp].SetFault(3); }

            // Discharge under temperature warning / protect
            aComp = 9;
            alarmID = (int)CsAlarmDefine.eGuiWarningBit.DCH_UT;
            if (aProtect[alarmID] == true)      { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else                                { FaultAlarm[aComp].SetFault(3); }

            // Low SOC
            // Discharge under temperature warning / protect
            aComp = 10;
            alarmID = (int)CsAlarmDefine.eGuiWarningBit.LOW_SOC;
            if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else { FaultAlarm[aComp].SetFault(3); }

            // MOS Over Temperature Alarm
            aComp = 11;
            alarmID = (int)CsAlarmDefine.eGuiWarningBit.MOS_OT;
            if (aProtect[alarmID] == true)      { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else                                { FaultAlarm[aComp].SetFault(3); }

            // Short Circuit Protect
            aComp = 12;
            alarmID = (int)CsAlarmDefine.eGuiProtectBit.SC;
            if (aProtect[alarmID] == true) { FaultAlarm[aComp].SetFault(1); }
            else { FaultAlarm[aComp].SetFault(3); }

            // DIFF Cell Voltage Alarm
            aComp = 12;
            alarmID = (int)CsAlarmDefine.eGuiWarningBit.DIFF_VOLT;
            if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else { FaultAlarm[aComp].SetFault(3); }
        }
        private void DisplayAlarmDeltaInd485(CsDeviceData.DeviceModuleData rModuleData)
        {
            bool[] aProtect = csUtils.UInt16ToBitArray(rModuleData.StatusData.protect);
            bool[] aWarning = csUtils.UInt16ToBitArray(rModuleData.StatusData.warning);
            bool[] error = csUtils.UInt16ToBitArray(rModuleData.StatusData.errorCode);

            for (int i = 0; i < 6; i++)
            {
                if (aProtect[i] == true)      { FaultAlarm[i].SetFault(1); }
                else if (aWarning[i] == true) { FaultAlarm[i].SetFault(2); }
                else                          { FaultAlarm[i].SetFault(3); }
            }

            // Charge over temperature warning / protect
            int aComp = 6;
            int alarmID = 8;
            if (aProtect[alarmID] == true)      { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else                                { FaultAlarm[aComp].SetFault(3); }

            // Discharge over temperature warning / protect
            aComp = 8;
            alarmID = 9;
            if (aProtect[alarmID] == true)      { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else                                { FaultAlarm[aComp].SetFault(3); }

            // Charge under temperature warning / protect
            aComp = 7;
            alarmID = 10;
            if (aProtect[alarmID] == true)      { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else                                { FaultAlarm[aComp].SetFault(3); }

            // Discharge under temperature warning / protect
            aComp = 9;
            alarmID = 11;
            if (aProtect[alarmID] == true)      { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else                                { FaultAlarm[aComp].SetFault(3); }

            // Low SOC / SOH
            if (aWarning[12] == true)
            {
                // Low SOC
                FaultAlarm[10].SetFaultName(11, "Low SOC");
                FaultAlarm[10].SetFault(2);
            }
            else if (aWarning[13] == true)
            {
                // Low SOH
                FaultAlarm[10].SetFaultName(11, "Low SOH");
                FaultAlarm[10].SetFault(2);
            }
            else
            {
                FaultAlarm[10].SetFaultName(11, "SOC/SOH");
                FaultAlarm[10].SetFault(3);
            }

            // MOS Over Temperature Alarm
            aComp = 11;
            alarmID = 7;
            if (aProtect[alarmID] == true)      { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else                                { FaultAlarm[aComp].SetFault(3); }

            // Cell ETC. Alarm
            if (aProtect[13] == true)
            {
                // Short Circuit Protect
                FaultAlarm[12].SetFaultName(13, "Short Circuit");
                FaultAlarm[12].SetFault(1);
            }
            else if (aWarning[14] == true)
            {
                FaultAlarm[12].SetFaultName(13, "MD ISO");
                FaultAlarm[12].SetFault(2);
            }
            else
            {
                FaultAlarm[12].SetFaultName(13, "ETC. Alarm");
                FaultAlarm[12].SetFault(3);
            }

            // Error Code
            if (error[0] == true)
            {
                FaultAlarm[13].SetFaultName(14, "Volt Error");
                FaultAlarm[13].SetFault(1);
            }
            else if (error[1] == true)
            {
                FaultAlarm[13].SetFaultName(14, "Temp Error");
                FaultAlarm[13].SetFault(1);
            }
            else if (error[4] == true)
            {
                FaultAlarm[13].SetFaultName(14, "Unbalance");
                FaultAlarm[13].SetFault(1);
            }
            else if (error[5] == true)
            {
                FaultAlarm[13].SetFaultName(14, "Emergency");
                FaultAlarm[13].SetFault(1);
            }
            else
            {
                FaultAlarm[13].SetFaultName(14, "Error Code");
                FaultAlarm[13].SetFault(3);
            }
        }

        private void DisplayAlarmSnmp(CsDeviceData.DeviceModuleData rModuleData)
        {
            bool[] aProtect = csUtils.UInt16ToBitArray(rModuleData.StatusData.protect);
            bool[] aWarning = csUtils.UInt16ToBitArray(rModuleData.StatusData.warning);
            bool[] error = csUtils.UInt16ToBitArray(rModuleData.StatusData.errorCode);

            for (int i = 0; i < 6; i++)
            {
                if (aProtect[i] == true) { FaultAlarm[i].SetFault(1); }
                else if (aWarning[i] == true) { FaultAlarm[i].SetFault(2); }
                else { FaultAlarm[i].SetFault(3); }
            }

            // Charge over temperature warning / protect
            int aComp = 6;
            int alarmID = 8;
            if (aProtect[alarmID] == true) { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else { FaultAlarm[aComp].SetFault(3); }

            // Charge under temperature warning / protect
            aComp = 7;
            alarmID = 10;
            if (aProtect[alarmID] == true) { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else { FaultAlarm[aComp].SetFault(3); }

            // Discharge over temperature warning / protect
            aComp = 8;
            alarmID = 9;
            if (aProtect[alarmID] == true) { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else { FaultAlarm[aComp].SetFault(3); }

            // Discharge under temperature warning / protect
            aComp = 9;
            alarmID = 11;
            if (aProtect[alarmID] == true) { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else { FaultAlarm[aComp].SetFault(3); }

            // Low SOC / SOH
            if (aWarning[12] == true)
            {
                // Low SOC
                FaultAlarm[10].SetFaultName(11, "Low SOC");
                FaultAlarm[10].SetFault(2);
            }
            else if (aWarning[13] == true)
            {
                // Low SOH
                FaultAlarm[10].SetFaultName(11, "Low SOH");
                FaultAlarm[10].SetFault(2);
            }
            else
            {
                FaultAlarm[10].SetFaultName(11, "SOC/SOH");
                FaultAlarm[10].SetFault(3);
            }

            // MOS Over Temperature Alarm
            aComp = 11;
            alarmID = 7;
            if (aProtect[alarmID] == true) { FaultAlarm[aComp].SetFault(1); }
            else if (aWarning[alarmID] == true) { FaultAlarm[aComp].SetFault(2); }
            else { FaultAlarm[aComp].SetFault(3); }

            // Cell ETC. Alarm
            if (aProtect[13] == true)
            {
                // Short Circuit Protect
                FaultAlarm[12].SetFaultName(13, "Short Circuit");
                FaultAlarm[12].SetFault(1);
            }
            else if (aWarning[14] == true)
            {
                FaultAlarm[12].SetFaultName(13, "MD ISO");
                FaultAlarm[12].SetFault(2);
            }
            else
            {
                FaultAlarm[12].SetFaultName(13, "ETC. Alarm");
                FaultAlarm[12].SetFault(3);
            }

            // Error Code
            if (error[0] == true)
            {
                FaultAlarm[13].SetFaultName(14, "Volt Error");
                FaultAlarm[13].SetFault(1);
            }
            else if (error[1] == true)
            {
                FaultAlarm[13].SetFaultName(14, "Temp Error");
                FaultAlarm[13].SetFault(1);
            }
            else if (error[4] == true)
            {
                FaultAlarm[13].SetFaultName(14, "Unbalance");
                FaultAlarm[13].SetFault(1);
            }
            else if (error[5] == true)
            {
                FaultAlarm[13].SetFaultName(14, "Emergency");
                FaultAlarm[13].SetFault(1);
            }
            else
            {
                FaultAlarm[13].SetFaultName(14, "Error Code");
                FaultAlarm[13].SetFault(3);
            }
        }
        #endregion
    }
}
