/*
 * @Author: mypx
 * @Date: 2025-09-05 09:08:00
 * @LastEditTime: 2025-09-05 13:47:49
 * @LastEditors: mypx mypx_coder@163.com
 * @Description: 
 */
#ifndef __ETK_RINGBUFFER_H__
#define __ETK_RINGBUFFER_H__

#include <stdbool.h>
#include <stdint.h>
#include <string.h>

/**
 * Data type enumeration for ring buffer
 */
typedef enum
{
    ETK_RB_UINT16, ///< 16-bit unsigned integer
    ETK_RB_UINT32, ///< 32-bit unsigned integer
    ETK_RB_FLOAT,  ///< 32-bit floating point
    ETK_RB_DOUBLE  ///< 64-bit floating point
} EtkRingBufDataType;

/**
 * Ring buffer structure
 */
typedef struct
{
    void              *buffer;       ///< Buffer pointer
    int                size;         ///< Buffer size
    int                write_index;  ///< Current write position
    int                count;        ///< Actual data count
    EtkRingBufDataType data_type;    ///< Data type
    int                element_size; ///< Size of each element
} etk_ringbuffer_t;

/**
 * Initialize the ring buffer
 */
void etk_ringbuffer_init(etk_ringbuffer_t *rb, void *buffer, int size, EtkRingBufDataType data_type);

/**
 * Write functions for different data types
 */
void etk_ringbuffer_write_u16(etk_ringbuffer_t *rb, uint16_t value);
void etk_ringbuffer_write_u32(etk_ringbuffer_t *rb, uint32_t value);
void etk_ringbuffer_write_f32(etk_ringbuffer_t *rb, float value);
void etk_ringbuffer_write_f64(etk_ringbuffer_t *rb, double value);

/**
 * Get the number of elements in the ring buffer
 */
int etk_ringbuffer_get_count(const etk_ringbuffer_t *rb);

/**
 * Get data functions for different data types
 */
uint16_t etk_ringbuffer_get_data_u16(const etk_ringbuffer_t *rb, int index);
uint32_t etk_ringbuffer_get_data_u32(const etk_ringbuffer_t *rb, int index);
float    etk_ringbuffer_get_data_f32(const etk_ringbuffer_t *rb, int index);
double   etk_ringbuffer_get_data_f64(const etk_ringbuffer_t *rb, int index);

/**
 * Check ring buffer status
 */
bool etk_ringbuffer_is_full(const etk_ringbuffer_t *rb);
bool etk_ringbuffer_is_empty(const etk_ringbuffer_t *rb);

/**
 * Clear the ring buffer
 */
void etk_ringbuffer_clear(etk_ringbuffer_t *rb);

/**
 * Get the capacity of the ring buffer
 */
int etk_ringbuffer_get_capacity(const etk_ringbuffer_t *rb);

/**
 * Peek functions for different data types (without modifying buffer state)
 */
uint16_t etk_ringbuffer_peek_u16(const etk_ringbuffer_t *rb, int index);
uint32_t etk_ringbuffer_peek_u32(const etk_ringbuffer_t *rb, int index);
float    etk_ringbuffer_peek_f32(const etk_ringbuffer_t *rb, int index);
double   etk_ringbuffer_peek_f64(const etk_ringbuffer_t *rb, int index);

#endif // ETK_RINGBUFFER_H
