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

namespace Jdas_Mbic
{
    public enum Bluepro_t
    {
        bluecell_header0 = 0,
        bluecell_header1,
        bluecell_header2,
        bluecell_header3,
        bluecell_type,
        bluecell_length_h,
        bluecell_length_l,
        bluecell_updatecnt_h,
        bluecell_updatecnt_l,
        bluecell_data,

    };
    public enum Updateseq
    {
        Bluecell_Reset = 0,
        Bluecell_Firmupdate_start,
        Bluecell_Firmupdate_sending,
        Bluecell_Firmupdate_end,
    };
    enum Bluecell_ProtIndex_p
    {
        Bluecell_Header = 0,
        Bluecell_Type,
        Bluecell_Length_H,
        Bluecell_Length_L,
        Bluecell_CrcIndex,
        Bluecell_data,
    }
    enum Bluecell_Prot_t{
        TYPE_BLUECELL_RESET = 0,
        TYPE_BLUECELL_SET   = 1,
        TYPE_BLUECELL_GET   = 2,
        TYPE_BLUECELL_SAVE  = 3,
        TYPE_BLUECELL_ACK   = 4,
    };
   
    enum MBICProt_st
    {
        MBIC_PREAMBLE_0 = 0,
        MBIC_PREAMBLE_1,
        MBIC_PREAMBLE_2,
        MBIC_PREAMBLE_3,
        MBIC_SUBUID_0,
        MBIC_SUBUID_1,
        MBIC_RCODE_0,
        MBIC_TRID_0,
        MBIC_TRID_1,
        MBIC_SEQSUM_0, // 9Index

        MBIC_TTL_0, //10 INDEX
        MBIC_TIME_0,
        MBIC_TIME_1,
        MBIC_TIME_2,
        MBIC_TIME_3,
        MBIC_TIME_4,
        MBIC_TIME_5,
        MBIC_ERRRESPONSE_0,
        MBIC_CMD_0,

        MBIC_LENGTH_0, // 19INDEX
        MBIC_LENGTH_1, // 20

        MBIC_HEADERCHECKSUM_0,
        MBIC_PAYLOADSTART,
        /*
         * PayLoadSTART
         */
    };
    public class Bluecell_BootProtocol
    {
        public enum DATATYPE
        {
            BLUECELL_SOFTWARERESET = 0,
            ATT_DL1_PATH = 0x12,
            ATT_UL1_PATH = 0x16,
            ATT_SelfTest = 0x18,
            ATT_DL2_PATH = 0x22,
            ATT_UL2_PATH = 0x26,
            ATT_DL3_PATH = 0x32,
            ATT_UL3_PATH = 0x36,
            ATT_DL4_PATH = 0x42,
            ATT_UL4_PATH = 0x46,
            Bluecell_ULO_ALC_ON_OFF = 0x51,
            Bluecell_DLI_AGC_ON_OFF = 0x61,
            ATT_TableSet = 0x70,
            ATT_TableGet = 0x71,
            Bluecell_StatusReq = 0x77,
            Bluecell_StatusSave = 0x78,
            Bluecell_DL1_USER = 0x80,
            Bluecell_DL2_USER = 0x81,
            Bluecell_DL3_USER = 0x82,
            Bluecell_DL4_USER = 0x83,
            Bluecell_UL1_USER = 0x84,
            Bluecell_UL2_USER = 0x85,
            Bluecell_UL3_USER = 0x86,
            Bluecell_UL4_USER = 0x87,
            Bluecell_TEMP_USER = 0x88,
            Bluecell_DLI_AGC_Threshold,
            Bluecell_DLI_AGC_Threshold_Default,
            Bluecell_DLI_Shutdown_ON_OFF,
            Bluecell_DLI_Shutdown_Threshold,
            Bluecell_DLI_Shutdown_Threshold_Default,
            Bluecell_DLI_Shutdown_Count,
            Bluecell_DLI_Level_High_Threshold,
            Bluecell_DLI_Level_Low_Threshold,
            Bluecell_DLI_Level_High_Low_Threshold_default,
            Bluecell_LED_TEST,
            Bluecell_Temperature_Offset,
            Bluecell_Temp_High_Threshold,
            Bluecell_Temp_High_Threshold_Default,
            Bluecell_ULO_Level_High_Threshold,
            Bluecell_ULO_Level_High_Threshold_default,
            Bluecell_ULO_ALC_Threshold,
            Bluecell_ULO_ALC_Threshold_Default,
            Bluecell_ULO_Shutdown_ON_OFF,
            Bluecell_ULO_Shutdown_Threshold,
            Bluecell_ULO_Shutdown_Threshold_Default,
            Bluecell_ULO_Shutdown_Retry_Count,
            Bluecell_Alarm_Mask,
            Bluecell_ATT_DL1,
            Bluecell_ATT_DL2,
            Bluecell_ATT_DL3,
            Bluecell_ATT_DL4,
            Bluecell_ATT_UL1,
            Bluecell_ATT_UL2,
            Bluecell_ATT_UL3,
            Bluecell_ATT_UL4,
            Bluecell_ATT_DL1_USER,
            Bluecell_ATT_DL2_USER,
            Bluecell_ATT_DL3_USER,
            Bluecell_ATT_DL4_USER,
            Bluecell_ATT_UL1_USER,
            Bluecell_ATT_UL2_USER,
            Bluecell_ATT_UL3_USER,
            Bluecell_ATT_UL4_USER,
            BLuecell_ATT_ALC1,
            BLuecell_ATT_ALC2,
            BLuecell_ATT_ALC3,
            BLuecell_ATT_ALC4,
            Bluecell_BankSelect,
            Bluecell_TimeSetting,
            Bluecell_Factory_Set,
            Bluecell_CarrierOnOff,
            Bluecell_PCBVersionSet,
            Bluecell_SerialNumberSet,
            Bluecell_ManufactureDateSet,
            Bluecell_DL_Det_ALL_Offset,
            Bluecell_UL_Det_Path1_Offset,
            Bluecell_UL_Det_Path2_Offset,
            Bluecell_UL_Det_Path3_Offset,
            Bluecell_UL_Det_Path4_Offset,
            Bluecell_Temp_Shutdown_Path_ON_OFF,
            Bluecell_Path1_GainValue,
            Bluecell_Path2_GainValue,
            Bluecell_Path3_GainValue,
            Bluecell_Path4_GainValue,
        };

       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
        Serial serial;
        /*bluecell Header*/
        public const byte Bluecell_Header0 = 0x42;//ASCII : B
        public const byte Bluecell_Header1 = 0x4C;//ASCII : L
        public const byte Bluecell_Header2 = 0x55;//ASCII : U
        public const byte Bluecell_Header3 = 0x45;//ASCII : E
        /*bluecell type*/


        public const int bluecell_Firmupdate_sendlength = 1024;
        Crc16 crc16 = new Crc16();
        public const byte BLUECELL_HEADER = 0xBE;
        public const byte BLUECELL_TAILER = 0xEB;
        const byte BLUECELL_RESET_LENGTH = 9;
        const byte BLUECELL_FIX_DATA_LENGTH = 4;

        const byte MBIC_HEADER_SIZE = 22;
        const byte MBIC_PREAMBLE0 = 0x16;
        const byte MBIC_PREAMBLE1 = 0x16;
        const byte MBIC_PREAMBLE2 = 0x16;
        const byte MBIC_PREAMBLE3 = 0x16;
        const byte MBIC_SUBUID0 = 0x00;
        const byte MBIC_SUBUID1 = 0xF1;
        const byte MBIC_RCODE = 0x00;
        const byte MBIC_TRID = 0x00;
        const byte MBIC_SEQNUM = 0x00;
        const byte MBIC_TTL = 0x00;
        const byte MBIC_TIME = 0x00;
        const byte MBIC_ERRRESPONSE = 0x00;
        const byte MBIC_CMD = 0x00;
        const byte MBIC_LENGTH = 0x00;
        const byte MBIC_CHECKSHUM_INDEX = MBIC_HEADER_SIZE - 1; //CheckSUM REMOVE INDEX
        const byte MBIC_ETX = 0x03;
        const byte MBIC_NODE_MU = 0x80;
        const byte MBIC_CPUVERSION = 0x000000;
        public byte[] MBIC_HeaderMergeFunction(byte[] data, int Length)
        {
            byte[] ret = new byte[data.Length + 22 + 3];
            UInt16 CRCData = 0;
            

            /*
             Header
             */
            ret[(int)MBICProt_st.MBIC_PREAMBLE_0] = MBIC_PREAMBLE0;
            ret[(int)MBICProt_st.MBIC_PREAMBLE_1] = MBIC_PREAMBLE1;
            ret[(int)MBICProt_st.MBIC_PREAMBLE_2] = MBIC_PREAMBLE2;
            ret[(int)MBICProt_st.MBIC_PREAMBLE_3] = MBIC_PREAMBLE3;

            ret[(int)MBICProt_st.MBIC_SUBUID_0] = MBIC_SUBUID0;
            ret[(int)MBICProt_st.MBIC_SUBUID_1] = MBIC_SUBUID1;

            ret[(int)MBICProt_st.MBIC_RCODE_0] = 0;

            ret[(int)MBICProt_st.MBIC_TRID_0] = 0;
            ret[(int)MBICProt_st.MBIC_TRID_1] = 0;

            ret[(int)MBICProt_st.MBIC_SEQSUM_0] = 0;

            ret[(int)MBICProt_st.MBIC_TTL_0] = 0;

            ret[(int)MBICProt_st.MBIC_TIME_0] = 0;
            ret[(int)MBICProt_st.MBIC_TIME_1] = 0;
            ret[(int)MBICProt_st.MBIC_TIME_2] = 0;
            ret[(int)MBICProt_st.MBIC_TIME_3] = 0;
            ret[(int)MBICProt_st.MBIC_TIME_4] = 0;
            ret[(int)MBICProt_st.MBIC_TIME_5] = 0;
            ret[(int)MBICProt_st.MBIC_ERRRESPONSE_0] = MBIC_ERRRESPONSE;

            ret[(int)MBICProt_st.MBIC_CMD_0] = MBIC_ERRRESPONSE;

            ret[(int)MBICProt_st.MBIC_LENGTH_0] = MBIC_ERRRESPONSE;
            ret[(int)MBICProt_st.MBIC_LENGTH_1] = MBIC_ERRRESPONSE;



            for (int i = 0; i < Length; i++)
                ret[(int)MBICProt_st.MBIC_PAYLOADSTART + i] = data[i];
            /*
             TAIL
             */
           // CRCData = crc16.CRC16_Generate(data, Length);
            ret[(int)MBICProt_st.MBIC_PAYLOADSTART + Length + 0] = Convert.ToByte((CRCData & 0xFF00) >> 8);
            ret[(int)MBICProt_st.MBIC_PAYLOADSTART + Length + 1] = Convert.ToByte((CRCData & 0x00FF));
            ret[(int)MBICProt_st.MBIC_PAYLOADSTART + Length + 2] = 0x03;
            return ret;
        }

        public void Bluecell_Reset(object serial)
        {
            UInt16 Length = (BLUECELL_RESET_LENGTH - BLUECELL_FIX_DATA_LENGTH);
            byte[] temp_buf = new byte[BLUECELL_RESET_LENGTH];
            UInt16 CRCRET = crc16.CRC16_Generate(temp_buf, Length);
            this.serial = (Serial)serial;
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_Header]       = BLUECELL_HEADER;
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_Type]         = (byte)Bluecell_Prot_t.TYPE_BLUECELL_RESET;
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_Length_H]     = Convert.ToByte(Length & 0x00FF << 8);
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_Length_L]     = Convert.ToByte(Length & 0x00FF);
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_data] = 0;
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_data + 1]     = Convert.ToByte(CRCRET & 0xFF00 >> 8);
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_data + 1]     = Convert.ToByte(CRCRET & 0x00FF);
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_data + 2]     = BLUECELL_TAILER;
            this.serial.Serial_DataSend(temp_buf, temp_buf.Length);
        }
        public void Bluecell_RF_Status_Req(object serial)
        {
            Crc16 crc16 = new Crc16();
            this.serial = (Serial)serial;
            byte[] temp_buf = new byte[8];
            byte[] MBIC_DATA = { 0x16, 0x16, 0x16, 0x16, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x06, 0x09, 0x00, 0x0c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03 };
            //this.serial.Serial_DataSend(MBIC_DATA, MBIC_DATA.Length);
            //return;
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_Header] = BLUECELL_HEADER;
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_Type] = (int)DATATYPE.Bluecell_StatusReq;
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_Length_H] = 0;//Convert.ToByte(temp_buf.Length - 4);
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_Length_L] = Convert.ToByte(temp_buf.Length - 4);
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_data + 0] = Convert.ToByte((crc16.CRC16_Generate(temp_buf, temp_buf.Length - 4) & 0xFF00) >> 8);
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_data + 1] = Convert.ToByte((crc16.CRC16_Generate(temp_buf, temp_buf.Length - 4) & 0x00FF));
            //Convert.ToByte((Updatedata.Length & 0xFF00) >> 8);
            temp_buf[(int)Bluecell_ProtIndex_p.Bluecell_data + 2] = BLUECELL_TAILER;
            this.serial.Serial_DataSend(temp_buf, temp_buf.Length);

        }
        public const byte bluecell_length    = 2;
        public const byte bluecell_updatecnt = 2;
        public const byte bluecell_crc16     = 2;

        private const byte BLUECELL_TYPE = 1;
        JdasMbic main_Form;
        const byte BLUECELL_DATA_SET_LENGTH = 56;
        public void Bluecell_RF_Status_Get(object serial, object main_form, byte[] temp_buf)
        {
            this.main_Form = (JdasMbic)main_form;
            this.serial = (Serial)serial;
            byte type = temp_buf[BLUECELL_TYPE];
            //  main_Form.Invoke(new ByteSend(this.main_Form.ReSetting_Values),(temp_buf));
            switch (type)
            {
                case (byte)Bluecell_BootProtocol.DATATYPE.Bluecell_StatusReq:

                    this.main_Form.GUIDataStatusSet(temp_buf);
                    break;
                case (byte)Bluecell_BootProtocol.DATATYPE.ATT_TableGet:
                    this.main_Form.TableDataStatusSet(temp_buf);
                    break;
                //case (byte)Bluecell_Prot_t.TYPE_BLUECELL_ACK:
                    //this.main_Form.Message_Box_Open();
                 //   break;
               // case (byte)Bluecell_Prot_t.TYPE_BLUECELL_ERROR:
                    //this.main_Form.Message_Box_Error_Open(temp_buf);
                  //  break;

            }
            //Debug.Invoke(new StringSend(Debug.Data_Recv_Str), data);
            //main_Form.label1_8GHz_DL_OUT.Text = Convert.ToString(temp_val);

        }

#if false
        public int Bluecell_Firmupdate_sendlength() {
            return bluecell_Firmupdate_sendlength;
        }
        private void BootHeaderput(ref byte[] fix_data)
        {
            fix_data[(int)Bluepro_t.bluecell_header0] = Bluecell_Header0;
            fix_data[(int)Bluepro_t.bluecell_header1] = Bluecell_Header1;
            fix_data[(int)Bluepro_t.bluecell_header2] = Bluecell_Header2;
            fix_data[(int)Bluepro_t.bluecell_header3] = Bluecell_Header3;
        }

        public byte[] Boot_Reset(object serial,byte[] Updatedata)
        {
            this.serial = (Serial)serial;
            byte[] fix_data = new byte[11];
            //Array.Clear(data, 0, data.Length);
            BootHeaderput(ref fix_data);
            fix_data[(int)Bluepro_t.bluecell_type]    = (byte)Updateseq.Bluecell_Reset;
            fix_data[(int)Bluepro_t.bluecell_length_h]  = 0;
            fix_data[(int)Bluepro_t.bluecell_length_l]  = 5;
            fix_data[(int)Bluepro_t.bluecell_updatecnt_h] = Convert.ToByte((Updatedata.Length & 0xFF00) >> 8);
            fix_data[(int)Bluepro_t.bluecell_updatecnt_l] = Convert.ToByte((Updatedata.Length & 0x00FF));

            fix_data[(int)Bluepro_t.bluecell_data + 0] = Convert.ToByte((crc16.CRC16_Generate(fix_data, fix_data.Length - 4) & 0xFF00) >> 8);
            fix_data[(int)Bluepro_t.bluecell_data + 1] = Convert.ToByte((crc16.CRC16_Generate(fix_data, fix_data.Length - 4) & 0x00FF));
            this.serial.Serial_DataSend(fix_data, fix_data.Length);
            return fix_data;            
        }
     
        public byte[] Boot_DataSending(byte[] update_data,UInt16 length, UInt16 updatacnt)
        {
            //Array.Clear(data, 0, data.Length);
            byte[] fix_data = new byte[bluecell_Firmupdate_sendlength];
            //BootHeaderput(ref fix_data);
            //length += 5;
            Array.Copy(update_data, (int)Bluepro_t.bluecell_data, fix_data, (int)Bluepro_t.bluecell_data, length);
            BootHeaderput(ref fix_data);
            fix_data[(int)Bluepro_t.bluecell_type] = (byte)Updateseq.Bluecell_Firmupdate_sending;
            fix_data[(int)Bluepro_t.bluecell_length_h] = Convert.ToByte((length & 0xFF00) >> 8);
            fix_data[(int)Bluepro_t.bluecell_length_l] = Convert.ToByte((length & 0x00FF));
            fix_data[(int)Bluepro_t.bluecell_updatecnt_h] = Convert.ToByte((updatacnt & 0xFF00) >> 8);
            fix_data[(int)Bluepro_t.bluecell_updatecnt_l] = Convert.ToByte((updatacnt & 0x00FF));

            //Array.Copy(update_data, 0, fix_data, (int)Bluepro_t.bluecell_data, length-3);
            fix_data[length + 9] = Convert.ToByte((crc16.CRC16_Generate(fix_data, length + 5) & 0xFF00) >> 8);
            fix_data[length + 10] = Convert.ToByte(crc16.CRC16_Generate(fix_data, length + 5) & 0x00FF);
            return fix_data;
        }
        public byte[] Boot_DataEnd(byte[] update_data, int length)
        {
            //Array.Clear(data, 0, data.Length);
            byte[] fix_data = new byte[11];
            Array.Copy(update_data, (int)Bluepro_t.bluecell_data, fix_data, (int)Bluepro_t.bluecell_data, length);
            BootHeaderput(ref fix_data);
            fix_data[(int)Bluepro_t.bluecell_type]    = (byte)Updateseq.Bluecell_Firmupdate_end;
            fix_data[(int)Bluepro_t.bluecell_length_h] = Convert.ToByte((length & 0xFF00) >> 8);
            fix_data[(int)Bluepro_t.bluecell_length_l] = Convert.ToByte((length & 0x00FF));
            fix_data[(int)Bluepro_t.bluecell_updatecnt_h] = 0;
            fix_data[(int)Bluepro_t.bluecell_updatecnt_l] = 0;

            //Array.Copy(update_data, 0, fix_data, (int)Bluepro_t.bluecell_data, length-3);
            fix_data[length + 9] = Convert.ToByte((crc16.CRC16_Generate(fix_data, length + 5) & 0xFF00) >> 8);
            fix_data[length + 10] = Convert.ToByte(crc16.CRC16_Generate(fix_data, length + 5) & 0x00FF);
            return fix_data;
        }
#endif
    }
}
