#include "Barcode_Scanner.h"
#include "api_RS485.h"
#include "string.h"
#include "init.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);
static uint32_t Protocol_UartRead1(uint8_t *pData, uint32_t len);
uint8_t nowdata[4];
uint8_t lastdata[4];
uint8_t checkresult;
uint8_t sendmsg[8];
uint8_t timenum = 0;
uint8_t firstflag = 0;
uint8_t RS485_data[64];
uint8_t checknumwrong;
uint8_t zhenduanflag = 0;
uint8_t clearOdoFlag = 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 = 0;
uint8_t powerstdio = 0;
uint8_t get_num_buf[34];
uint8_t comparestart;
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 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:
                        memcpy(R485_ID4Ah.Msg,RS485_data,64);
                        checksum = Yadi_CAL_Data_Sum(&BarCode[2], 64 + 2);
                        if(checksum != BarCode[68])
                        {
                            checknumwrong = 1;
                        }
                        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 == 0)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            case 2:
                                    LineGetSta.turnleft1 = BarCode[7];
                                break;
                            case 3:
                                    LineGetSta.turnright1 = BarCode[7];
                                break;
                            case 4:
                                    LineGetSta.ABSlight1 = BarCode[7];
                                    if(LineGetSta.ABSlight1 == 0)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            case 5:
                                    LineGetSta.lowlight1 = BarCode[7];
                                    if(LineGetSta.lowlight1 == 0)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            case 6:
                                    LineGetSta.highlight1 = BarCode[7];
                                    if(LineGetSta.highlight1 == 0)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            case 7:
                                    LineGetSta.weizhilight1 = BarCode[7];
                                    if(LineGetSta.weizhilight1 == 0)
                                    {
                                        line_stdio = 1;
                                    }
                                break;
                            default:
                                break;
                            }
                        }
                    default:
                        break;
                    }
                    memset(RS485_data,0,64);
                    RS485_TX_finish = 0;

                }
                else
                {
                    RS485_send_num--;
                    RS485_TX_finish = 0;
                }
        }
    }
    else if(zhenduanflag == 1)
    {
          if(BarCode[0] == 0x59 && BarCode[1] == 0x44)
            {
                    for(int i = 0;i<255;i++)
                    {
                        if(BarCode[i] == 0x4A && BarCode[i - 1] == 0x4B)
                        {
                            arraynum = i;
                        }
                    }
                    // g_Stage = 1;
                    if(((BarCode[arraynum]) == 0x4A) && ((BarCode[arraynum-1]) == 0x4B))
                    {
                        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
                                {
                                    RS485_TX_finish = 0;
                                }
                            }
                            break;
                        case 3:
                            if(BarCode[2] == 0x4F)
                            {
                                if((BarCode[4] == 0x6E) && (BarCode[5] == 0x50) && (BarCode[6] == 0))
                                {
                                    zhenduansendStep++;
                                    RS485_TX_finish = 0;
                                }
                                if(BarCode[4] == 0x7F)
                                {
                                    // wait_write_flag = 1;
                                    RS485_TX_finish = 1;
                                }
                                
                            }
                            else
                            {
                                RS485_TX_finish = 0;
                            }
                            break;
                        default:
                            break;
                        }
                        memset(RS485_data,0,64);
                    }
                    else
                    {
                        RS485_TX_finish = 0x0;
                    }
            }
    }
    else
    {
         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;
                       }
                        
                    }
            }
    }
}
void BarCodeDataGet(void)
{
    if((mDataBufPtr1[0] == 0x59) && (mDataBufPtr1[1] == 0x59)&&(mDataBufPtr1[39] != 0x0))
    {
        memcpy(barcode_Msg,&mDataBufPtr1[6],34);
    }
}
uint8_t GetDataCompare(void)
{
    uint8_t result = 0;
    for(int i = 0;i<34;i++)
    {
        if(get_num_buf[i] == barcode_Msg[i] )
        {
            result = 0;
            // u8compareresult = 0;
        }
        else
        {
            result = 1;
            // u8compareresult = 1;
        }
        return result;
    }
}
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;
    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;
    return;
}
void Recv_Byte(void)
{
    int      i = 0;
    int      j = 0;
    uint32_t      len;

    readNum = Protocol_UartRead(mDataBufPtr + mDataBufLen, 1024 - mDataBufLen);
    
    if ( readNum > 0 )
    {
        mDataBufLen += readNum;

        while(mDataBufLen)
        {
            for(i = 0; i < mDataBufLen; i++)
            {
                if(i > 4)
                {
                    if((mDataBufPtr[i] == 0x4A ) && (mDataBufPtr[i - 1] == 0x4B))
                    {
                        if( i < 1)
                        {
                            break;
                        }
                        memset(BarCode, 0, sizeof(BarCode));
                        for(j = 0; j < i+1; j++)
                        {
                            BarCode[j] = mDataBufPtr[j];
                        }
                        break;
                    }
                }
                
            }

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