using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraCharts;

using LFP_Manager.Forms;
using LFP_Manager.DataStructure;
using LFP_Manager.Utils;
using DevExpress.Utils.Text;

namespace LFP_Manager.Controls
{
    public delegate void paramCommand(int sId, int mode, int index, int flag, ref DeviceParamData aParam, ref DeviceCalibration aCalib);

    public partial class ucShelfStatus : DevExpress.XtraEditors.XtraUserControl
    {
        #region CONSTDATA
        const int STATUS_QTY = 10;
        #endregion

        #region VARIABLES
        int ModuleID = 1;
        bool start = false;

        CommConfig Config;

        DeviceSystemData[] SystemData;

        DataTable[] dtVolt;
        DataTable[] dtTemp;
        Series[] seriesVolt;
        Series[] seriesTemp;

        ucStatus[] alarmTrip;

        Palette paletteV;
        Palette paletteT;

        public event paramCommand OnCommand = null;
        public event SendDataUartEvent OnSendUartData = null;
        #endregion

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

            InitStatusName();
        }
        #endregion

        #region PROPERTIES
        public void UpdateSystemId(int mID)
        {
            ModuleID = mID;
        }

        public void Start(int mID, ref CommConfig aConfig, ref DeviceSystemData[] aSystemData)
        {
            ModuleID = mID;
            Config = aConfig;
            SystemData = aSystemData;

            switch (Config.CommType)
            {
                case csConstData.CommType.COMM_UART:
                    btnParam.Text = "Param";
                    btnParam.Enabled = true;
                    btnCalib.Enabled = true;
                    btnCalib.Text = "Calib";
                    break;
                case csConstData.CommType.COMM_RS485:
                    btnParam.Text = "Information";
                    btnParam.Enabled = true;
                    btnCalib.Enabled = true;
                    btnCalib.Text = "Calib";
                    break;
                case csConstData.CommType.COMM_SNMP:
                    btnParam.Text = "Information";
                    btnParam.Enabled = true;
                    btnCalib.Enabled = false;
                    btnCalib.Text = "";
                    break;
                default:
                    break;
            }

            InitDataTableVolt();
            InitDataTableTemp();
            vSeriesInit();
            tSeriesInit();

            tmrDisplay.Start();

            start = true;
        }

        public void Stop()
        {
            start = false;
            tmrDisplay.Stop();
        }

        public void ModuleIDSet(int mID)
        {
            ModuleID = mID;
        }

        public int ModuleIDGet()
        {
            return ModuleID;
        }

        public void UpdateData(ref DeviceSystemData[] aSystemData)
        {
            SystemData = aSystemData;
        }
        #endregion

        #region INIT_COMPONENT

        private void InitStatusName()
        {
            ucHighTemp.SetName("High Temp");
            //ucHighTemp.SetTextWidth(80);
            ucLowTemp.SetName("Low Temp");
            //ucLowTemp.SetTextWidth(80);
            ucOverVolt.SetName("Pack OV");
            //ucOverVolt.SetTextWidth(80);
            ucUnderVolt.SetName("Pack UV");
            //ucUnderVolt.SetTextWidth(80);
            ucCellOverVolt.SetName("Cell OV");
            //ucOverVolt.SetTextWidth(80);
            ucCellUnderVolt.SetName("Cell UV");
            //ucUnderVolt.SetTextWidth(80);
            ucChaOverCurr.SetName("Cha OC");
            //ucChaOverCurr.SetTextWidth(110);
            ucDchOverCurr.SetName("Dch OC");
            //ucDchOverCurr.SetTextWidth(110);
            ucLowSOC.SetName("Low SOC");
            //ucLowSOC.SetTextWidth(80);
            ucCvDiff.SetName("ETC. Alarm");
            //ucMdComm.SetTextWidth(80);

            alarmTrip = new ucStatus[STATUS_QTY];

            alarmTrip[0] = ucHighTemp;
            alarmTrip[1] = ucLowTemp;
            alarmTrip[2] = ucOverVolt;
            alarmTrip[3] = ucUnderVolt;
            alarmTrip[4] = ucCellOverVolt;
            alarmTrip[5] = ucCellUnderVolt;
            alarmTrip[6] = ucChaOverCurr;
            alarmTrip[7] = ucDchOverCurr;
            alarmTrip[8] = ucLowSOC;
            alarmTrip[9] = ucCvDiff;
        }

        private void InitDataTableVolt()
        {
            dtVolt = new DataTable[SystemData[ModuleID - 1].cellQty];

            for (int i = 0; i < dtVolt.Length; i++)
            {
                dtVolt[i] = new DataTable();
                dtVolt[i].Columns.Add("C_No", typeof(Int32));
                dtVolt[i].Columns.Add("Alarm", typeof(Int32));
                dtVolt[i].Columns.Add("Value", typeof(double));

                // Add data rows to the table.
                DataRow row = null;

                row = dtVolt[i].NewRow();
                row["C_No"] = i + 1;
                row["Alarm"] = 0;
                row["Value"] = 3.2;

                dtVolt[i].Rows.Add(row);
            }
        }

        private void InitDataTableTemp()
        {
            dtTemp = new DataTable[SystemData[ModuleID - 1].tempQty];
            for (int i = 0; i < dtTemp.Length; i++)
            {
                dtTemp[i] = new DataTable();
                dtTemp[i].Columns.Add("T_No", typeof(Int32));
                dtTemp[i].Columns.Add("Alarm", typeof(Int32));
                dtTemp[i].Columns.Add("Value", typeof(double));

                // Add data rows to the table.
                DataRow row = null;

                row = dtTemp[i].NewRow();
                row["T_No"] = i + 1;
                row["Alarm"] = 0;
                row["Value"] = 25.4;
                dtTemp[i].Rows.Add(row);
            }
        }

        private Palette vPaletteInit(string bName, short bValue)
        {
            paletteV = new Palette(bName);
            for (int i = 0; i < dtVolt.Length; i++)
            {
                if (((bValue >> i) & 0x0001) == 0x0001)
                    paletteV.Add(Color.Orange);
                else
                    paletteV.Add(Color.Green);
            }
            return paletteV;
        }

        private void vPaletteUpdate(short bValue)
        {
            paletteV.Clear();
            for (int i = 0; i < dtVolt.Length; i++)
            {
                if (((bValue >> i) & 0x0001) == 0x0001)
                    paletteV.Add(Color.Orange);
                else
                    paletteV.Add(Color.Green);
            }
        }

        private Palette tPaletteInit(string bName, short bValue)
        {
            paletteT = new Palette(bName);

            for (int i = 0; i < dtTemp.Length; i++)
            {
                if (((bValue >> i) & 0x0001) == 0x0001)
                    paletteT.Add(Color.Orange);
                else
                    paletteT.Add(Color.Green);
            }

            return paletteT;
        }

        private void tPaletteUpdate(short bValue)
        {
            paletteT.Clear();
            for (int i = 0; i < dtTemp.Length; i++)
            {
                if (((bValue >> i) & 0x0001) == 0x0001)
                    paletteT.Add(Color.Orange);
                else
                    paletteT.Add(Color.Green);
            }
        }

        private void vSeriesInit()
        {
            VChart.Series.Clear();
            VChart.Legend.Visibility = DevExpress.Utils.DefaultBoolean.False;

            seriesVolt = new Series[SystemData[ModuleID - 1].cellQty];

            for (int i = 0; i < seriesVolt.Length; i++)
            {
                seriesVolt[i] = new Series(String.Format("C_{0:00}", i + 1), ViewType.Bar)
                {
                    DataSource = dtVolt[i],
                    //Label.PointOptions.PointView = PointView.ArgumentAndValues,
                    //Label.PointOptions.ValueNumericOptions.Format = NumericFormat.Number,
                    //Label.PointOptions.ValueNumericOptions.Precision = 3,
                    CrosshairLabelPattern = "C_{A:00} : {V:F3}",

                    // Specify data members to bind the series.
                    ArgumentScaleType = ScaleType.Numerical,
                    ArgumentDataMember = "C_No",
                    ValueScaleType = ScaleType.Numerical,
                };
                ((SideBySideBarSeriesView)(seriesVolt[i].View)).BarWidth = 10.0;
                seriesVolt[i].ValueDataMembers.AddRange(new string[] { "Value" });
                VChart.Series.Add(seriesVolt[i]);
            }

            VChart.PaletteRepository.Clear();
            VChart.PaletteRepository.Add("V Palette", vPaletteInit("V Palette", 0));
            VChart.PaletteName = "V Palette";

            // Cast the chart's diagram to the XYDiagram type, to access its axes.
            XYDiagram diagram = (XYDiagram)VChart.Diagram;
            if (diagram.AxisY.ConstantLines.Count > 0)
                diagram.AxisY.ConstantLines.Clear();

            // Create a constant line.
            ConstantLine constantLineMax = new ConstantLine("Limit(Max)");
            ConstantLine constantLineMin = new ConstantLine("Limit(Min)");
            ConstantLine constantDataMax = new ConstantLine(
                String.Format("                                                                   Max({0:#0.000}V:{1:00})", 0, 0));
            ConstantLine constantDataAvg = new ConstantLine(
                String.Format("                                 Avg({0:#0.000}V) - ({1:#0.000}V)", 0, 0));
            ConstantLine constantDataMin = new ConstantLine(
                String.Format("Min({0:#0.000}V:{1:00})", 0, 0));

            constantLineMax.Color = Color.Red;
            constantLineMin.Color = Color.Red;

            // Customize the behavior of the constant line.
            constantLineMax.Visible = true;
            constantLineMax.ShowInLegend = true;
            constantLineMax.LegendText = "Limit(Max)";
            constantLineMax.ShowBehind = false;

            constantLineMin.Visible = true;
            constantLineMin.ShowInLegend = true;
            constantLineMin.LegendText = "Limit(Min)";
            constantLineMin.ShowBehind = false;

            constantDataMax.Visible = true;
            constantDataMax.ShowInLegend = true;
            constantDataMax.LegendText = "Max";
            constantDataMax.ShowBehind = false;
            constantDataMax.Color = Color.MediumVioletRed;
            constantDataMax.Title.TextColor = Color.Black;
            constantDataMax.Title.Font = new System.Drawing.Font("Tahoma", 8F, System.Drawing.FontStyle.Bold);

            constantDataAvg.Visible = true;
            constantDataAvg.ShowInLegend = true;
            constantDataAvg.LegendText = "Avg";
            constantDataAvg.ShowBehind = false;
            constantDataAvg.Color = Color.LawnGreen;
            constantDataAvg.Title.TextColor = Color.Black;
            constantDataAvg.Title.Font = new System.Drawing.Font("Tahoma", 8F, System.Drawing.FontStyle.Bold);

            constantDataMin.Visible = true;
            constantDataMin.ShowInLegend = true;
            constantDataMin.LegendText = "Min";
            constantDataMin.ShowBehind = false;
            constantDataMin.Color = Color.BlueViolet;
            constantDataMin.Title.TextColor = Color.Black;
            constantDataMin.Title.Font = new System.Drawing.Font("Tahoma", 8F, System.Drawing.FontStyle.Bold);

            // Define its axis value.
            constantLineMax.AxisValue = 3.85;
            constantLineMin.AxisValue = 2.5;
            constantDataMax.AxisValue = 0;
            constantDataAvg.AxisValue = 0;
            constantDataMin.AxisValue = 0;

            diagram.AxisY.ConstantLines.Add(constantLineMax);
            diagram.AxisY.ConstantLines.Add(constantLineMin);
            diagram.AxisY.ConstantLines.Add(constantDataMax);
            diagram.AxisY.ConstantLines.Add(constantDataAvg);
            diagram.AxisY.ConstantLines.Add(constantDataMin);

            // Axis Y
            diagram.AxisY.VisualRange.Auto = false;
            diagram.AxisY.VisualRange.AutoSideMargins = false;
            diagram.AxisY.VisualRange.StartSideMargin = 0;
            diagram.AxisY.VisualRange.EndSideMargin = 0;
            diagram.AxisY.VisualRange.MaxValue = 4.0;
            diagram.AxisY.VisualRange.MinValue = 2.0;
            diagram.AxisY.WholeRange.MaxValue = 4.0;
            diagram.AxisY.WholeRange.MinValue = 2.0;

            diagram.AxisY.NumericScaleOptions.AutoGrid = false;
            diagram.AxisY.NumericScaleOptions.GridAlignment = NumericGridAlignment.Ones;
            diagram.AxisY.NumericScaleOptions.GridOffset = 0;
            diagram.AxisY.NumericScaleOptions.GridSpacing = 0.1;

            //diagram.AxisY.GridSpacing = 0.1;
            diagram.AxisY.Title.Text = "Voltage(V)";
            //diagram.AxisY.Label.NumericOptions.Precision = 3;
            diagram.AxisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.True;
            diagram.AxisY.Title.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular);

            // Axis X
            diagram.AxisX.VisualRange.MaxValue = seriesVolt.Length;
            diagram.AxisX.VisualRange.MinValue = 1;
            diagram.AxisX.VisualRange.Auto = false;
            diagram.AxisX.VisualRange.AutoSideMargins = false;
            diagram.AxisX.VisualRange.SideMarginsValue = 0.5;

            diagram.AxisX.Title.Text = "Cell No";
            diagram.AxisX.Title.Visibility = DevExpress.Utils.DefaultBoolean.False;
            diagram.AxisX.Title.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular);
        }

        private void tSeriesInit()
        {
            TChart.Series.Clear();
            TChart.Legend.Visibility = DevExpress.Utils.DefaultBoolean.False;

            seriesTemp = new Series[SystemData[ModuleID - 1].tempQty];

            for (int i = 0; i < seriesTemp.Length; i++)
            {
                seriesTemp[i] = new Series(String.Format("T_{0:00}", i + 1), ViewType.Bar)
                {
                    DataSource = dtTemp[i],
                    //Label.PointOptions.PointView = PointView.ArgumentAndValues,
                    //Label.PointOptions.ValueNumericOptions.Format = NumericFormat.Number,
                    //Label.PointOptions.ValueNumericOptions.Precision = 3,
                    CrosshairLabelPattern = "T_{A:00} : {V:F1}",

                    // Specify data members to bind the series.
                    ArgumentScaleType = ScaleType.Numerical,
                    ArgumentDataMember = "T_No",
                    ValueScaleType = ScaleType.Numerical,
                };
                ((SideBySideBarSeriesView)(seriesTemp[i].View)).BarWidth = 2.5;
                seriesTemp[i].ValueDataMembers.AddRange(new string[] { "Value" });
                TChart.Series.Add(seriesTemp[i]);
            }

            TChart.PaletteRepository.Clear();
            TChart.PaletteRepository.Add("T Palette", tPaletteInit("T Palette", 0));
            TChart.PaletteName = "T Palette";

            // Cast the chart's diagram to the XYDiagram type, to access its axes.
            XYDiagram diagram = (XYDiagram)TChart.Diagram;
            if (diagram.AxisY.ConstantLines.Count > 0)
                diagram.AxisY.ConstantLines.Clear();

            diagram.Margins.All = 0;

            ConstantLine constantLineMax = new ConstantLine("Limit(Max)");
            ConstantLine constantLineMin = new ConstantLine("Limit(Min)");
            ConstantLine constantDataMax = new ConstantLine(String.Format("                                            Max({0:#0.0}C)", 0));
            ConstantLine constantDataAvg = new ConstantLine(String.Format("                     Avg({0:#0.0}C)", 0));
            ConstantLine constantDataMin = new ConstantLine(String.Format("Min({0:#0.0}C)", 0));

            constantLineMax.Color = Color.Red;
            constantLineMin.Color = Color.Red;

            // Customize the behavior of the constant line.
            constantLineMax.Visible = true;
            constantLineMax.ShowInLegend = true;
            constantLineMax.LegendText = "Limit(Max)";
            constantLineMax.ShowBehind = false;

            constantLineMin.Visible = true;
            constantLineMin.ShowInLegend = true;
            constantLineMin.LegendText = "Limit(Min)";
            constantLineMin.ShowBehind = false;

            constantDataMax.Visible = true;
            constantDataMax.ShowInLegend = true;
            constantDataMax.LegendText = "Max";
            constantDataMax.ShowBehind = false;
            constantDataMax.Color = Color.MediumVioletRed;
            constantDataMax.Title.TextColor = Color.Black;
            constantDataMax.Title.Font = new System.Drawing.Font("Tahoma", 8F, System.Drawing.FontStyle.Bold);

            constantDataAvg.Visible = true;
            constantDataAvg.ShowInLegend = true;
            constantDataAvg.LegendText = "Avg";
            constantDataAvg.ShowBehind = false;
            constantDataAvg.Color = Color.LawnGreen;
            constantDataAvg.Title.TextColor = Color.Black;
            constantDataAvg.Title.Font = new System.Drawing.Font("Tahoma", 8F, System.Drawing.FontStyle.Bold);

            constantDataMin.Visible = true;
            constantDataMin.ShowInLegend = true;
            constantDataMin.LegendText = "Min";
            constantDataMin.ShowBehind = false;
            constantDataMin.Color = Color.BlueViolet;
            constantDataMin.Title.TextColor = Color.Black;
            constantDataMin.Title.Font = new System.Drawing.Font("Tahoma", 8F, System.Drawing.FontStyle.Bold);

            // Define its axis value.
            constantLineMax.AxisValue = 60.0;
            constantLineMin.AxisValue = -20.0;
            constantDataMax.AxisValue = 0;
            constantDataAvg.AxisValue = 0;
            constantDataMin.AxisValue = 0;

            diagram.AxisY.ConstantLines.Add(constantLineMax);
            diagram.AxisY.ConstantLines.Add(constantLineMin);
            diagram.AxisY.ConstantLines.Add(constantDataMax);
            diagram.AxisY.ConstantLines.Add(constantDataAvg);
            diagram.AxisY.ConstantLines.Add(constantDataMin);

            // Axis Y
            diagram.AxisY.VisualRange.Auto = false;
            diagram.AxisY.VisualRange.AutoSideMargins = false;
            diagram.AxisY.VisualRange.StartSideMargin = 0;
            diagram.AxisY.VisualRange.EndSideMargin = 0;
            diagram.AxisY.VisualRange.MaxValue = 80.0;
            diagram.AxisY.VisualRange.MinValue = -30.0;
            diagram.AxisY.WholeRange.MaxValue = 80.0;
            diagram.AxisY.WholeRange.MinValue = -30.0;

            diagram.AxisY.NumericScaleOptions.AutoGrid = false;
            diagram.AxisY.NumericScaleOptions.GridAlignment = NumericGridAlignment.Ones;
            diagram.AxisY.NumericScaleOptions.GridOffset = 0;
            diagram.AxisY.NumericScaleOptions.GridSpacing = 5;

            diagram.AxisY.Title.Text = "Temperature(C)";
            diagram.AxisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.True;
            diagram.AxisY.Title.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular);

            // Axis X
            diagram.AxisX.VisualRange.MaxValue = seriesTemp.Length;
            diagram.AxisX.VisualRange.MinValue = 1;
            diagram.AxisX.VisualRange.Auto = false;
            diagram.AxisX.VisualRange.AutoSideMargins = false;
            diagram.AxisX.VisualRange.SideMarginsValue = 0.5;

            diagram.AxisX.Title.Text = "Temperature No";
            diagram.AxisX.Title.Visibility = DevExpress.Utils.DefaultBoolean.False;
            diagram.AxisX.Title.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular);
        }

        #endregion

        #region DISPLAY DATA

        private void tmrDisplay_Tick(object sender, EventArgs e)
        {
            DisplayLevelMasking();
            switch (Config.CommType)
            {
                case csConstData.CommType.COMM_UART:
                    switch (Config.UartModelIndex)
                    {
                        case csConstData.MODEL_INDEX.LFPM_124050D: // 124050
                            DisplayDataUart124050();
                            break;
                        default:
                            DisplayDataUart();
                            break;
                    }
                    break;
                case csConstData.CommType.COMM_RS485:
                    DisplayDataRs485();
                    break;
                case csConstData.CommType.COMM_SNMP:
                    DisplayDataSnmp();
                    break;
                default:
                    break;
            }
        }

        void DisplayLevelMasking()
        {
            switch (Config.CommType)
            {
                case csConstData.CommType.COMM_UART:
                    // UART Mode
                    switch (Config.ControlLevel)
                    {
                        case 0:         // User Level
                            btnCalib.Text = "Calib";
                            btnCalib.Enabled = false;
                            break;
                        case 1:         // Technician Level
                            btnCalib.Text = "Calib";
                            btnCalib.Enabled = true;
                            break;
                        case 2:         // Engineer Level
                            btnCalib.Text = "Calib";
                            btnCalib.Enabled = true;
                            break;
                        case 3:         // Master Level
                            btnCalib.Text = "Calib";
                            btnCalib.Enabled = true;
                            break;
                        default:        // User Level
                            btnCalib.Text = "Calib";
                            btnCalib.Enabled = true;
                            break;
                    }
                    break;
                case csConstData.CommType.COMM_RS485:
                    switch (Config.ControlLevel)
                    {
                        case 0:         // User Level
                            btnCalib.Text = "Calib";
                            btnCalib.Enabled = false;
                            break;
                        case 1:         // Technician Level
                            btnCalib.Text = "Calib";
                            btnCalib.Enabled = true;
                            break;
                        case 2:         // Engineer Level
                            btnCalib.Text = "Calib";
                            btnCalib.Enabled = true;
                            break;
                        case 3:         // Master Level
                            btnCalib.Text = "Calib";
                            btnCalib.Enabled = true;
                            break;
                        default:        // User Level
                            btnCalib.Text = "Calib";
                            btnCalib.Enabled = true;
                            break;
                    }
                    break;
                case csConstData.CommType.COMM_SNMP:
                    // SNMP Mode
                    btnCalib.Enabled = false;
                    btnCalib.Text = "";
                    break;
                default:
                    break;
            }
        }

        void DisplayDataUart()
        {
            if (start)
            {
                dgVoltage.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.voltageOfPack) / 10);
                dgCurrent.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.current) / 10);
                dgSOC.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.rSOC) / 10);
                dgSOH.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.stateOfHealth) / 10);
                dgTemperature.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].AvgData.maxTemp) / 10);               //Byul 21.08.09 "maxTemp"
                lbFetTemp.Text = String.Format("  FET: {0:##0.0}C", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.Ext1Temperature) / 10);
                lbAmbTemp.Text = String.Format("  AMB: {0:##0.0}C", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.Ext2Temperature) / 10);

                //lbFetTemp.Text = String.Format("  FAULT: 0x{0:X4}", SystemData[ModuleID - 1].StatusData.protection);

                lbHeatbeat.Text = String.Format("Cycle: {0}", SystemData[ModuleID - 1].ValueData.cycleCount);

                DisplayCellVoltage();
                DisplayCellTemperature();

                DisplayInformationUart();
                DisplayAlarmUart();
                DisplayStatusStrUart();
                DisplayAlarmStrUart();
            }
        }

        void DisplayDataUart124050()
        {
            if (start)
            {
                dgVoltage.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.voltageOfPack) / 10);
                dgCurrent.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.current) / 10);
                dgSOC.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.rSOC) / 10);
                dgSOH.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.stateOfHealth) / 10);
                dgTemperature.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].AvgData.maxTemp) / 10);               //Byul 21.08.09 "maxTemp"
                lbFetTemp.Text = String.Format("  FET: {0:##0.0}C", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.Ext1Temperature) / 10);
                lbAmbTemp.Text = String.Format("  AMB: {0:##0.0}C", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.Ext2Temperature) / 10);

                //lbFetTemp.Text = String.Format("  FAULT: 0x{0:X4}", SystemData[ModuleID - 1].StatusData.specialAlarm);

                lbHeatbeat.Text = String.Format("Cycle: {0}", SystemData[ModuleID - 1].ValueData.cycleCount);

                DisplayCellVoltage();
                DisplayCellTemperature();

                DisplayInformationUart();
                DisplayAlarmUart124050();
                DisplayStatusStrUart124050();
                DisplayAlarmStrUart124050();
            }
        }
        void DisplayDataRs485()
        {
            if (start)
            {
                dgVoltage.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.voltageOfPack) / 10);
                dgCurrent.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.current) / 10);
                dgSOC.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.rSOC) / 10);
                dgSOH.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.stateOfHealth) / 10);
                dgTemperature.Text = String.Format("{0:0.0}", Convert.ToDouble(SystemData[ModuleID - 1].AvgData.maxTemp) / 10);               //Byul 21.08.09 "maxTemp"
                lbFetTemp.Text = String.Format(@"  AVG: {0:##0.0}C", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.Ext1Temperature) / 10);
                lbAmbTemp.Text = String.Format(@"  AMB: {0:##0.0}C", Convert.ToDouble(SystemData[ModuleID - 1].ValueData.Ext2Temperature) / 10);

                lbHeatbeat.Text = String.Format("Cycle: {0}", SystemData[ModuleID - 1].ValueData.cycleCount);
                //lbHeatbeat.Text = String.Format("Cycle: {0}", SystemData[ModuleID - 1].MaxValue.MaxChgCurrent);

                DisplayCellVoltage();
                DisplayCellTemperature();

                DisplayInformationRs485();
                DisplayAlarmRs485();

                DisplayStatusStrRs485();
                DisplayAlarmStrRs485();
            }
        }

        void DisplayDataSnmp()
        {
            if (start)
            {
                dgVoltage.Text = string.Format("{0:0.0}", Convert.ToDouble(SystemData[0].ValueData.voltageOfPack) / 10);
                dgCurrent.Text = string.Format("{0:0.0}", Convert.ToDouble(SystemData[0].ValueData.current) / 10);
                dgSOC.Text = string.Format("{0:0.0}", Convert.ToDouble(SystemData[0].ValueData.rSOC) / 10);
                dgSOH.Text = string.Format("{0:0.0}", Convert.ToDouble(SystemData[0].ValueData.stateOfHealth) / 10);
                dgTemperature.Text = string.Format("{0:0.0}", Convert.ToDouble(SystemData[0].AvgData.maxTemp) / 10);               //Byul 21.08.09 "maxTemp"
                lbFetTemp.Text = string.Format("  FET: {0:##0.0}C", Convert.ToDouble(SystemData[0].ValueData.Ext1Temperature) / 10);
                lbAmbTemp.Text = string.Format("  AMB: {0:##0.0}C", Convert.ToDouble(SystemData[0].ValueData.Ext2Temperature) / 10);

                lbHeatbeat.Text = string.Format("Cycle: {0}", SystemData[0].ValueData.cycleCount);

                DisplayCellVoltage();
                DisplayCellTemperature();

                DisplayInformationUart();
                DisplayAlarmSnmp();
                DisplayStatusStrSnmp();
                DisplayAlarmStrSnmp();
            }
        }

        private void DisplayInformationUart()
        {
            string strInfor = string.Format("V: {0} - Model: {1} - SN: {2}"
                , SystemData[ModuleID - 1].Information.SwProductRev
                , SystemData[ModuleID - 1].Information.ModelName
                , SystemData[ModuleID - 1].Information.HwSerialNumber
                );
            gbValue.Text = "Value - " + strInfor;
        }

        private void DisplayInformationRs485()
        {
            string strInfor = string.Format("V: {0} - Model: {1} - SN: {2}"
                , SystemData[ModuleID - 1].Information.SwProductRev
                , SystemData[ModuleID - 1].Information.ModelName
                , SystemData[ModuleID - 1].Information.HwSerialNumber
                );
            gbValue.Text = "Value - " + strInfor;
        }

        private void DisplayInformationSnmp()
        {
            string strInfor = string.Format("V: {0} - Model: {1} ({2}) - SN: {3} ({4})"
                , SystemData[0].Information.SwProductRev
                , SystemData[0].Information.ModelName
                , SystemData[0].Information.ProductCode
                , SystemData[0].Information.HwSerialNumber
                , SystemData[0].Information.ManufacturingDate
                );
            gbValue.Text = "Value - " + strInfor;
        }

        private void DisplayCellVoltage()
        {
            try
            {
                for (int i = 0; i < seriesVolt.Length; i++)
                    dtVolt[i].Rows[0]["Value"] = Convert.ToDouble(SystemData[ModuleID - 1].ValueData.CellVoltage[i]) / 1000;

                if (SystemData[ModuleID - 1].StatusData.cellBallanceStatus != 0x0000)
                    vPaletteUpdate(SystemData[ModuleID - 1].StatusData.cellBallanceStatus);
                else
                    vPaletteUpdate(0);

                double maxValue = Convert.ToDouble(SystemData[ModuleID - 1].AvgData.maxCellVoltage) / 1000;
                double avgValue = Convert.ToDouble(SystemData[ModuleID - 1].AvgData.avgCellVoltage) / 1000;
                double minValue = Convert.ToDouble(SystemData[ModuleID - 1].AvgData.minCellVoltage) / 1000;
                double gapValue = Convert.ToDouble(SystemData[ModuleID - 1].AvgData.diffCellVoltage) / 1000;
                int maxCno = Convert.ToInt32(SystemData[ModuleID - 1].AvgData.maxCellNum);
                int minCno = Convert.ToInt32(SystemData[ModuleID - 1].AvgData.minCellNum);

                // Cast the chart's diagram to the XYDiagram type, to access its axes.
                ((XYDiagram)VChart.Diagram).AxisY.ConstantLines[2].Name =
                    String.Format("                                                                            Max({0:#0.000}V:{1:00})", maxValue, maxCno);
                ((XYDiagram)VChart.Diagram).AxisY.ConstantLines[3].Name =
                    String.Format("                                 Avg({0:#0.000}V) - ({1:#0.000}V)", avgValue, gapValue);
                ((XYDiagram)VChart.Diagram).AxisY.ConstantLines[4].Name =
                    String.Format("Min({0:#0.000}V:{1:00})", minValue, minCno);

                // Define its axis value.
                ((XYDiagram)VChart.Diagram).AxisY.ConstantLines[2].AxisValue = maxValue;
                ((XYDiagram)VChart.Diagram).AxisY.ConstantLines[3].AxisValue = avgValue;
                ((XYDiagram)VChart.Diagram).AxisY.ConstantLines[4].AxisValue = minValue;

                //VChart.Legend.Visible = true;

                //VChart.Titles[0].Text =
                //    String.Format("Voltage Status");

                //VChart.Invalidate();
            }
            catch (Exception)
            {
                //MsgBox.ErrorShow(ex);
            }

        }
        private void DisplayCellTemperature()
        {
            try
            {
                for (int i = 0; i < seriesTemp.Length; i++)
                    dtTemp[i].Rows[0]["Value"] = Convert.ToDouble(SystemData[ModuleID - 1].ValueData.CellTemperature[i]) / 10;

                double maxValue = Convert.ToDouble(SystemData[ModuleID - 1].AvgData.maxTemp) / 10;
                double avgValue = Convert.ToDouble(SystemData[ModuleID - 1].AvgData.avgTemp) / 10;
                double minValue = Convert.ToDouble(SystemData[ModuleID - 1].AvgData.minTemp) / 10;
                int maxCno = Convert.ToInt32(SystemData[ModuleID - 1].AvgData.maxTempNum);
                int minCno = Convert.ToInt32(SystemData[ModuleID - 1].AvgData.minTempNum);

                ((XYDiagram)TChart.Diagram).AxisY.ConstantLines[2].Name = String.Format("                                                       Max({0:#0.0}C:{1:00})", maxValue, maxCno);
                ((XYDiagram)TChart.Diagram).AxisY.ConstantLines[3].Name = String.Format("                              Avg({0:#0.0}C)", avgValue);
                ((XYDiagram)TChart.Diagram).AxisY.ConstantLines[4].Name = String.Format("Min({0:#0.0}C:{1:00})", minValue, minCno);

                // Define its axis value.
                ((XYDiagram)TChart.Diagram).AxisY.ConstantLines[2].AxisValue = maxValue;
                ((XYDiagram)TChart.Diagram).AxisY.ConstantLines[3].AxisValue = avgValue;
                ((XYDiagram)TChart.Diagram).AxisY.ConstantLines[4].AxisValue = minValue;

                //TChart.Legend.Visible = true;

                //TChart.Titles[0].Text =
                //    String.Format("Temperature Status");
            }
            catch (Exception)
            {
                //MsgBox.ErrorShow(ex);
            }

        }

        private void DisplayStatusStrUart()
        {
            if (SystemData[ModuleID - 1].CommFail == false)
            {
                if (SystemData[ModuleID - 1].ShelfCommFail == false)
                {
                    switch ((int)SystemData[ModuleID - 1].StatusData.status)
                    {
                        case 0x0000:                // Stand by
                            lbStatus.Text = "STANDBY";
                            lbStatus.ForeColor = System.Drawing.Color.Black;
                            break;
                        case 0x0001:                // Charging
                            lbStatus.Text = "CHARGING";
                            lbStatus.ForeColor = System.Drawing.Color.Blue;
                            break;
                        case 0x0002:                // Discharging
                            lbStatus.Text = "DISCHARGING";
                            lbStatus.ForeColor = System.Drawing.Color.Magenta;
                            break;
                        case 0x0004:                // TRIP
                            if ((SystemData[ModuleID - 1].StatusData.specialAlarm & 0x0001) != 0)
                            {
                                lbStatus.Text = "PWR-OFF"; // "ANTI -THEFT (Comm.)";
                                lbStatus.ForeColor = Color.Red;
                            }
                            else if ((SystemData[ModuleID - 1].StatusData.specialAlarm & 0x0002) != 0)
                            {
                                lbStatus.Text = "PWR-OFF";  // "ANTI -THEFT (Gyro)";
                                lbStatus.ForeColor = Color.Red;
                            }
                            else
                            {
                                lbStatus.Text = "TRIP";
                                lbStatus.ForeColor = Color.Red;
                            }
                            break;
                        case 0x0008:                // Chg-Lmt
                            lbStatus.Text = "CHG-LIMIT";
                            lbStatus.ForeColor = System.Drawing.Color.Blue;
                            break;
                        case 0x8000:                // Stand by - Heat
                            lbStatus.Text = "STANDBY-HEAT";
                            lbStatus.ForeColor = System.Drawing.Color.Blue;
                            break;
                        case 0x8001:                // Charging
                            lbStatus.Text = "CHARGING-HEAT";
                            lbStatus.ForeColor = System.Drawing.Color.Blue;
                            break;
                        case 0x8002:                // Discharging
                            lbStatus.Text = "DISCHARGING-HEAT";
                            lbStatus.ForeColor = System.Drawing.Color.Magenta;
                            break;
                        case 0x8004:                // TRIP
                            lbStatus.Text = "TRIP-HEAT";
                            lbStatus.ForeColor = System.Drawing.Color.Red;
                            break;
                        case 0x8008:                // Chg-Lmt
                            lbStatus.Text = "CHG-LIMIT-HEAT";
                            lbStatus.ForeColor = System.Drawing.Color.Blue;
                            break;
                        default:
                            lbStatus.Text = "UNKNOWN";
                            lbStatus.ForeColor = System.Drawing.Color.Black;
                            break;
                    }
                }
                else
                {
                    lbStatus.Text = "COMM FAIL";
                    lbStatus.ForeColor = System.Drawing.Color.Red;
                }
            }
            else
            {
                lbStatus.Text = "OFF LINE";
                lbStatus.ForeColor = System.Drawing.Color.Red;
            }
        }
        private void DisplayStatusStrUart124050()
        {
            if (SystemData[ModuleID - 1].CommFail == false)
            {
                if (SystemData[ModuleID - 1].ShelfCommFail == false)
                {
                    switch ((int)SystemData[ModuleID - 1].StatusData.status)
                    {
                        case 0x0000:                // Stand by
                            lbStatus.Text = "STANDBY";
                            lbStatus.ForeColor = System.Drawing.Color.Black;
                            break;
                        case 0x0001:                // Charging
                            lbStatus.Text = "CHARGING";
                            lbStatus.ForeColor = System.Drawing.Color.Blue;
                            break;
                        case 0x0002:                // Discharging
                            lbStatus.Text = "DISCHARGING";
                            lbStatus.ForeColor = System.Drawing.Color.Magenta;
                            break;
                        case 0x0004:                // TRIP
                            if ((SystemData[ModuleID - 1].StatusData.errorCode & 0x8000) != 0)
                            {
                                lbStatus.Text = "PWR-OFF"; // "ANTI -THEFT (Comm.)";
                                lbStatus.ForeColor = Color.Red;
                            }
                            else if ((SystemData[ModuleID - 1].StatusData.errorCode & 0x4000) != 0)
                            {
                                lbStatus.Text = "PWR-OFF";  // "ANTI -THEFT (Gyro)";
                                lbStatus.ForeColor = Color.Red;
                            }
                            else
                            {
                                lbStatus.Text = "TRIP";
                                lbStatus.ForeColor = Color.Red;
                            }
                            break;
                        case 0x0008:                // Chg-Lmt
                            lbStatus.Text = "CHG-LIMIT";
                            lbStatus.ForeColor = System.Drawing.Color.Blue;
                            break;
                        case 0x8000:                // Stand by - Heat
                            lbStatus.Text = "STANDBY-HEAT";
                            lbStatus.ForeColor = System.Drawing.Color.Blue;
                            break;
                        case 0x8001:                // Charging
                            lbStatus.Text = "CHARGING-HEAT";
                            lbStatus.ForeColor = System.Drawing.Color.Blue;
                            break;
                        case 0x8002:                // Discharging
                            lbStatus.Text = "DISCHARGING-HEAT";
                            lbStatus.ForeColor = System.Drawing.Color.Magenta;
                            break;
                        case 0x8004:                // TRIP
                            lbStatus.Text = "TRIP-HEAT";
                            lbStatus.ForeColor = System.Drawing.Color.Red;
                            break;
                        case 0x8008:                // Chg-Lmt
                            lbStatus.Text = "CHG-LIMIT-HEAT";
                            lbStatus.ForeColor = System.Drawing.Color.Blue;
                            break;
                        default:
                            lbStatus.Text = "UNKNOWN";
                            lbStatus.ForeColor = System.Drawing.Color.Black;
                            break;
                    }
                }
                else
                {
                    lbStatus.Text = "COMM FAIL";
                    lbStatus.ForeColor = System.Drawing.Color.Red;
                }
            }
            else
            {
                lbStatus.Text = "OFF LINE";
                lbStatus.ForeColor = System.Drawing.Color.Red;
            }
        }

        private void DisplayAlarmStrUart()
        {
            if (SystemData[ModuleID - 1].CommFail == false)
            {
                if (SystemData[ModuleID - 1].ShelfCommFail == false)
                {
                    switch (SystemData[ModuleID - 1].StatusData.batteryStatus)
                    {
                        case 0:         // NORMAL
                            if ((SystemData[ModuleID - 1].StatusData.specialAlarm & 0x0001) != 0)
                            {
                                lbAlarm.Text = "FAULT (Comm)";
                                lbAlarm.ForeColor = Color.Red;
                            }
                            else if ((SystemData[ModuleID - 1].StatusData.specialAlarm & 0x0002) != 0)
                            {
                                lbAlarm.Text = "FAULT (GyroScope)";
                                lbAlarm.ForeColor = Color.Red;
                            }
                            else
                            {
                                if ((SystemData[ModuleID - 1].StatusData.specialAlarm & 0x0004) != 0)
                                {
                                    lbAlarm.Text = "WARNING";
                                    lbAlarm.ForeColor = System.Drawing.Color.Orange;
                                }
                                else
                                {
                                    lbAlarm.Text = "NORMAL";
                                    lbAlarm.ForeColor = System.Drawing.Color.Green;
                                }
                            }
                            break;
                        case 1:         // WARNING
                            lbAlarm.Text = "WARNING";
                            lbAlarm.ForeColor = System.Drawing.Color.Orange;
                            break;
                        case 2:         // FAULT
                            lbAlarm.Text = "FAULT";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        case 3:         // WARMING UP
                            lbAlarm.Text = "WARMING UP";
                            lbAlarm.ForeColor = System.Drawing.Color.Black;
                            break;
                        case 4:         // FAULT (Anti-Theft GyroScope.)
                            lbAlarm.Text = "FAULT (GyroScope)";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        case 5:         // FAULT (Anti-Theft Gyro-Scope)
                            lbAlarm.Text = "FAULT (Comm)";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        default:
                            lbAlarm.Text = string.Format("UNKNOWN ({0})", SystemData[ModuleID - 1].StatusData.batteryStatus);
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                    }
                }
                else
                {
                    lbAlarm.Text = "COMM FAIL";
                    lbAlarm.ForeColor = System.Drawing.Color.Red;
                }
            }
            else
            {
                lbAlarm.Text = "OFF LINE";
                lbAlarm.ForeColor = System.Drawing.Color.Red;
            }
        }
        private void DisplayAlarmStrUart124050()
        {
            if (SystemData[ModuleID - 1].CommFail == false)
            {
                if (SystemData[ModuleID - 1].ShelfCommFail == false)
                {
                    switch (SystemData[ModuleID - 1].StatusData.batteryStatus)
                    {
                        case 0:         // NORMAL
                            if ((SystemData[ModuleID - 1].StatusData.errorCode & 0x8000) != 0)
                            {
                                lbAlarm.Text = "FAULT (Comm)";
                                lbAlarm.ForeColor = Color.Red;
                            }
                            else if ((SystemData[ModuleID - 1].StatusData.errorCode & 0x4000) != 0)
                            {
                                lbAlarm.Text = "FAULT (GyroScope)";
                                lbAlarm.ForeColor = Color.Red;
                            }
                            else
                            {
                                if ((SystemData[ModuleID - 1].StatusData.specialAlarm & 0x4000) != 0)
                                {
                                    lbAlarm.Text = "WARNING";
                                    lbAlarm.ForeColor = System.Drawing.Color.Orange;
                                }
                                else
                                {
                                    lbAlarm.Text = "NORMAL";
                                    lbAlarm.ForeColor = System.Drawing.Color.Green;
                                }
                            }
                            break;
                        case 1:         // WARNING
                            lbAlarm.Text = "WARNING";
                            lbAlarm.ForeColor = System.Drawing.Color.Orange;
                            break;
                        case 2:         // FAULT
                            lbAlarm.Text = "FAULT";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        case 3:         // WARMING UP
                            lbAlarm.Text = "WARMING UP";
                            lbAlarm.ForeColor = System.Drawing.Color.Black;
                            break;
                        case 4:         // FAULT (Anti-Theft GyroScope.)
                            lbAlarm.Text = "FAULT (GyroScope)";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        case 5:         // FAULT (Anti-Theft Gyro-Scope)
                            lbAlarm.Text = "FAULT (Comm)";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        default:
                            lbAlarm.Text = string.Format("UNKNOWN ({0})", SystemData[ModuleID - 1].StatusData.batteryStatus);
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                    }
                }
                else
                {
                    lbAlarm.Text = "COMM FAIL";
                    lbAlarm.ForeColor = System.Drawing.Color.Red;
                }
            }
            else
            {
                lbAlarm.Text = "OFF LINE";
                lbAlarm.ForeColor = System.Drawing.Color.Red;
            }
        }

        private void DisplayStatusStrRs485()
        {
            if (SystemData[ModuleID - 1].CommFail == false)
            {
                if (SystemData[ModuleID - 1].ShelfCommFail == false)
                {
                    if ((SystemData[ModuleID - 1].StatusData.batteryStatus == 4)
                        || (SystemData[ModuleID - 1].StatusData.batteryStatus == 5))
                    {
                        lbStatus.Text = "PWR-OFF";
                        lbStatus.ForeColor = Color.Red;
                    }
                    else if (SystemData[ModuleID - 1].StatusData.batteryStatus == 2)
                    {
                        lbStatus.Text = "TRIP";
                        lbStatus.ForeColor = Color.Red;
                    }
                    else
                    {
                        switch (SystemData[ModuleID - 1].StatusData.status)
                        {
                            case 0x0000:                // Stand by
                                lbStatus.Text = "STANDBY";
                                lbStatus.ForeColor = Color.Black;
                                break;
                            case 0x0001:                // Charging
                                lbStatus.Text = "CHARGING";
                                lbStatus.ForeColor = Color.Blue;
                                break;
                            case 0x0002:                // Discharging
                                lbStatus.Text = "DISCHARGING";
                                lbStatus.ForeColor = Color.Magenta;
                                break;
                            case 0x0003:                // Float Charging
                                lbStatus.Text = "FLOATING";
                                lbStatus.ForeColor = Color.Black;
                                break;
                            case 0x0004:                // Warming Up
                                lbStatus.Text = "WARMING UP";
                                lbStatus.ForeColor = Color.Black;
                                break;
                            default:
                                lbStatus.Text = string.Format("UNKNOWN({0})", SystemData[ModuleID - 1].StatusData.status);
                                lbStatus.ForeColor = Color.Black;
                                break;
                        }
                    }
                }
                else
                {
                    lbStatus.Text = "COMM FAIL";
                    lbStatus.ForeColor = Color.Red;
                }
            }
            else
            {
                lbStatus.Text = "OFF LINE";
                lbStatus.ForeColor = Color.Red;
            }
        }

        private void DisplayAlarmStrRs485()
        {
            if (SystemData[ModuleID - 1].CommFail == false)
            {
                if (SystemData[ModuleID - 1].ShelfCommFail == false)
                {
                    switch (SystemData[ModuleID - 1].StatusData.batteryStatus)
                    {
                        case 0:         // NORMAL
                            lbAlarm.Text = "NORMAL";
                            lbAlarm.ForeColor = System.Drawing.Color.Green;
                            break;
                        case 1:         // WARNING
                            lbAlarm.Text = "WARNING";
                            lbAlarm.ForeColor = System.Drawing.Color.Orange;
                            break;
                        case 2:         // FAULT
                            lbAlarm.Text = "FAULT";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        case 3:         // WARMING UP
                            lbAlarm.Text = "WARMING UP";
                            lbAlarm.ForeColor = System.Drawing.Color.Black;
                            break;
                        case 4:         // FAULT (Anti-Theft GyroScope.)
                            lbAlarm.Text = "FAULT (GyroScope)";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        case 5:         // FAULT (Anti-Theft Gyro-Scope)
                            lbAlarm.Text = "FAULT (Comm)";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        default:
                            lbAlarm.Text = string.Format("UNKNOWN ({0})", SystemData[ModuleID - 1].StatusData.batteryStatus);
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                    }
                }
                else
                {
                    lbAlarm.Text = "COMM FAIL";
                    lbAlarm.ForeColor = System.Drawing.Color.Red;
                }
            }
            else
            {
                lbAlarm.Text = "OFF LINE";
                lbAlarm.ForeColor = System.Drawing.Color.Red;
            }
        }

        private void DisplayStatusStrSnmp()
        {
            if (SystemData[0].CommFail == false)
            {
                if (SystemData[0].ShelfCommFail == false)
                {
                    if ((SystemData[0].StatusData.batteryStatus == 4)
                        || (SystemData[0].StatusData.batteryStatus == 5))
                    {
                        lbStatus.Text = "PWR-OFF";
                        lbStatus.ForeColor = Color.Red;
                    }
                    else
                    {
                        switch (SystemData[0].StatusData.status)
                        {
                            case 0x0000:                // Stand by
                                lbStatus.Text = "STANDBY";
                                lbStatus.ForeColor = Color.Black;
                                break;
                            case 0x0001:                // Charging
                                lbStatus.Text = "CHARGING";
                                lbStatus.ForeColor = Color.Blue;
                                break;
                            case 0x0002:                // Discharging
                                lbStatus.Text = "DISCHARGING";
                                lbStatus.ForeColor = Color.Magenta;
                                break;
                            case 0x0004:                // PROTECT
                                lbStatus.Text = "TRIP";
                                lbStatus.ForeColor = Color.Red;
                                break;
                            case 0x0008:                // Charging Lmt
                                lbStatus.Text = "CHG-LIMIT";
                                lbStatus.ForeColor = Color.Blue;
                                break;
                            default:
                                lbStatus.Text = "UNKNOWN";
                                lbStatus.ForeColor = Color.Black;
                                break;
                        }
                    }
                }
                else
                {
                    lbStatus.Text = "COMM FAIL";
                    lbStatus.ForeColor = Color.Red;
                }
            }
            else
            {
                lbStatus.Text = "OFF LINE";
                lbStatus.ForeColor = Color.Red;
            }
        }

        private void DisplayAlarmStrSnmp()
        {
            if (SystemData[0].CommFail == false)
            {
                if (SystemData[0].ShelfCommFail == false)
                {
                    switch (SystemData[0].StatusData.batteryStatus)
                    {
                        case 0:         // NORMAL
                            lbAlarm.Text = "NORMAL";
                            lbAlarm.ForeColor = System.Drawing.Color.Green;
                            break;
                        case 1:         // WARNING
                            lbAlarm.Text = "WARNING";
                            lbAlarm.ForeColor = System.Drawing.Color.Orange;
                            break;
                        case 2:         // FAULT
                            lbAlarm.Text = "FAULT";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        case 3:         // WARMING UP
                            lbAlarm.Text = "WARMING UP";
                            lbAlarm.ForeColor = System.Drawing.Color.Black;
                            break;
                        case 4:         // FAULT (Anti-Theft GyroScope.)
                            lbAlarm.Text = "FAULT (GyroScope)";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        case 5:         // FAULT (Anti-Theft Gyro-Scope)
                            lbAlarm.Text = "FAULT (Comm)";
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                        default:
                            lbAlarm.Text = string.Format("UNKNOWN ({0})", SystemData[0].StatusData.batteryStatus);
                            lbAlarm.ForeColor = System.Drawing.Color.Red;
                            break;
                    }
                }
                else
                {
                    lbAlarm.Text = "COMM FAIL";
                    lbAlarm.ForeColor = System.Drawing.Color.Red;
                }
            }
            else
            {
                lbAlarm.Text = "OFF LINE";
                lbAlarm.ForeColor = System.Drawing.Color.Red;
            }
        }

        private void DisplayAlarmUart()
        {
            bool[] aFault = csUtils.Int16ToBitArray(SystemData[ModuleID - 1].StatusData.protection);
            bool[] aWarining = csUtils.Int16ToBitArray(SystemData[ModuleID - 1].StatusData.warning);
            bool aCommfail;

            switch (Config.CommType)
            {
                case csConstData.CommType.COMM_UART:
                    aCommfail = SystemData[ModuleID - 1].ShelfCommFail;
                    break;
                case csConstData.CommType.COMM_RS485:
                    aCommfail = SystemData[ModuleID - 1].ShelfCommFail;
                    break;
                case csConstData.CommType.COMM_SNMP:
                    aCommfail = SystemData[ModuleID - 1].CommFail;
                    break;
                default:
                    break;
            }

            for (int i = 0; i < 8; i++)
            {
                if (aFault[i] == true)
                    alarmTrip[i].SetValue(2);
                else if (aWarining[i] == true)
                    alarmTrip[i].SetValue(1);
                else
                    alarmTrip[i].SetValue(0);

                // Charge Over Current protect
                if (i == 6)
                {
                    if ((aFault[i] == true) && (aFault[i]))
                        alarmTrip[i].SetValue(2);
                    else if (aWarining[i] == true)
                        alarmTrip[i].SetValue(1);
                    else
                        alarmTrip[i].SetValue(0);
                }
            }

            // Cell Voltage Difference
            if (aFault[9] == true)
            {
                alarmTrip[9].SetName("Cell Volt Diff");
                alarmTrip[9].SetValue(2);
            }
            else if (aWarining[9] == true)
            {
                alarmTrip[9].SetName("Cell Volt Diff");
                alarmTrip[9].SetValue(1);
            }
            else
            {
                if ((SystemData[ModuleID - 1].StatusData.specialAlarm & 0x0004) != 0)
                {
                    alarmTrip[9].SetName("CB OFF");
                    alarmTrip[9].SetValue(1);
                }
                else
                {
                    alarmTrip[9].SetName("ETC. Alarm");
                    alarmTrip[9].SetValue(0);
                }
            }

            // Low SOC
            if (aWarining[11] == true)
                alarmTrip[8].SetValue(1);
            else
                alarmTrip[8].SetValue(0);
        }

        private void DisplayAlarmUart124050()
        {
            bool[] aFault = csUtils.Int16ToBitArray(SystemData[ModuleID - 1].StatusData.protection);
            bool[] aWarining = csUtils.Int16ToBitArray(SystemData[ModuleID - 1].StatusData.warning);
            bool aCommfail;

            aCommfail = SystemData[ModuleID - 1].ShelfCommFail;

            for (int i = 0; i < 8; i++)
            {
                if (aFault[i] == true)
                    alarmTrip[i].SetValue(2);
                else if (aWarining[i] == true)
                    alarmTrip[i].SetValue(1);
                else
                    alarmTrip[i].SetValue(0);

                // Charge Over Current protect
                if (i == 6)
                {
                    if ((aFault[i] == true) && (aFault[i]))
                        alarmTrip[i].SetValue(2);
                    else if (aWarining[i] == true)
                        alarmTrip[i].SetValue(1);
                    else
                        alarmTrip[i].SetValue(0);
                }
            }

            // Cell Voltage Difference
            if (aFault[9] == true)
            {
                alarmTrip[9].SetName("Cell Volt Diff");
                alarmTrip[9].SetValue(2);
            }
            else if (aWarining[9] == true)
            {
                alarmTrip[9].SetName("Cell Volt Diff");
                alarmTrip[9].SetValue(1);
            }
            else
            {
                if ((SystemData[ModuleID - 1].StatusData.specialAlarm & 0x4000) != 0)
                {
                    alarmTrip[9].SetName("CB OFF");
                    alarmTrip[9].SetValue(1);
                }
                else
                {
                    alarmTrip[9].SetName("ETC. Alarm");
                    alarmTrip[9].SetValue(0);
                }
            }

            // Low SOC
            if (aWarining[11] == true)
                alarmTrip[8].SetValue(1);
            else
                alarmTrip[8].SetValue(0);
        }

        private void DisplayAlarmRs485()
        {
            bool[] aFault = csUtils.Int16ToBitArray(SystemData[ModuleID - 1].StatusData.protection);
            bool[] aWarining = csUtils.Int16ToBitArray(SystemData[ModuleID - 1].StatusData.warning);
            bool aCommfail;

            if (Config.ModuleQty == 1)
            {
                aCommfail = SystemData[ModuleID - 1].ShelfCommFail;
            }
            else
            {
                aCommfail = SystemData[ModuleID - 1].CommFail;
            }

            for (int i = 0; i < 8; i++)
            {
                if (aFault[i] == true)
                    alarmTrip[i].SetValue(2);
                else if (aWarining[i] == true)
                    alarmTrip[i].SetValue(1);
                else
                    alarmTrip[i].SetValue(0);

                // Charge Over Current protect
                if (i == 6)
                {
                    if ((aFault[i] == true) && (aFault[i]))
                        alarmTrip[i].SetValue(2);
                    else if (aWarining[i] == true)
                        alarmTrip[i].SetValue(1);
                    else
                        alarmTrip[i].SetValue(0);
                }
            }

            // Low SOC
            if (aWarining[11] == true)
                alarmTrip[8].SetValue(1);
            else
                alarmTrip[8].SetValue(0);

            // Cell Voltage Difference
            // Cell ETC. Alarm
            if (aFault[8] == true)
            {
                // Short Circuit Protect
                alarmTrip[9].SetName("Short Circuit");
                alarmTrip[9].SetValue(2);
            }
            else if (aWarining[9] == true)
            {
                alarmTrip[9].SetName("Cell Volt Diff");
                alarmTrip[9].SetValue(1);
            }
            else if (aWarining[13] == true)
            {
                alarmTrip[9].SetName("CB OFF");
                alarmTrip[9].SetValue(1);
            }
            else if (aWarining[14] == true)
            {
                alarmTrip[9].SetName("ENV OT");
                alarmTrip[9].SetValue(1);
            }
            else if (aWarining[15] == true)
            {
                alarmTrip[9].SetName("ENV UT");
                alarmTrip[9].SetValue(1);
            }
            else
            {
                alarmTrip[9].SetName("ETC. Alarm");
                alarmTrip[9].SetValue(0);
            }
        }

        private void DisplayAlarmSnmp()
        {
            bool[] aFault = csUtils.Int16ToBitArray(SystemData[0].StatusData.protection);
            bool[] aWarining = csUtils.Int16ToBitArray(SystemData[0].StatusData.warning);
            bool aCommfail;

            if (Config.CommType == 0)
            {
                aCommfail = SystemData[0].ShelfCommFail;
            }
            else
            {
                aCommfail = SystemData[0].CommFail;
            }

            for (int i = 0; i < 8; i++)
            {
                if (aFault[i] == true)
                    alarmTrip[i].SetValue(2);
                else if (aWarining[i] == true)
                    alarmTrip[i].SetValue(1);
                else
                    alarmTrip[i].SetValue(0);

                // Charge Over Current protect
                if (i == 6)
                {
                    if ((aFault[i] == true) && (aFault[i]))
                        alarmTrip[i].SetValue(2);
                    else if (aWarining[i] == true)
                        alarmTrip[i].SetValue(1);
                    else
                        alarmTrip[i].SetValue(0);
                }
            }

            // Low SOC
            if (aWarining[11] == true) { alarmTrip[8].SetValue(1); }
            else                       { alarmTrip[8].SetValue(0); }

            // ETC. Alarm
            if (aFault[9] == true)
            {
                // Short Circuit Protect
                alarmTrip[9].SetName("Short Circuit");
                alarmTrip[9].SetValue(2);
            }
            else if (aWarining[13] == true)
            {
                // Cell Voltage Diff
                alarmTrip[9].SetName("Cell Volt Diff");
                alarmTrip[9].SetValue(1);
            }
            else if (aWarining[14] == true)
            {
                // Circuit Breaker Off
                alarmTrip[9].SetName("CB OFF");
                alarmTrip[9].SetValue(1);
            }
            else if (aWarining[8] == true)
            {
                alarmTrip[9].SetName("ENV OT");
                alarmTrip[9].SetValue(1);
            }
            else if (aWarining[9] == true)
            {
                alarmTrip[9].SetName("ENV UT");
                alarmTrip[9].SetValue(1);
            }
            else
            {
                alarmTrip[9].SetName("ETC. Alarm");
                alarmTrip[9].SetValue(0);
            }
        }

        #endregion

        #region BUTTON EVENT

        private void btnParam_Click(object sender, EventArgs e)
        {
            switch (Config.CommType)
            {
                case csConstData.CommType.COMM_UART:
                    foreach (Form frm in Application.OpenForms)
                    {
                        if (frm.Name == "fmxParamConfig")
                        {
                            frm.Activate();
                            return;
                        }
                    }
                    fmxParamConfig ParamConfigForm = new fmxParamConfig(ModuleID, Config, SystemData[ModuleID - 1].ParamData);

                    ParamConfigForm.OnUpdate += UpdateParam;
                    ParamConfigForm.OnCommand += ParamSetCmd;
                    ParamConfigForm.Show();
                    break;
                case csConstData.CommType.COMM_RS485:
                    FmxInformation InformationForm1 = new FmxInformation(ModuleID, Config, ref SystemData[ModuleID - 1]);

                    InformationForm1.ShowDialog();
                    break;
                case csConstData.CommType.COMM_SNMP:
                    FmxInformation InformationForm2 = new FmxInformation(ModuleID, Config, ref SystemData[ModuleID - 1]);

                    InformationForm2.ShowDialog();
                    break;
                default:
                    break;
            }
        }

        private void btnCalibration_Click(object sender, EventArgs e)
        {
            switch (Config.CommType)
            {
                case csConstData.CommType.COMM_UART:
                    fmxCalibration CalibrationForm = 
                        new fmxCalibration(ModuleID, Config, SystemData[ModuleID - 1].ParamData, SystemData[ModuleID - 1].CalibrationData);

                    CalibrationForm.OnUpdate += UpdateCalibration;
                    CalibrationForm.OnCommand += ParamSetCmd;
                    CalibrationForm.ShowDialog();
                    break;
                case csConstData.CommType.COMM_RS485:
                    fmxAntiTheft AntiTheftForm = new fmxAntiTheft(ModuleID, SystemData[ModuleID - 1].CalibrationData);

                    AntiTheftForm.OnUpdate += UpdateCalibrationRS485;
                    AntiTheftForm.OnCommand += AntiTheftSetCmd;  // OnSendUartData
                    AntiTheftForm.OnSendUartData += OnSendUartData;
                    AntiTheftForm.ShowDialog();
                    break;
                case csConstData.CommType.COMM_SNMP:
                    break;
            }
        }

        #endregion

        #region CONTROL EVENT FUNCTION

        private void UpdateParam(object sendor)
        {
            ((fmxParamConfig)sendor).UpdateData(SystemData[ModuleID - 1].ParamData, SystemData[ModuleID - 1].CalibrationData);
        }

        private void UpdateCalibration(object sendor)
        {
            ((fmxCalibration)sendor).UpdateData(SystemData[ModuleID - 1].ParamData, SystemData[ModuleID - 1].CalibrationData, SystemData[ModuleID - 1]);
        }

        private void UpdateCalibrationRS485(object sendor)
        {
            ((fmxAntiTheft)sendor).UpdateData(SystemData[ModuleID - 1].ParamData, SystemData[ModuleID - 1].CalibrationData, SystemData[ModuleID - 1]);
        }

        private void ParamSetCmd(int mID, int mode, int index, int flag, ref DeviceParamData aParam, ref DeviceCalibration aCalib)
        {
            OnCommand?.Invoke(mID, mode, index, flag, ref aParam, ref aCalib);
        }

        // RS485 Control Function
        private void AntiTheftSetCmd(int mID, int mode, int index, int flag, ref DeviceParamData aParam, ref DeviceCalibration aCalib)
        {
            OnCommand?.Invoke(mID, mode, index, flag, ref aParam, ref aCalib);
        }

        #endregion
    }
}
