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

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

namespace LFP_Manager.Forms
{
    public delegate void InvDataUpdateEvent(object sendor);
    public delegate void InvDateCmdEvent(int sId, int mode, int index, int flag, 
        ref CsDeviceData.DeviceModuleData.DeviceInforation wData);
    public delegate void InvDateCmdEventBySnmp(int mode, string wData);

    public partial class fmxInventoryConfig : DevExpress.XtraEditors.XtraForm
    {
        #region VARIABLES

        int SystemId = 0;
        int CmdResult = 0;
        CommConfig Config;
        CsDeviceData.DeviceModuleData ModuleData;
        DeviceInforation wInvData;

        public event InvDataUpdateEvent OnUpdate = null;
        public event InvDateCmdEvent OnCommand = null;

        public event SendDataUartEvent OnSendUartData = null;

        #endregion

        #region CONSTRUCTORS
        public fmxInventoryConfig()
        {
            InitializeComponent();
        }
        public fmxInventoryConfig(int sId, ref CommConfig aConfig, ref CsDeviceData.DeviceModuleData mData)
        {
            InitializeComponent();

            SystemId = sId;
            ModuleData = mData;
            Config = aConfig;

            switch (Config.CommType)
            {
                case csConstData.CommType.COMM_UART:
                    nManuDate.Enabled = true;
                    BtnManuDateWrite.Enabled = true;
                    nSerialNo.Enabled = true;
                    BtnSerialNoWrite.Enabled = true;
                    break;
                case csConstData.CommType.COMM_RS485:
                    nManuDate.Enabled = false;
                    BtnManuDateWrite.Enabled = false;
                    nSerialNo.Enabled = false;
                    BtnSerialNoWrite.Enabled = false;
                    break;
                case csConstData.CommType.COMM_SNMP:
                    nManuDate.Enabled = false;
                    BtnManuDateWrite.Enabled = false;
                    nSerialNo.Enabled = false;
                    BtnSerialNoWrite.Enabled = false;
                    break;
                default:
                    break;
            }

            tmrDisplay.Enabled = true;
        }
        #endregion

        #region INIT DATA
        void InitData()
        {
            wInvData = new DeviceInforation
            {
                BMS_SN = new byte[16],
                Module_SN = new byte[24]
            };          //22.06.30 Byul 32->16, 32->24
        }
        #endregion

        #region DISPLAY DATA

        private void DisplayValue()
        {
            // Manufacture Date
            lbMDate.Text = String.Format("Manufacture Date: {0}", ModuleData.Information.ManufacturingDate);

            // Device Address%
            lbSerialNo.Text = String.Format("Serial No: {0}", ModuleData.Information.HwSerialNumber);
        }
        #endregion

        #region TIMER ENVENT
        private void tmrDisplay_Tick(object sender, EventArgs e)
        {
            DisplayValue();
            if (OnUpdate != null)
            {
                OnUpdate(this);
            }
        }
        #endregion

        #region PUBLIC FUCTIONS
        public void UpdateData(ref CsDeviceData.DeviceModuleData mData)
        {
            ModuleData = mData;
        }

        public void RecvData(string result, bool error)
        {
            Cmd_Result(result, error);
        }

        public void Cmd_Result(string result, bool error)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(delegate ()
                {
                    if (error)
                        MessageBox.Show(result, "Result", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    else
                        MessageBox.Show(result, "Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }));
            }
            else
            {
                if (error)
                    MessageBox.Show(result, "Result", MessageBoxButtons.OK, MessageBoxIcon.Error);
                else
                    MessageBox.Show(result, "Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        #endregion

        #region BUTTON EVENT

        private void btnClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void BtnManuDateWrite_Click(object sender, EventArgs e)
        {
            if ((nManuDate.Text == "") || (nManuDate.Text.Length > 8))
            {
                MessageBox.Show("Check Manufacture Date Format", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            byte[] crc;
            ushort addr = 0x00A3;
            int i = 0;
            // Normal mode --> Bootloader mode
            byte[] sdata = new byte[7 + 8 + 2];
            sdata[i++] = (byte)SystemId;         // Dev Address
            sdata[i++] = 0x10;         // Function Code
            sdata[i++] = (byte)(addr >> 8);         // Address H
            sdata[i++] = (byte)(addr >> 0);         // Address L
            sdata[i++] = 0x00;         // Number of Register H
            sdata[i++] = 0x04;         // Number of Register L
            sdata[i++] = 0x08;         // Byte Count

            string str = nManuDate.Text;
            byte[] aData = Encoding.UTF8.GetBytes(str);

            for (int j = 0; j < 8; j++)
            {
                sdata[i++] = aData[j];
            }
            crc = csSerialCommFunction.GetCRC(sdata, i);

            sdata[i++] = crc[1];         // CRCH
            sdata[i++] = crc[0];         // CRCL

            OnSendUartData?.Invoke(addr, sdata, false, 1);
        }

        private void BtnSerialNoWrite_Click(object sender, EventArgs e)
        {
            if ((nSerialNo.Text == "") || (nSerialNo.Text.Length > 16))
            {
                MessageBox.Show("Check Serial Number format", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            byte[] crc;
            ushort addr = 0x0078;
            int i = 0;
            // Normal mode --> Bootloader mode
            byte[] sdata = new byte[7 + 16 + 2];
            sdata[i++] = (byte)SystemId;         // Dev Address
            sdata[i++] = 0x10;         // Function Code
            sdata[i++] = (byte)(addr >> 8);         // Address H
            sdata[i++] = (byte)(addr >> 0);         // Address L
            sdata[i++] = 0x00;         // Number of Register H
            sdata[i++] = 0x08;         // Number of Register L
            sdata[i++] = 0x10;         // Byte Count

            string str = nSerialNo.Text;
            byte[] aData = Encoding.UTF8.GetBytes(str);

            for (int j = 0; j < aData.Length; j++)
            {
                sdata[i + j] = aData[j];
            }
            i += 16;
            crc = csSerialCommFunction.GetCRC(sdata, i);

            sdata[i++] = crc[1];         // CRCH
            sdata[i++] = crc[0];         // CRCL

            OnSendUartData?.Invoke(addr, sdata, false, 1);
        }

        #endregion
    }
}