using Jdas_Mbic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Jdas_Mbic
{
    class Data_Handler
    {
        //FileDownload fileDownload;
        Update_Serial fileDownload;
        const byte Terminal_Controller_Update_Ack = 0x11;
        const byte Terminal_Controller_Update_Nak = 0x22;
        const byte Terminal_Controller_FirmwareUpdateLen = 250;
        const byte Terminal_Reset = 0x0A;
        const byte Terminal_BootStart = 0x0B;
        public enum MBIC_Download_Req_L
        {
            MBIC_Notice_REQ = 0x10,
            MBIC_Download_DATA_REQ,
            MBIC_Download_Confirm_REQ,
            MBIC_Complete_Notice_REQ_REQ,
            MBIC_Reboot_Notice_REQ,
        };
        public enum MBIC_Download_Rsp_L
        {
            MBIC_Notice_RSP = 0x90,
            MBIC_Download_DATA_RSP,
            MBIC_Download_Confirm_RSP,
            MBIC_Complete_Notice_RSP,
            MBIC_Reboot_Notice_RSP,
        };

        public Boolean HeaderCheck(byte[] data)
        {
            Boolean ret = false;

            if(data[0] == 0xbe)
            {
                ret = true;
            }
            return ret;
        }

        public Boolean MBIC_HeaderCheck(byte[] data)
        {
            Boolean ret = false;
            try
            {
                if (data[0] == 0x16
                    && data[1] == 0x16
                    && data[2] == 0x16
                    && data[3] == 0x16)
                {
                    ret = true;
                }
            }
            catch { }

            return ret;
        }
        public bool CrcCheck(byte[] data)
        {
            bool ret = false;
            Crc16 crc = new Crc16();
           /* byte[] temp ={
                0xBE,0x77,0x01,0x5C,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x01,0xFF,0xE2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x0F,0x00,0x0F,0x00,0x34,0x02,0x17,0x01,0xD3,0x01,0x39,0x02,0x1A,0x1D,0x00,0x00,0xFF,0xC7,0xFF,0xC7,0xFF,0x81,0xFF,0xAB,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0xFE,0xD4,0xFF,0xEC,0xFF,0x2E,0xFF,0xD8,0xFF,0xE2,0xFF,0xCE,0xFF,0xF1,0xFF,0xE2,0xFF,0xE2,0x00,0x00,0x00,0x00,0x00,0xFF,0xCE,0xFF,0x38,0x00,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x02,0x06,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x20,0x20,0x01,0x00,0x20,0x85,0x20,0x20,0x20,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x9C,0x9C,0x01,0xFF,0xE2,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF6,0xCF,0xEB
            };*/
            UInt16 length,Crcdata = 0;
            try
            {
                length = (UInt16)((data[2] << 8) | data[3]);
            }
            catch
            {
                return ret;
            }
            try
            {
                Crcdata = Convert.ToUInt16((data[length + 1] << 8) | (data[length + 2]));
                //length = (UInt16)((temp[2] << 8) | temp[3]);
                //ret = crc.CRC16_Check(temp, length, Crcdata);
                ret = crc.CRC16_Check(data,length, Crcdata);
            }
            catch(Exception e)
            {
                return ret;
            }
            return ret;
        }
        public bool MBIC_CrcCheck(byte[] data)
        {
            bool ret = false;
            Crc16 crc = new Crc16();
            byte length, crcindex;
            try
            {
                length = data[2];
            }
            catch
            {
                return ret;
            }
            crcindex = (byte)(length + 1);
            try
            {
                ret = crc.CRC16_Check(data, length, data[crcindex]);
            }
            catch (Exception e)
            {
                return ret;
            }
            return ret;
        }
        // 바이트 배열을 String으로 변환 
        private string ByteToString(byte[] strByte)
        {
            string str = Encoding.Default.GetString(strByte);
            return str;
        }
        // String을 바이트 배열로 변환 
        private byte[] StringToByte(string str)
        {
            byte[] StrByte = Encoding.UTF8.GetBytes(str);
            return StrByte;
        }
        JdasMbic main_Form; //= new Main_Form();
        Serial serial;
        
        public void Recv_dataCheck(object serial,object main_form, object fileDownload, byte[] data)
        {
            Crc16 crc = new Crc16();
            Boolean DataCheck;
            Bluecell_BootProtocol bluecell_BootProtocol = new Bluecell_BootProtocol();

            this.serial = (Serial)serial;
            this.main_Form = (JdasMbic)main_form;
            byte seq,cmd;
            UInt16 CRCRET = 0;
            int Length = 0;
            int LastFrame = 0;
            ushort  crcret = 0;
            byte[] datatmp = new byte[100];
            DataCheck = MBIC_HeaderCheck(data); // MBIC Header Check
            try
            {
                seq = data[1];
                
            }
            catch {
                return;
            }
            if (fileDownload != null)
            {
                this.fileDownload = (Update_Serial)fileDownload;
            }
            else
            {
                this.fileDownload = new Update_Serial();
            }
            if (this.fileDownload.Update_ready == true)
            {
                DataCheck = HeaderCheck(data);
                if (DataCheck == false)
                {
                    return;
                }
                DataCheck = CrcCheck(data);
                if(DataCheck == false)
                {
                    return;
                }


                switch (seq)
                {
                    case Terminal_Reset:
                    case Terminal_BootStart:
                    case Terminal_Controller_Update_Ack:
                    case Terminal_Controller_Update_Nak:
                        //int DataAckcnt = data[(int)Bluepro_t.bluecell_type + 1];
                        //this.fileDownload.UpdateFileSend(data, DataAckcnt);
                        this.fileDownload.Termianl__Operate(data);
                        break;
                    case 3:
                        break;
                    default:
                        break;
                }
                
            }
            else if (DataCheck == true)/*Header Check*/
            {
                //(int)MBICProt_st.MBIC_PAYLOADSTART
                DataCheck = MBIC_CrcCheck(data);
                if(DataCheck == true)
                {

                    cmd = data[(int)MBICProt_st.MBIC_CMD_0];
                    switch (cmd)
                    {
                        case (byte)MBIC_Download_Rsp_L.MBIC_Notice_RSP:
                        
                        case (byte)MBIC_Download_Rsp_L.MBIC_Download_DATA_RSP:
                            Length = (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 0] << 24)
                                    | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 1] << 16)
                                    | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 2] << 8)
                                    | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 3]);
                            LastFrame = (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 4] << 24)
                                       | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 5] << 16)
                                       | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 6] << 8)
                                       | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 7]);
                            if (LastFrame + 1 != Length)
                            {
                                if (Length == this.main_Form.MBIC_BootLoader_DataArray.Length)
                                    this.fileDownload.MBIC_FirmwareUpdateSend(ref this.serial, this.main_Form.MBIC_BootLoader_DataArray);
                            }
                            else
                            {
                                crcret = crc.CRC16_Generate(this.main_Form.MBIC_BootLoader_DataArray, this.main_Form.MBIC_BootLoader_DataArray.Length);
                                datatmp[0] = (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 0]);
                                datatmp[1] =  (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 1]);
                                datatmp[2] =  (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 2]);
                                datatmp[3] =  (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 3]);
                                datatmp[4] = Convert.ToByte(crcret & 0xFF00 >> 8);
                                datatmp[5] = Convert.ToByte(crcret & 0xFF00 >> 8);
                                datatmp[6] = 0;     /*Reserve*/
                                datatmp[7] = 0;     /*Reserve*/
                                datatmp[8] = 0;     /*Reserve*/
                                datatmp[9] = 0;     /*Reserve*/
                                datatmp[10] =0;     /*Reserve*/
                                datatmp[11] = 0;    /*Reserve*/

                                datatmp = bluecell_BootProtocol.MBIC_HeaderMergeFunction(datatmp, 12);
                                this.serial.Serial_DataSend(datatmp, 22 + 12 + 3);
                            }
                            
                            break;
                        case (byte)MBIC_Download_Rsp_L.MBIC_Download_Confirm_RSP:
                            Length = (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 0] << 24)
                                    | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 1] << 16)
                                    | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 2] << 8)
                                    | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 3]);
                            CRCRET = crc.CRC16_Generate(this.main_Form.MBIC_BootLoader_DataArray, this.main_Form.MBIC_BootLoader_DataArray.Length);

                            LastFrame = (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 4] << 24)
                                       | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 5] << 16)
                                       | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 6] << 8)
                                       | (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 7]);
                            if (LastFrame + 1 != Length)
                            {
                                if (Length == this.main_Form.MBIC_BootLoader_DataArray.Length)
                                    this.fileDownload.MBIC_FirmwareUpdateSend(ref this.serial, this.main_Form.MBIC_BootLoader_DataArray);
                            }
                            else
                            {
                                crcret = crc.CRC16_Generate(this.main_Form.MBIC_BootLoader_DataArray, this.main_Form.MBIC_BootLoader_DataArray.Length);
                                datatmp[0] = (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 0]);
                                datatmp[1] = (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 1]);
                                datatmp[2] = (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 2]);
                                datatmp[3] = (data[(int)MBICProt_st.MBIC_PAYLOADSTART + 3]);
                                datatmp[4] = Convert.ToByte(crcret & 0xFF00 >> 8);
                                datatmp[5] = Convert.ToByte(crcret & 0xFF00 >> 8);
                                datatmp[6] = 0;     /*Reserve*/
                                datatmp[7] = 0;     /*Reserve*/
                                datatmp[8] = 0;     /*Reserve*/
                                datatmp[9] = 0;     /*Reserve*/
                                datatmp[10] = 0;     /*Reserve*/
                                datatmp[11] = 0;    /*Reserve*/

                                datatmp = bluecell_BootProtocol.MBIC_HeaderMergeFunction(datatmp, 12);
                                this.serial.Serial_DataSend(datatmp, 22 + 12 + 3);
                            }

                            break;
                        case (byte)MBIC_Download_Rsp_L.MBIC_Reboot_Notice_RSP:
                            
                            break;
                    }
                }
                else
                {

                }
            }
            else/* * * * * * * * * * * * * *API RECV 부분 * * * * * * * * * * * * *  */
            {
                if(ByteToString(data).Contains("Build at") == true)
                {
                    string tempstr = ByteToString(data);
                    //tempstr.IndexOf("Build at");
                    tempstr = tempstr.Substring(tempstr.IndexOf("Build at"));
                    tempstr = tempstr.Substring(tempstr.IndexOf("Build at"), tempstr.IndexOf("\r\n"));
                    this.main_Form.DateLabelInputFunc(tempstr);
                }
                DataCheck = HeaderCheck(data);
                if (DataCheck == false)
                {
                    return;
                }
                DataCheck = CrcCheck(data);
                if (DataCheck == false)
                {
                    return;
                }
                bluecell_BootProtocol.Bluecell_RF_Status_Get(this.serial,this.main_Form, data);
            }
        }

    }
}
