
#include "asr_config.h"
#include <stdio.h>
extern volatile unsigned char f_asr_response;
extern unsigned char f_asr_wakeup;
extern volatile unsigned int asr_wakeup_tick_timer;

#ifdef VOICE_POWER_MARK
//语音识别控制
static bool voiceControl = true;
#endif

#ifdef PLAY_POWER_MARK
//提示音播放控制
static bool playControl = true;
#endif

#ifdef PLAY_POWER_MARK
/**
  \brief    如果有需求“打开/关闭语音播报”，可以通过令playControl = false关闭提示音播放
  \param    Null
  \return   true/false
  \note          
 */
static bool asr_check_play_power()
{
    if (!playControl)
    {
        f_asr_response = 0;
#if APP_LOG_ENABLE
        printf("The beep has been turned off\n");
#endif
        return false;
    }
    return true;
}
#endif

#ifdef VOICE_POWER_MARK
/**
  \brief    语音控制开关，当voiceControl = false的时候，只有唤醒词能被识别
  \param    Null
  \return   true/false
  \note          
 */
static bool asr_check_asr_power()
{
    if (!voiceControl)
    {
        //如有需要还可以播放提示音用于提醒，比如“请先打开语音控制”
        //f_asr_response = ***;
#if APP_LOG_ENABLE
        printf("Voice control has been turned off\n");
#endif
        return false;
    }
    return true;
}
#endif

/**
  \brief      播放相关提示音
  \param[in]   播放指令的名称
  \return Null
  \note          
 */
void asr_readme_play(unsigned char asr_play_id)
{
    //  unsigned char temp_id = 0;
    /*   for (; temp_id < WNVC_BUFF_TAB_NUM; temp_id++)
    {
        if (0 == memcmp(asr_play_id, (char *)wnvc_buffer_tab[temp_id].buffer,
                        strlen((char *)wnvc_buffer_tab[temp_id].buffer)))
        {
            break;
        }
    }*/
    if (f_asr_response < WNVC_BUFF_TAB_NUM)
    {
        //播放 f_asr_response 对应序号的提示音
        f_asr_response = asr_play_id;
    }

#if APP_LOG_ENABLE
    printf("ReadmePlay ID: %d\n", f_asr_response);
#endif
}

/**
  \brief      获取发送的串口指令长度
  \param[in]  发送的数据起始地址  
  \return     发送串口指令的长度
  \note          
 */
unsigned char get_send_data_len(unsigned char *dat)
{
    unsigned char len = 0;
    unsigned char mark = 0;

    for (; len < SEND_UART_DATA_LEN; len++)
    {
        if (dat[len] == 0x00)
        {
            mark++;
        }
        else
        {
            mark = 0;
        }

        if (mark >= 5)
        {
            len -= mark - 1;
            break;
        }
    }
    return len;
}
/**
  \brief      调用该函数发送串口数据和播放提示音
  \param[in]   data：所识别指令对应参数 
  \return  Null
  \note          
 */
static void send_buf_play_prompt(ASR_LOGIC data)
{
    unsigned char buf_len = 0;
    if (data._send_uart)
    {
        //如果识别后有串口输出，则获取数据长度
        buf_len = get_send_data_len((unsigned char *)data._send_uart);
        if (buf_len)
        {
            //发送串口指令
            app_uart_tx((unsigned char *)data._send_uart, buf_len); //SEND_UART_DATA_LEN
        }
    }

#ifdef PLAY_POWER_MARK
    static unsigned char play_flag = 0;
    if (!memcmp((unsigned char *)data._asr_result, (const char *)PLAY_POWER_ON, strlen((const char *)PLAY_POWER_ON)))
    {
        play_flag = 0;
        playControl = true;
#if APP_LOG_ENABLE
        printf("Open the play\n");
#endif
    }
    if (!memcmp((unsigned char *)data._asr_result, (const char *)PLAY_POWER_OFF, strlen((const char *)PLAY_POWER_OFF)))
    {
        playControl = false;
#if APP_LOG_ENABLE
        printf("Close play\n");
#endif
    }
#endif

    if (data._asr_response)
    {
        //如果有播放提示音，_asr_response 不为零，则播放对应提示音
        asr_readme_play(data._asr_response);
#ifdef PLAY_POWER_MARK
        //如果当前语音播放是关闭的，则将 f_asr_response 清零，不播放提示音
        if (!play_flag && !playControl)
        {
            play_flag = 1;
        }
        else
        {
            asr_check_play_power();
        }
#endif
    }
}
/**
  \brief      唤醒动作
  \param[in]   data：所识别指令对应参数
  \return Null
  \note          
 */
static void asr_wakeup_cmd(ASR_LOGIC data)
{
#if APP_LOG_ENABLE
    printf("Wakeup:%s\n", data._asr_result);
#endif
    f_asr_wakeup = 1;          //识别唤醒词，将唤醒标志位置一
    asr_wakeup_tick_timer = 0; //设定唤醒时间计时变量，唤醒后将该变量清零
    send_buf_play_prompt(data);
}

/**
  \brief      识别非唤醒词
  \param[in]   [in]   data：所识别指令对应参数
  \return Null
  \note          
 */
static void asr_action_cmd(ASR_LOGIC data)
{
    if (f_asr_wakeup)
    {
        asr_wakeup_tick_timer = 0; //如果在唤醒状态，识别了控制指令则重新计时唤醒时间
#ifdef VOICE_POWER_MARK
        if (voiceControl)
        {
#endif
            send_buf_play_prompt(data);
#ifdef VOICE_POWER_MARK
        }
        else
        {
#if APP_LOG_ENABLE
            asr_readme_play(VOICE_POWER_FLAG_PLAY);
            printf("Please turn on the voice first..\n");
#endif
        }
#endif

#ifdef VOICE_POWER_MARK
        if (!memcmp((unsigned char *)data._asr_result, (const char *)VOICE_POWER_ON, strlen((const char *)VOICE_POWER_ON)))
        {
#if APP_LOG_ENABLE
            printf("Open the voice\n");
#endif
            if (!voiceControl)
            {
                send_buf_play_prompt(data);
            }
            voiceControl = true;
        }
        if (!memcmp((unsigned char *)data._asr_result, (const char *)VOICE_POWER_OFF, strlen((const char *)VOICE_POWER_OFF)))
        {
            voiceControl = false;
#if APP_LOG_ENABLE
            printf("Close voice\n");
#endif
        }
#endif

#if APP_LOG_ENABLE
        printf("Reset time\n");
#endif
    }
    else
    { //在非唤醒状态，识别非唤醒词则不作处理
#if APP_LOG_ENABLE
        printf("Not wake up\n");
#endif
    }
}

/**
  \brief       判断识别的是哪一条指令
  \param[in]   识别结果
  \return Null
  \note         
 */
int asr_deal(const char *asrData)
{

    if (!asrData)
    {
        return 0;
    }
    unsigned char item = 0;         //asr_logic[]的下标，用于表示当前识别指令对应的结构体
    unsigned char wakeup_index = 0; //wakeup_cmd_data[]的下标，用于查询识别指令是否是唤醒词

#if APP_LOG_ENABLE
    //识别结果打印
    printf("\nASR Result: %s\r\n", asrData);
#endif

    for (; item < ASR_CMD_INDEX; item++)
    {
        //确认识别结果是哪一条指令
        if (strcmp(asrData, (const char *)asr_logic[item]._asr_result) == 0)
        {
            break;
        }
    }

    if (item >= ASR_CMD_INDEX)
        return 0;

    for (; wakeup_index < ASR_WAKE_INDEX; wakeup_index++)
    {
        //确认当前识别结果是否是唤醒词
        if (strcmp(asrData, (const char *)&wakeup_cmd_data[wakeup_index]) == 0)
        {
			asr_logic[item]._asr_response= rand()%2+4;
            asr_wakeup_cmd(asr_logic[item]);
            return 1;
        }
    }

    //如果识别结果不是唤醒词，则为其他识别指令
    asr_action_cmd(asr_logic[item]);

    return 1;
}

/**
  \brief       数组比较
  \param[in]   接收到的数据
  \param[in]   设定的数据
  \param[in]   接收到的数据长度
  \return 0：不相同 /  1：相同
  \note         
 */
static unsigned char check_rcv_data_buf(unsigned char *dat, unsigned char *dest, unsigned char bufLen)
{
    unsigned char *prt_dat = dat;
    unsigned char *ptr_dest = dest;

    unsigned char i = 0;
    for (; i < bufLen; i++)
    {
        if (prt_dat[i] != ptr_dest[i])
        {
            return 1;
        }
    }
    /*
    while (prt_dat && ptr_dest)
    {
        if (*prt_dat++ != *ptr_dest++)
        {
            return 1;
        }
    }
    */
    return 0;
}

/**
  \brief       对接收到的数进行处理
  \param[in]   接收到的数据
  \param[in]   数据长度
  \return NULL
  \note         
 */
static void asr_rcv_data_deal(unsigned char *dat, unsigned char bufLen)
{
    if (!bufLen)
    {
#if APP_LOG_ENABLE
        printf("Data Err\n");
#endif
        return;
    }

    unsigned char item = 0;

    for (; item < RCV_UART_DATA_NUM; item++)
    {
        //将接收到的串口指令与设定好的数据对比
        if (!check_rcv_data_buf(dat, rcv_uart_logic[item]._rcv_uart, bufLen))
        {
            if (rcv_uart_logic[item]._rcv_response)
            {
                //接收到的串口指令有对应的提示音，则播放提示音
                asr_readme_play(rcv_uart_logic[item]._rcv_response);
                break;
            }
        }
    }
    return;
}

/**
  \brief       Process received data.
  \return      NONE.
*/
void asr_sync_master_data()
{
    unsigned char *pbyte = NULL;
    unsigned char bufLen = 0;

    pbyte = app_uart_get_rx_data(&bufLen); //获取uart1接收数据
    if (pbyte)
    {                                     //接收到数据
        asr_rcv_data_deal(pbyte, bufLen); //处理接收到的数据，比如说要播放提示音等
    }

    pbyte = asr_rcv_log_uart_data_get(&bufLen); //获取uart0接收数据
    if (pbyte)
    {                               //接收到数据
        app_uart_tx(pbyte, bufLen); //将回去的uart0 rx数据通过uart1 tx发送出去
#if APP_LOG_ENABLE
        unsigned int i = 0;

        printf("\n-----------------------------------------------\n");
        printf("Forwarding UART_1: 0x");
        for (i = 0; i < bufLen; i++)
        {
            printf("%02X, ", pbyte[i]);
        }
        printf("\n-----------------------------------------------\n");
#endif
		 asr_rcv_data_deal(pbyte, bufLen);
    }
}

/**
  \brief       上电部分参数初始化：开机提示音
  \return NULL
  \note         
 */
void power_on_data_init()
{
    asr_readme_play(WELCOME_PLAY);
}

/**
  \brief       播放退出唤醒提示音
  \return NULL
  \note         
 */
void wake_down_play()
{
#if APP_LOG_ENABLE
    printf("\nASR Wakedown\n");
#endif
    asr_readme_play(WAKEDOWN_PLAY);
}