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

using LFP_Manager.DataStructure;
using LFP_Manager.Function;
using LFP_Manager.Controls;

namespace LFP_Manager.Forms
{
    public partial class fmxParamConfig : DevExpress.XtraEditors.XtraForm
    {
        #region DELEGATE
        public delegate void ParamUpdateEvent(object sendor);
        public delegate void ParamCmdEvent(int sId, int mode, int index, int flag, ref DeviceParamData aParam, ref DeviceCalibration aCalib);
        #endregion

        #region VARIABLES

        private int SystemId = 0;
        private CommConfig Config = null;
        private DeviceParamData Param;
        private DeviceCalibration Calib;

        private ucParamSet[] ParamSet = null;

        private int PasswordResult = 0;

        public event ParamUpdateEvent OnUpdate = null;
        public event ParamCmdEvent OnCommand = null;

        #endregion

        #region CONSTRUCTORS

        public fmxParamConfig()
        {
            InitializeComponent();
        }

        public fmxParamConfig(int sId, CommConfig aConfig, DeviceParamData aParam)
        {
            InitializeComponent();

            Config = aConfig;
            SystemId = sId;
            Param = aParam;

            InitComponent();

            gbVoltageParamSet.Text = "Parameter Config";
            
            tmrDisplay.Enabled = true;
        }

        public void InitComponent()
        {
            ParamSet = new ucParamSet[11];


            // Cell Voltage Parameter
            ParamSet[0] = ucCOVParam;
            ParamSet[0].SetParamName(0, "Cell Over Voltage");
            ParamSet[0].SetParamName(1, "mV");
            ParamSet[0].SetId(0);
            ParamSet[0].OnCommand += OnCmdEvent;

            ParamSet[1] = ucCUVParam;
            ParamSet[1].SetParamName(0, "Cell Under Voltage");
            ParamSet[1].SetParamName(1, "mV");
            ParamSet[1].SetId(1);
            ParamSet[1].OnCommand += OnCmdEvent;
            //ucCUVParam.EnableItem(0, false);

            // System Voltage Parameter
            ParamSet[2] = ucSOVParam;
            ParamSet[2].SetParamName(0, "System Over Voltage");
            ParamSet[2].SetParamName(1, "V");
            ParamSet[2].SetId(2);
            ParamSet[2].OnCommand += OnCmdEvent;

            ParamSet[3] = ucSUVParam;
            ParamSet[3].SetParamName(0, "System Under Voltage");
            ParamSet[3].SetParamName(1, "V");
            ParamSet[3].SetId(3);
            ParamSet[3].OnCommand += OnCmdEvent;
            //ucSUVParam.EnableItem(0, false);

            // Charge Temperature Parameter
            ParamSet[4] = ucCHTParam;
            ParamSet[4].SetParamName(0, "Charge High Temp");
            ParamSet[4].SetParamName(1, "C");
            ParamSet[4].SetId(4);
            ParamSet[4].OnCommand += OnCmdEvent;

            ParamSet[5] = ucCLTParam;
            ParamSet[5].SetParamName(0, "Charge Low Temp");
            ParamSet[5].SetParamName(1, "C");
            ParamSet[5].SetId(5);
            ParamSet[5].OnCommand += OnCmdEvent;

            // Discharge Temperature Parameter
            ParamSet[6] = ucDHTParam;
            ParamSet[6].SetParamName(0, "Discharge High Temp");
            ParamSet[6].SetParamName(1, "C");
            ParamSet[6].SetId(6);
            ParamSet[6].OnCommand += OnCmdEvent;
            //ucDHTParam.EnableItem(0, false);

            ParamSet[7] = ucDLTParam;
            ParamSet[7].SetParamName(0, "Discharge Low Temp");
            ParamSet[7].SetParamName(1, "C");
            ParamSet[7].SetId(7);
            ParamSet[7].OnCommand += OnCmdEvent;
            //ucDLTParam.EnableItem(0, false);

            // Over Current Parameter
            ParamSet[8] = ucCOCParam;
            ParamSet[8].SetParamName(0, "Charge Over Current");
            ParamSet[8].SetParamName(1, "A");
            ParamSet[8].SetId(8);
            ParamSet[8].OnCommand += OnCmdEvent;
            //ucCOCParam.EnableItem(2, false);

            ParamSet[9] = ucDOCParam;
            ParamSet[9].SetParamName(0, "Discharge Over Current");
            ParamSet[9].SetParamName(1, "A");
            ParamSet[9].SetId(9);
            ParamSet[9].OnCommand += OnCmdEvent;
            //ucDOCParam.EnableItem(2, false);

            // Low Capacity Parameter
            ParamSet[10] = ucSocParam;
            ParamSet[10].SetParamName(0, "SOC");
            ParamSet[10].SetParamName(1, "%");
            ParamSet[10].SetId(10);
            ParamSet[10].OnCommand += OnCmdEvent;
            ParamSet[10].VisibleItem(0, false);
            ParamSet[10].VisibleItem(2, false);
        }

        #endregion

        #region COMMAND EVENT

        private void OnCmdEvent(int mode, int flag, ParamData aParam)
        {
            int cmd = 0;
            DeviceParamData wParam = Param.DeepCopy();

            switch (mode)
            {
                case 0:                 // Cell Over Voltage
                    cmd = csConstData.UART_PARAM_LIST.CELL_OVER_VOLTAGE;
                    wParam.CellOverVoltageTrip = aParam.Fault;
                    wParam.CellOverVoltageWarning = aParam.Warning;
                    wParam.CellOverVoltageRelease = aParam.Release;
                    break;
                case 1:                 // Cell Under Voltage
                    cmd = csConstData.UART_PARAM_LIST.CELL_UNDER_VOLTAGE;
                    wParam.CellUnderVoltageTrip = aParam.Fault;
                    wParam.CellUnderVoltageWarning = aParam.Warning;
                    wParam.CellUnderVoltageRelease = aParam.Release;
                    break;
                case 2:                 // System Over Voltage
                    cmd = csConstData.UART_PARAM_LIST.PACK_OVER_VOLTAGE;
                    wParam.SysOverVoltageTrip = aParam.Fault;
                    wParam.SysOverVoltageWarning = aParam.Warning;
                    wParam.SysOverVoltageRelease = aParam.Release;
                    break;
                case 3:                 // System Under Voltage
                    cmd = csConstData.UART_PARAM_LIST.PACK_UNDER_VOLTAGE;
                    wParam.SysUnderVoltageTrip = aParam.Fault;
                    wParam.SysUnderVoltageWarning = aParam.Warning;
                    wParam.SysUnderVoltageRelease = aParam.Release;
                    break;
                case 4:                 // Charge High Temperature
                    cmd = csConstData.UART_PARAM_LIST.CHG_HIGH_TEMPERATURE;
                    wParam.ChaHighTempTrip = aParam.Fault;
                    wParam.ChaHighTempWarning = aParam.Warning;
                    wParam.ChaHighTempRelease = aParam.Release;
                    break;
                case 5:                 // Charge Low Temperature
                    cmd = csConstData.UART_PARAM_LIST.CHG_LOW_TEMPERATURE;
                    wParam.ChaLowTempTrip = aParam.Fault;
                    wParam.ChaLowTempWarning = aParam.Warning;
                    wParam.ChaLowTempRelease = aParam.Release;
                    break;
                case 6:                 // Discharge High Temperature
                    cmd = csConstData.UART_PARAM_LIST.DCH_HIGH_TEMPERATURE;
                    wParam.DchHighTempTrip = aParam.Fault;
                    wParam.DchHighTempWarning = aParam.Warning;
                    wParam.DchHighTempRelease = aParam.Release;
                    break;
                case 7:                 // Discharge Low Temperature
                    cmd = csConstData.UART_PARAM_LIST.DCH_LOW_TEMPERATURE;
                    wParam.DchLowTempTrip = aParam.Fault;
                    wParam.DchLowTempWarning = aParam.Warning;
                    wParam.DchLowTempRelease = aParam.Release;
                    break;
                case 8:                 // Charge Over Current
                    cmd = csConstData.UART_PARAM_LIST.CHG_OVER_CURRENT;
                    wParam.ChaOverCurrentTrip2 = aParam.Fault;
                    wParam.ChaOverCurrentTrip1 = aParam.Warning;
                    wParam.ChaOverCurrentReleaseTime = aParam.Release;
                    break;
                case 9:                 // Discharge Over Current
                    cmd = csConstData.UART_PARAM_LIST.DCH_OVER_CURRENT;
                    wParam.DchOverCurrentTrip2 = aParam.Fault;
                    wParam.DchOverCurrentTrip1 = aParam.Warning;
                    wParam.DchOverCurrentReleaseTime = aParam.Release;
                    break;
                case 10:
                    cmd = csConstData.UART_PARAM_LIST.LOW_CAPACITY;
                    wParam.LowSocTrip = aParam.Fault;
                    wParam.LowSocWarning = aParam.Warning;
                    wParam.LowSocRelease = aParam.Release;
                    break;
                case 16:                // Default Parameter
                    cmd = 0;
                    wParam.DefalutParamOption = aParam.Fault;
                    wParam.DefalutParamAll = aParam.Release;
                    break;
                case 0x2D:
                    wParam.ReadParamAll = 0x002D;
                    cmd = 0x2D;
                    break;
                case 99:
                    cmd = 200;           // All parameter read
                    break;
            }
            OnCommand?.Invoke(SystemId, cmd, 6, flag, ref wParam, ref Calib);
        }

        #endregion

        #region UPDATE DATA
        public void UpdateData(DeviceParamData aParam, DeviceCalibration aCalib)
        {
            Param = aParam;
            Calib = aCalib;
        }
        #endregion

        #region TIMER EVENT
        private void tmrDisplay_Tick(object sender, EventArgs e)
        {
            DisplayValue();

            OnUpdate?.Invoke(this);
        }
        #endregion

        private void DisplayValue()
        {
            ParamData pData = new ParamData();

            // Cell Voltage Parameter
            pData.Fault = Param.CellOverVoltageTrip;
            pData.Warning = Param.CellOverVoltageWarning;
            pData.Release = Param.CellOverVoltageRelease;
            ucCOVParam.UpdateData(pData);

            pData.Fault = Param.CellUnderVoltageTrip;
            pData.Warning = Param.CellUnderVoltageWarning;
            pData.Release = Param.CellUnderVoltageRelease;
            ucCUVParam.UpdateData(pData);

            // System Voltage Parameter
            pData.Fault = Param.SysOverVoltageTrip;
            pData.Warning = Param.SysOverVoltageWarning;
            pData.Release = Param.SysOverVoltageRelease;
            ucSOVParam.UpdateData(pData);

            pData.Fault = Param.SysUnderVoltageTrip;
            pData.Warning = Param.SysUnderVoltageWarning;
            pData.Release = Param.SysUnderVoltageRelease;
            ucSUVParam.UpdateData(pData);

            // Charge Temp Parameter
            pData.Fault = Param.ChaHighTempTrip;
            pData.Warning = Param.ChaHighTempWarning;
            pData.Release = Param.ChaHighTempRelease;
            ucCHTParam.UpdateData(pData);

            pData.Fault = Param.ChaLowTempTrip;
            pData.Warning = Param.ChaLowTempWarning;
            pData.Release = Param.ChaLowTempRelease;
            ucCLTParam.UpdateData(pData);

            // Discharge Temp Parameter
            pData.Fault = Param.DchHighTempTrip;
            pData.Warning = Param.DchHighTempWarning;
            pData.Release = Param.DchHighTempRelease;
            ucDHTParam.UpdateData(pData);

            pData.Fault = Param.DchLowTempTrip;
            pData.Warning = Param.DchLowTempWarning;
            pData.Release = Param.DchLowTempRelease;
            ucDLTParam.UpdateData(pData);

            // Charge Over Current
            pData.Fault = Param.ChaOverCurrentTrip2;
            pData.Warning = Param.ChaOverCurrentTrip1;
            pData.Release = Param.ChaOverCurrentReleaseTime;
            ucCOCParam.UpdateData(pData);

            // Discharge Over Current
            pData.Fault = Param.DchOverCurrentTrip2;
            pData.Warning = Param.DchOverCurrentTrip1;
            pData.Release = Param.DchOverCurrentReleaseTime;
            ucDOCParam.UpdateData(pData);

            // SOC Parameter
            pData.Fault = Param.LowSocTrip;
            pData.Warning = Param.LowSocWarning;
            pData.Release = Param.LowSocRelease;
            ucSocParam.UpdateData(pData);
        }

        #region BUTTON EVENT
        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnGetAll_Click(object sender, EventArgs e)
        {
            ParamData aa = new ParamData();
            OnCmdEvent(0x2D, 0, aa);
        }

        private void btnDefaultSet_Click(object sender, EventArgs e)
        {
            ParamData aa = new ParamData();

            OnCmdEvent(16, 1, aa);

            //DefaultTempAlarm();
        }
        #endregion

        #region FORM EVENT
        private void fmxParamConfig_Load(object sender, EventArgs e)
        {
            ParamConfig_ReLoad();
        }

        private void ParamConfig_ReLoad()
        {
            switch (Config.ControlLevel)
            {
                case 0:         // User Level
                    for (int i = 0; i < ParamSet.Length; i++)
                    {
                        ParamSet[i].EnableDisableSetBtn(false);
                    }
                    btnDefaultSet.Enabled = false;
                    break;
                case 1:         // Technician Level
                    for (int i = 0; i < ParamSet.Length; i++)
                    {
                        ParamSet[i].EnableDisableSetBtn(false);
                    }
                    btnDefaultSet.Enabled = false;
                    break;
                case 2:         // Engineer Level
                    for (int i = 0; i < ParamSet.Length; i++)
                    {
                        ParamSet[i].EnableDisableSetBtn(true);
                    }
                    btnDefaultSet.Enabled = true;
                    break;
                case 3:         // Master Level
                    for (int i = 0; i < ParamSet.Length; i++)
                    {
                        ParamSet[i].EnableDisableSetBtn(true);
                    }
                    btnDefaultSet.Enabled = true;
                    break;
                default:        // User Level
                    for (int i = 0; i < ParamSet.Length; i++)
                    {
                        ParamSet[i].EnableDisableSetBtn(false);
                    }
                    btnDefaultSet.Enabled = false;
                    break;
            }
        }
        #endregion

    }
}