#include "queue.h"

///   front   ...         rear      数据方向 ->
/* 队列的顺序存储结构(循环队列) */

can_queue_tag can_tx_queue;
can_queue_tag can_rx_queue;

/****************************************************
 *  函 数 名：init_queue
 *  函数功能：初始化队列
 *  入口参数：无
 *  说    明：
 ****************************************************/
void queue_init(p_can_queue_tag p_queue)
{                                      /* 构造一个空队列Q */
    p_queue->head = p_queue->tail = 0; /*空队列*/
    p_queue->count                = 0;
}

/****************************************************
 *  函 数 名：is_queue_empty
 *  函数功能：查询队列是否为空
 *  入口参数：Q 队列
 *  说    明：空队列，返回SUCCESS；否则返回ERROR
 ****************************************************/
uint8_t queue_empty(p_can_queue_tag p_queue)
{ /* 若*/
    return p_queue->count == 0;
}

uint8_t queue_full(p_can_queue_tag p_queue)
{ /* 若*/
    return p_queue->count == MAX_QSIZE;
}

/****************************************************
 *  函 数 名：queue_length
 *  函数功能：初始化长度
 *  入口参数：Q 队列
 *  说    明：
 ****************************************************/
uint16_t queue_length(can_queue_tag p_queue)
{ /* 返回Q的元素个数，即队列的长度 */
    return (p_queue.tail - p_queue.head + MAX_QSIZE) % MAX_QSIZE;
}

/****************************************************
 *  函 数 名：get_head
 *  函数功能：获取对头数据
 *  入口参数：Q 队列
 *  说    明：
 ****************************************************/
uint8_t get_head(
    can_queue_tag *p_queue,
    pdu_tag       *e)
{                                       /* 若队列不空，则用e返回Q的队头元素，并返回OK；否则返回ERROR*/
    if (p_queue->head == p_queue->tail) /* 队列空 */
        return Q_ERR;
    *e = p_queue->can_message[p_queue->head];

    p_queue->head = (p_queue->head + 1) % MAX_QSIZE;
    return Q_OK;
}

/****************************************************
 *  函 数 名：insert_queue
 *  函数功能：队列插入数据
 *  入口参数：Q 待插入队列    e 待插入数据
 *  说    明：
 ****************************************************/
QUEUE_STATUS en_queue(p_can_queue_tag p_queue,
                      pdu_tag         data)
{
    if (queue_full(p_queue))
        return Q_FULL;
    p_queue->count++;
    p_queue->can_message[p_queue->head] = data;
    p_queue->head                       = (p_queue->head + 1) % MAX_QSIZE;
    return Q_OK;
    /* 插入元素e为Q的新的队尾元素 */
    // if ((p_queue->tail + 1) % MAX_QSIZE == p_queue->head) /* 队列满 */
    //     return ERROR;
    // p_queue->can_message[p_queue->tail] = e;
    // p_queue->tail                       = (p_queue->tail + 1) % MAX_QSIZE;
    // return SUCCESS;
}

QUEUE_STATUS de_queue(p_can_queue_tag p_queue,
                      p_pdu_tag       p_data)
{ /* 插入元素e为Q的新的队尾元素 */
    // if ((p_queue->tail + 1) % MAX_QSIZE == p_queue->head) /* 队列满 */
    //     return ERROR;
    // p_queue->can_message[p_queue->tail] = e;
    // p_queue->tail                       = (p_queue->tail + 1) % MAX_QSIZE;
    // return SUCCESS;
    if (queue_empty(p_queue))
        return Q_EMPTY;
    *p_data       = p_queue->can_message[p_queue->tail];
    p_queue->tail = (p_queue->tail + 1) % MAX_QSIZE;
    p_queue->count--;

    return Q_OK;
}