#include "tim.h"
#include "common.h"
#include "string.h"
#include "soft_obstacle.h"


int findStrInArray( uint8_t *array, int aLen, const char *str )
{
    int strLen = strlen( str );
    uint8_t s1 = str[0];

    if ( aLen < strLen )
        return 0;

    for ( int i = 0; i < aLen; i++ )
    {
        if ( array[i] == s1 )
        {
            if ( memcmp( &array[i], str, strLen ) == 0 )
                return 1;
        }
    }
    return 0;
}

void buf2int( int *tint, unsigned char *buf )
{
    int i;
    unsigned char *p1 = ( unsigned char * )tint;
    unsigned char *p3 = buf;
    for ( i = 0; i < 4; i++ )
    {
        *p1 = *p3;
        p1++;
        p3++;
    }
}


/*****************************uint16从大到小排列*************************/
void u16t_buf_sort( uint16_t *arr, uint16_t length )
{
    if ( length < 2 )
    {
        return;
    }
    uint16_t num = 0, num1 = 0;
    uint16_t tmp = 0;
    for ( num = length - 1; num >= 1; num-- )
    {
        for ( num1 = 0; num1 <= num - 1; num1++ )
        {
            if ( *( arr + num1 ) > *( arr + num1 + 1 ) )
            {
                tmp = *( arr + num1 );
                *( arr + num1 ) = *( arr + num1 + 1 );
                *( arr + num1 + 1 ) = tmp;
            }
        }
    }
}

/*****************************恩曌&莫之比雷达排序************************/
void mimomocib_buf_sort( mimo_part_radar *arr, uint16_t length )
{
    if ( length < 2 )
    {
        return;
    }
    uint16_t num = 0, num1 = 0;
    mimo_part_radar tmp;
    for ( num = length - 1; num >= 1; num-- )
    {
        for ( num1 = 0; num1 <= num - 1; num1++ )
        {
            if ( ( ( arr + num1 )->Distance ) > ( ( arr + num1 + 1 )->Distance ) )
            {
                tmp = *( arr + num1 );
                *( arr + num1 ) = *( arr + num1 + 1 );
                *( arr + num1 + 1 ) = tmp;
            }
        }
    }
}

/****************************short 类型放到buf中***************/
void short2buf( unsigned char *buf, short *tshort )
{
    int i;
    unsigned char *p1 = ( unsigned char * )tshort;
    unsigned char *p3 = buf;
    for ( i = 0; i < 2; i++ )
    {
        *p3 = *p1;
        p1++;
        p3++;
    }
}

/*
int转hex转string
*/
void char_to_hex_string( unsigned char *cdata, short lenc, char *sbuf, short lens, char *ES )
{
    short tmp_lens = lens;

    for ( int i = 0 ; i < lenc  && tmp_lens >= 2 ; i++ )
    {
        char hight = ( cdata[i] >> 4 ) & 0x0f;
        char low = cdata[i] & 0x0f;

        if ( hight > 9 )
            sbuf[lens - tmp_lens] = 'A' + hight - 10;
        else
            sbuf[lens - tmp_lens] = '0' + hight;
        tmp_lens--;

        if ( low > 9 )
            sbuf[lens - tmp_lens] = 'A' + low - 10;
        else
            sbuf[lens - tmp_lens] = '0' + low;
        tmp_lens--;
    }

    int i = 0;
    //尾缀
    for ( ; tmp_lens > 0 ; tmp_lens-- )
    {
        if ( *( ES + i ) != '\0' )
        {
            sbuf[lens - tmp_lens] = *( ES + i );
        }
        else
        {
            break;
        }
        i++;
    }
}



/*
@brief: 
  num: 整型数值
  str: 字符串地址
  radix：进制
*/
char* itoa( int num, char* str, int radix )
{
    char index[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //索引表
    unsigned unum;//存放要转换的整数的绝对值,转换的整数可能是负数
    int i = 0, j, k; //i用来指示设置字符串相应位，转换之后i其实就是字符串的长度；转换后顺序是逆序的，有正负的情况，k用来指示调整顺序的开始位置;j用来指示调整顺序时的交换。

    //获取要转换的整数的绝对值
    if ( radix == 10 && num < 0 ) //要转换成十进制数并且是负数
    {
        unum = ( unsigned ) - num; //将num的绝对值赋给unum
        str[i++] = '-'; //在字符串最前面设置为'-'号，并且索引加1
    }
    else unum = ( unsigned )num; //若是num为正，直接赋值给unum

    //转换部分，注意转换后是逆序的
    do
    {
        str[i++] = index[unum % ( unsigned )radix]; //取unum的最后一位，并设置为str对应位，指示索引加1
        unum /= radix; //unum去掉最后一位

    }
    while ( unum ); //直至unum为0退出循环

    str[i] = '\0'; //在字符串最后添加'\0'字符，c语言字符串以'\0'结束。

    //将顺序调整过来
    if ( str[0] == '-' ) k = 1; //如果是负数，符号不用调整，从符号后面开始调整
    else k = 0; //不是负数，全部都要调整

    char temp;//临时变量，交换两个值时用到
    for ( j = k; j <= ( i - 1 ) / 2; j++ ) //头尾一一对称交换，i其实就是字符串的长度，索引最大值比长度少1
    {
        temp = str[j]; //头部赋值给临时变量
        str[j] = str[i - 1 + k - j]; //尾部赋值给头部
        str[i - 1 + k - j] = temp; //将临时变量的值(其实就是之前的头部值)赋给尾部
    }

    return str;//返回转换后的字符串
}


char* Int2String(int num,char *str,uint8_t size)//10进制 
{
    int i = 0;//指示填充str 
    if(num<0)//如果num为负数，将num变正 
    {
        num = -num;
        str[i++] = '-';
    } 
    //转换 
    do
    {
        if(size>0) 
        {
            str[i++] = num%10+48;
        }
        size--;
        num /= 10; 
    }while(num);
    
    str[i] = '\0';
    
    //确定开始调整的位置 
    int j = 0;
    if(str[0]=='-')//如果有负号，负号不用调整 
    {
        j = 1;//从第二位开始调整 
        ++i;//由于有负号，所以交换的对称轴也要后移1位 
    }
    //对称交换 
    for(;j<i/2;j++)
    {
        //对称交换两端的值 其实就是省下中间变量交换a+b的值：a=a+b;b=a-b;a=a-b; 
        str[j] = str[j] + str[i-1-j];
        str[i-1-j] = str[j] - str[i-1-j];
        str[j] = str[j] - str[i-1-j];
    } 
    
    return str;//返回转换后的值 
}


/**
  * @file    Check_dev_link
  * @brief   检测设备连接状态
  * @param   dev 设备 ms 时间毫秒 p数据地址 size数据大小
  * @details 
  * @author  Zhang Sir 
 **/
void Check_dev_link(Connect_check *dev,uint16_t ms,char *p,uint16_t size)
{
    if(dev->connect_status == COMP_NOEXIST)
        return;
    
    dev->error_time = HAL_GetTick() - dev->recv_time;

    if (dev->connect_status == COMP_NORMAL && (dev->error_time > ms))
    {   
        if(p != NULL)
            memset(p, 0, size);

        dev->connect_status = COMP_LOST;
    }
}

/**
  * @file    Check_Timer_Ready
  * @brief   定时器循环检测
  * @param   
  * @details 
  * @author  Zhang Sir 
 **/
bool Check_Timer_Ready(uint32_t *time,uint16_t HZ)
{
    if(HAL_GetTick() - *time >= HZ)
    {
        *time = HAL_GetTick();
        return true;
    }
    return false;
}

int16_t math_cons_i16( int16_t value, int16_t min, int16_t max )
{
    return ( ( value ) < ( min ) ? ( min ) : ( ( value ) > ( max ) ? ( max ) : ( value ) ) );
}

//数组array是否为空，只有'\0'以及'0'
bool StrArrayNull( uint8_t *array, int aLen )
{
    for ( int i = 0; i < aLen; i++ )
    {
        if(array[i] != 0 && array[i] != '0')
            return false;
    }

    return true;
}

