#include "Barcode_Scanner.h"
#include "api_RS485.h"
#include "string.h"
#include "init.h"
#include "Display_Info.h"
#include "R485_Communication_Matrix.h"
#define UART_RX_MAX_DEPTH (1024)    // 4K

typedef struct
{
    uint32_t read_pos;
    uint32_t write_pos;
    uint8_t  Rx_Buffer [ UART_RX_MAX_DEPTH ];
} UARTRxBuf_t;

static UARTRxBuf_t      UARTRxBuf;
static UARTRxBuf_t      UARTRxBuf1;
static uint8_t  mDataBufPtr[1024]   = {0};
static uint32_t mDataBufLen   = 0;
static uint8_t  mDataBufPtr1[1024]   = {0};
static uint32_t mDataBufLen1   = 0;
uint8_t  BarCode[256] = {0};
uint8_t  BarCode1[256] = {0};
uint32_t readNum = 0;
uint32_t readNum1 = 0;

static uint32_t Protocol_UartRead(uint8_t *pData, uint32_t len);//485
static uint32_t Protocol_UartRead1(uint8_t *pData, uint32_t len);//扫码枪
static uint32_t Protocol_UartRead2(uint8_t *pData, uint32_t len);//esp32
uint8_t nowdata[4];
uint8_t lastdata[4];
uint8_t sendmsg[8];
uint8_t timenum = 0;
uint8_t firstflag = 0;
uint8_t RS485_data[64];
uint8_t checknumwrong = 3;
uint8_t zhenduanflag = 0;
uint8_t clearOdoFlag = 0;
uint8_t connectbleFlag = 0;
uint8_t Auto_ONOFF = 0;
uint32_t key_value;
uint8_t key_array[4];
uint8_t seed_value[4];
uint8_t zhenduansendStep = 0;
uint8_t line_stdio = 2;
uint8_t powerstdio = 0;
uint8_t get_num_buf[34];
uint8_t comparestart;
uint8_t blename[5];
uint8_t btmac[6];
uint8_t firstpowerflag = 0;
uint16_t lightnumber = 0;
uint8_t writeflag = 0;
void get_key(void)
{
    key_array[0] = seed_value[0] | seed_value[3];
    key_array[1] = (seed_value[1] >> 1) | (seed_value[2] << 1);
    key_array[2] = (seed_value[2] >> 2) | (seed_value[1] << 2);
    key_array[3] = (seed_value[3] >> 3) | (seed_value[0] << 3);
    key_value = ((uint32_t)key_array[0] << 24U);
    key_value = key_value | ((uint32_t)key_array[1] << 16U);
    key_value = key_value | ((uint32_t)key_array[2] << 8U);
    key_value = key_value | (uint32_t)key_array[3];
}

void Key_Calculation(uint8_t *Seed_Value,uint8_t *Key_result)
{
    Key_result[0] = Seed_Value[0] | Seed_Value[3];
    Key_result[1] = (Seed_Value[1] >> 1) | (Seed_Value[2] << 1);
    Key_result[2] = (Seed_Value[2] >> 2) | (Seed_Value[1] << 2);
    Key_result[3] = (Seed_Value[3] >> 3) | (Seed_Value[0] << 3);
}
uint8_t recvflag111 = 0;
uint8_t xierucishu = 0;
void datacheck(void)
{

    // RS485_send_time = 0;
    // RS485_TX_finish = 0;
    uint16_t checksum = 0;
    uint8_t arraynum = 0;
    if(zhenduanflag == 0)
    {
        if(BarCode[0] == 0x59 && BarCode[1] == 0x44)
        {
                for(int i = 0;i<255;i++)
                {
                    if(BarCode[i] == 0x4A && BarCode[i - 1] == 0x4B)
                    {
                        arraynum = i;
                    }
                }
                if(((BarCode[arraynum]) == 0x4A) && ((BarCode[arraynum-1]) == 0x4B))
                {
                    for(int i = 0;i < 64;i++)
                    {
                        RS485_data[i] = BarCode[4+i];
                    }
                    switch (BarCode[2])
                    {
                        case 0x48:
                        memcpy(R485_ID48h.Msg,RS485_data,64);
                        checksum = Yadi_CAL_Data_Sum(&BarCode[2], 64 + 2);
                        if(checksum != BarCode[68])
                        {
                            // checknumwrong = 1;
                        }
                        break;
                        case 0x49:
                        memcpy(R485_ID49h.Msg,RS485_data,64);
                        checksum = Yadi_CAL_Data_Sum(&BarCode[2], 64 + 2);
                        if(checksum != BarCode[68])
                        {
                            // checknumwrong = 1;
                        }
                        break;
                        case 0x4A:
                        if(connectbleFlag == 1)
                        {
                            memcpy(R485_ID4Ah.Msg,RS485_data,64);
                        }
                        memcpy(R485_ID4Ah.Msg,RS485_data,64);
                        checksum = Yadi_CAL_Data_Sum(&BarCode[2], 64 + 2);
                        if(checksum != BarCode[68])
                        {
                            // checknumwrong = 1;
                        }
                        break;
                        case 0x4D:
                        memcpy(R485_ID4Dh.Msg,RS485_data,64);
                        break;
                        case 0x81:
                        {
                            btmac[0] = RS485_data[0];
                            btmac[1] = RS485_data[1];
                            btmac[2] = RS485_data[2];
                            btmac[3] = RS485_data[3];
                            btmac[4] = RS485_data[4];
                            btmac[5] = RS485_data[5];
                            blename[0] = RS485_data[6];
                            blename[1] = RS485_data[7];
                            blename[2] = RS485_data[8];
                            blename[3] = RS485_data[9];
                            blename[4] = 0xff;
                            lightnumber = (RS485_data[11]<<8)+RS485_data[10];
                            writeflag = RS485_data[12];
                            recvflag111 = 1;
                            RS485_TX_finish = 0;
                            // General_Number_Disp(blename, 3, 165); 
                        }
                        break;
                        case 0x4F:
                        {
                            switch (BarCode[6])
                            {
                            case 0:
                                LineGetSta.power1 = (BarCode[7]<<8 |BarCode[8]);
                                if(LineGetSta.power1 < 24)
                                {
                                    powerstdio = 1;
                                }
                            break;
                            case 1:
                                    LineGetSta.ble1 = BarCode[7];
                                    if(LineGetSta.ble1 == 1)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            case 2:
                                    LineGetSta.turnleft1 = BarCode[7];
                                    if(LineGetSta.turnleft1 == 1)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            case 3:
                                    LineGetSta.turnright1 = BarCode[7];
                                    if(LineGetSta.turnright1 == 1)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            case 4:
                                    LineGetSta.ABSlight1 = BarCode[7];
                                    if(LineGetSta.ABSlight1 == 1)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            case 5:
                                    LineGetSta.lowlight1 = BarCode[7];
                                    if(LineGetSta.lowlight1 == 1)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            case 6:
                                    LineGetSta.highlight1 = BarCode[7];
                                    if(LineGetSta.highlight1 == 1)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            case 7:
                                    LineGetSta.weizhilight1 = BarCode[7];
                                    if(LineGetSta.weizhilight1 == 1)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            default:
                                break;
                            }
                            break;
                        }
                    default:
                        break;
                    }
                    memset(RS485_data,0,64);
                    memset(BarCode,0,sizeof(BarCode));
                    RS485_TX_finish = 0;

                }
                else
                {
                    // RS485_send_num--;
                    RS485_TX_finish = 0;
                }
        }
        else
        {
            // RS485_TX_finish = 0;
        }
    }
    else if(zhenduanflag == 1)
    {
          if(BarCode[0] == 0x59 && BarCode[1] == 0x44)
            {
                    for(int i = 0;i<255;i++)
                    {
                        if(BarCode[3] == 0x40)
                        {
                            if(BarCode[i] == 0x4A && BarCode[i - 1] == 0x4B && i > 0x40-3)
                            {
                                arraynum = i;
                            }
                        }
                        else
                        {
                            if(BarCode[i] == 0x4A && BarCode[i - 1] == 0x4B)
                            {
                                arraynum = i;
                            }
                        }
                        
                    }
                    // g_Stage = 1;
                    if(((BarCode[arraynum]) == 0x4A) && ((BarCode[arraynum-1]) == 0x4B))
                    {
                        if(BarCode[2] == 0x81)
                        {
                            writeflag = BarCode[16];
                            RS485_TX_finish = 0;
                        }
                        switch (zhenduansendStep)
                        {
                        case 0:
                            if(BarCode[2] == 0x4F)
                            {
                                if(BarCode[4] == 0x50 && BarCode[5] == 0x3)
                                {
                                    zhenduansendStep++;
                                    RS485_TX_finish = 0;
                                }
                            }
                            break;
                        case 1:
                            if(BarCode[2] == 0x4F)
                            {
                                if(BarCode[4] == 0x67 && BarCode[5] == 0x1)
                                {
                                    seed_value[0] = BarCode[6];
                                    seed_value[1] = BarCode[7];
                                    seed_value[2] = BarCode[8];
                                    seed_value[3] = BarCode[9];
                                    get_key();
                                    zhenduansendStep++;
                                    RS485_TX_finish = 0;
                                }
                            }
                            break;
                        case 2:
                            if(BarCode[2] == 0x4F)
                            {
                                if(BarCode[4] == 0x67 && BarCode[5] == 0x2)
                                {
                                    zhenduansendStep++;
                                    RS485_TX_finish = 0;
                                }
                                else if(BarCode[4] != 0x67)
                                {
                                    zhenduansendStep = 0;
                                    RS485_TX_finish = 0;
                                }
                                else
                                {
                                    ;
                                }
                            }
                            break;
                        case 3:
                            if(BarCode[2] == 0x4F)
                            {
                                
                                if((BarCode[4] == 0x6E) && (BarCode[5] == 0x50) && (BarCode[6] == 0))
                                {
                                    // if(xierucishu > 4)
                                    // {
                                        
                                        zhenduansendStep++;
                                        xierucishu = 0;
                                    // }
                                    // else
                                    // {
                                    //     xierucishu++;
                                    // }
                                    
                                    RS485_TX_finish = 0;
                                }
                                if(BarCode[4] == 0x7F && BarCode[5] == 0x2E && BarCode[6] == 0x78 )
                                {
                                    RS485_TX_finish = 1;
                                    // zhenduansendStep = 0;
                                    // ;
                                }
                                if(BarCode[4] == 0x7F && BarCode[5] == 0x2E && BarCode[6] == 0x31 )
                                {
                                    RS485_TX_finish = 0;
                                }
                            }
                            else
                            {
                                // RS485_TX_finish = 0;
                            }
                            break;
                        default:
                            break;
                        }
                        memset(RS485_data,0,64);
                    }
                    else
                    {
                        // RS485_TX_finish = 0x0;
                    }
            }
    }
    else if(zhenduanflag == 2)
    {
         if(BarCode[0] == 0x59 && BarCode[1] == 0x44)
            {
                    for(int i = 0;i<255;i++)
                    {
                        if(BarCode[i] == 0x4A && BarCode[i - 1] == 0x4B)
                        {
                            arraynum = i;
                        }
                    }
                    if(((BarCode[arraynum]) == 0x4A) && ((BarCode[arraynum-1]) == 0x4B))
                    {
                       if(BarCode[4] == 0x62 && BarCode[5] == 0x50 && BarCode[6] == 0)
                       {
                            memcpy(get_num_buf,BarCode+7,34 );
                            comparestart = 1;
                            zhenduanflag = 3;
                            
                       }
                        
                    }
            }
    }
}
uint8_t cmpresult = 3;
void BarCodeDataGet(void)
{

    if((mDataBufPtr1[0] == 0x59) && (mDataBufPtr1[1] == 0x59)&&(mDataBufPtr1[39] != 0x0))
    {
        memcpy(barcode_Msg,&mDataBufPtr1[6],34);
        memcpy(barcode_Msg1,&mDataBufPtr1[6],34);
    }
    else
    {
        memcpy(barcode_Msg1,&mDataBufPtr1[6],34);
        memset(barcode_Msg,0,34);
    }
}
uint8_t GetDataCompare(void)
{
    
    for(int i = 0;i<34;i++)
    {
        if(get_num_buf[i] == barcode_Msg1[i] )
        {
            cmpresult = 0;
            // u8compareresult = 0;
        }
        else
        {
            cmpresult = 1;
            return cmpresult;
            // u8compareresult = 1;
        }
        
    }
    return cmpresult;
    
}
void UART_Put(uint32_t Value)
{
    uint32_t nextPos = 0u;
    
    nextPos = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;

    if ( nextPos == UARTRxBuf.read_pos )
    {
        //队列已满，无法插入队列
        // UARTRxBuf.write_pos  = 0;
        // RS485_TX_finish = 0;
    }
    else
    {
        UARTRxBuf.Rx_Buffer [ UARTRxBuf.write_pos ] = Value;
        UARTRxBuf.write_pos                         = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;
    }
    // RS485_TX_finish = 0;
    // LINE_OUT_NEG_09 = 1;
    // RS485_TX_finish = 0;
    // RS485_send_time = 0;
    RS485_send_time = 0;
    return;
}
void UART_Put1(uint32_t Value)
{
    uint32_t nextPos = 0u;
    
    nextPos = (UARTRxBuf1.write_pos + 1) % UART_RX_MAX_DEPTH;

    if ( nextPos == UARTRxBuf1.read_pos )
    {
        //队列已满，无法插入队列
        // UARTRxBuf.write_pos  = 0;
        // RS485_TX_finish = 0;
    }
    else
    {
        UARTRxBuf1.Rx_Buffer [ UARTRxBuf1.write_pos ] = Value;
        UARTRxBuf1.write_pos                         = (UARTRxBuf1.write_pos + 1) % UART_RX_MAX_DEPTH;
    }
    // RS485_TX_finish = 0;
    // LINE_OUT_NEG_09 = 1;
    // RS485_TX_finish = 0;
    if(firstpowerflag != 2)
    {
        firstpowerflag = 1;
    }
    return;
}

void UART_Put2(uint32_t Value)
{
    uint32_t nextPos = 0u;
    
    nextPos = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;

    if ( nextPos == UARTRxBuf.read_pos )
    {
        //队列已满，无法插入队列
        // UARTRxBuf.write_pos  = 0;
        // RS485_TX_finish = 0;
    }
    else
    {
        // UARTRxBuf.Rx_Buffer [ UARTRxBuf.write_pos ] = Value;
        // UARTRxBuf.write_pos                         = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;
    }
    // RS485_send_time = 0;
    return;
}

void Recv_Byte(void)
{
    int      i = 0;
    int      j = 0;
    uint32_t      len;
    int k = 0;
    readNum = Protocol_UartRead(mDataBufPtr + mDataBufLen, 1025 - mDataBufLen);
    uint8_t testflag = 0;
    if ( readNum > 0 )
    {
        mDataBufLen += readNum;

        while(mDataBufLen)
        {
            for(i = 0; i < mDataBufLen; i++)
            {
                // if(i > 5)
                // {
                    if(mDataBufPtr[i - 1] == 0x59  && mDataBufPtr[i] == 0x44)
                    {
                        k = i - 1;
                    }


                    
                    if((mDataBufPtr[k] == 0x59 && mDataBufPtr[k+1] == 0x44) && (mDataBufPtr[i] == 0x4A ) && (mDataBufPtr[i - 1] == 0x4B) && (i > mDataBufPtr[k + 3] - 3))
                    {
                        if( i < 1)
                        {
                            break;
                        }
                        memset(BarCode, 0, sizeof(BarCode));
                        for(j = 0; j < i+1; j++)
                        {
                            BarCode[j] = mDataBufPtr[j];
                        }
                        testflag = 0;
                        break;
                    }
                    else
                    {

                        testflag = 1;
                        // break;
                    
                    }
                // }
                
            }
            if(testflag)
            {
                testflag = 0;
                break;
            }
            // 解析协议
            len = i+1;
            if ( (len > 0) && (len < mDataBufLen) )
            {
                // 将未解析的数据移到头部
                // Move unparsed data to the head
                
                memcpy(mDataBufPtr, mDataBufPtr + len, mDataBufLen - len);
                
                // memcpy(nowdata,mDataBufPtr + len,len);
                // datacheck();
            }
            mDataBufLen -= len;
            datacheck();
        }
        
    }
    
    return;
}

static uint32_t Protocol_UartRead(uint8_t *pData, uint32_t len)
{
    uint32_t i       = 0;
    uint32_t DataLen = 0u;
    uint32_t ReadLen = 0u;

    if ( UARTRxBuf.write_pos == UARTRxBuf.read_pos )
    {
        return 0;    //队列空
    }

    if ( UARTRxBuf.write_pos > UARTRxBuf.read_pos )
    {
        DataLen = UARTRxBuf.write_pos - UARTRxBuf.read_pos;
    }
    else
    {
        DataLen = UART_RX_MAX_DEPTH - (UARTRxBuf.read_pos - UARTRxBuf.write_pos);
    }

    if ( len > DataLen )
    {
        ReadLen = DataLen;
    }
    else
    {
        ReadLen = len;
    }

    for ( i = 0u; i < ReadLen; i++ )
    {
        pData [ i ]        = UARTRxBuf.Rx_Buffer [ UARTRxBuf.read_pos ];
        UARTRxBuf.read_pos = (UARTRxBuf.read_pos + 1) % UART_RX_MAX_DEPTH;
    }

    return i;
}
void Recv_Byte1(void)
{
    int      i = 0;
    int      j = 0;
    uint32_t      len;
    readNum1 = Protocol_UartRead1(mDataBufPtr1 + mDataBufLen1, 1024 - mDataBufLen1);
    // if (readNum1 > 0)
    // {
    // BarCodeDataGet();
    // }
    if (readNum1 > 0)
    {
        mDataBufLen1 += readNum1;

        while(mDataBufLen1)
        {
            memset(BarCode1, 0, sizeof(BarCode1));
            for(i = 0; i < mDataBufLen1; i++)
            {
                    // if((mDataBufPtr1[i] == 0x0 ) && (mDataBufPtr1[i - 1] == 0x0))
                    // {
                        // if( i < 1)
                        // {
                        //     break;
                        // }
                        // memset(BarCode1, 0, sizeof(BarCode1));
                        
                        for(j = 0; j < mDataBufLen1; j++)
                        {
                            BarCode1[j] = mDataBufPtr1[j];
                        }
                        
                    
                    // }
                
                
            }

            // 解析协议
            len = mDataBufLen1;
            if ( (len > 0) && (len < mDataBufLen1) )
            {
                // 将未解析的数据移到头部
                // Move unparsed data to the head
                
                memcpy(mDataBufPtr1, mDataBufPtr1 + len, mDataBufLen1 - len);
                
                // memcpy(nowdata,mDataBufPtr + len,len);
                // datacheck();
            }
            
            mDataBufLen1 -= len;
            
        }
        BarCodeDataGet();
    }
    
    
}

static uint32_t Protocol_UartRead1(uint8_t *pData, uint32_t len)
{
    uint32_t i       = 0;
    uint32_t DataLen = 0u;
    uint32_t ReadLen = 0u;

    if ( UARTRxBuf1.write_pos == UARTRxBuf1.read_pos )
    {
        return 0;    //队列空
    }

    if ( UARTRxBuf1.write_pos > UARTRxBuf1.read_pos )
    {
        DataLen = UARTRxBuf1.write_pos - UARTRxBuf1.read_pos;
    }
    else
    {
        DataLen = UART_RX_MAX_DEPTH - (UARTRxBuf1.read_pos - UARTRxBuf1.write_pos);
    }

    if ( len > DataLen )
    {
        ReadLen = DataLen;
    }
    else
    {
        ReadLen = len;
    }

    for ( i = 0u; i < ReadLen; i++ )
    {
        pData [ i ]        = UARTRxBuf1.Rx_Buffer [ UARTRxBuf1.read_pos ];
        UARTRxBuf1.read_pos = (UARTRxBuf1.read_pos + 1) % UART_RX_MAX_DEPTH;
    }

    return i;
}


void Recv_Byte2(void)
{
    int      i = 0;
    int      j = 0;
    uint32_t      len;
    readNum1 = Protocol_UartRead2(mDataBufPtr1 + mDataBufLen1, 1024 - mDataBufLen1);
    // if (readNum1 > 0)
    // {
    // BarCodeDataGet();
    // }
    if (readNum1 > 0)
    {
        mDataBufLen1 += readNum1;

        while(mDataBufLen1)
        {
            memset(BarCode1, 0, sizeof(BarCode1));
            for(i = 0; i < mDataBufLen1; i++)
            {
                    // if((mDataBufPtr1[i] == 0x0 ) && (mDataBufPtr1[i - 1] == 0x0))
                    // {
                        // if( i < 1)
                        // {
                        //     break;
                        // }
                        // memset(BarCode1, 0, sizeof(BarCode1));
                        
                        for(j = 0; j < mDataBufLen1; j++)
                        {
                            BarCode1[j] = mDataBufPtr1[j];
                        }
                        
                    
                    // }
                
                
            }

            // 解析协议
            len = mDataBufLen1;
            if ( (len > 0) && (len < mDataBufLen1) )
            {
                // 将未解析的数据移到头部
                // Move unparsed data to the head
                
                memcpy(mDataBufPtr1, mDataBufPtr1 + len, mDataBufLen1 - len);
                
                // memcpy(nowdata,mDataBufPtr + len,len);
                // datacheck();
            }
            
            mDataBufLen1 -= len;
            
        }
        BarCodeDataGet();
    }
    
    
}

static uint32_t Protocol_UartRead2(uint8_t *pData, uint32_t len)
{
    uint32_t i       = 0;
    uint32_t DataLen = 0u;
    uint32_t ReadLen = 0u;

    if ( UARTRxBuf1.write_pos == UARTRxBuf1.read_pos )
    {
        return 0;    //队列空
    }

    if ( UARTRxBuf1.write_pos > UARTRxBuf1.read_pos )
    {
        DataLen = UARTRxBuf1.write_pos - UARTRxBuf1.read_pos;
    }
    else
    {
        DataLen = UART_RX_MAX_DEPTH - (UARTRxBuf1.read_pos - UARTRxBuf1.write_pos);
    }

    if ( len > DataLen )
    {
        ReadLen = DataLen;
    }
    else
    {
        ReadLen = len;
    }

    for ( i = 0u; i < ReadLen; i++ )
    {
        pData [ i ]        = UARTRxBuf1.Rx_Buffer [ UARTRxBuf1.read_pos ];
        UARTRxBuf1.read_pos = (UARTRxBuf1.read_pos + 1) % UART_RX_MAX_DEPTH;
    }

    return i;
}
