#include "rgb_effect.h"

#include <string.h>


/**
 * @brief 根据名称查找灯效
 * 
 * @param eff 灯效数组
 * @param count 灯效数量
 * @param name 灯效名称
 * @return const rgb_effect_t* 找到的灯效指针，未找到则返回RT_NULL
 */
const rgb_effect_t *rgb_effect_find_by_name(const rgb_effect_t *eff, uint16_t count, const char *name)
{
    if (!eff || count == 0 || !name) {
        rt_kprintf("func: %s, eff or count or name is NULL.\r\n", __func__);
        return RT_NULL;
    }

    for (uint16_t i = 0; i < count; i++) {
        if (eff[i].name && strcmp(eff[i].name, name) == 0) {
            return &eff[i];
        }
    }

    return RT_NULL;
}

/**
 * @brief 获取灯效指定帧的颜色数据
 * 
 * @param effect 灯效参数
 * @param frame_index 帧索引
 * @return const uint32_t* 帧颜色数据指针，未找到则返回RT_NULL
 */
const uint32_t *rgb_effect_get_frame(const rgb_effect_t *eff, uint16_t frame_index)
{
    if (!eff || !eff->frames || eff->led_count == 0 || eff->frame_count == 0) {
        rt_kprintf("func: %s, eff or eff->frames or eff->led_count or eff->frame_count is NULL.\r\n", __func__);
        return RT_NULL;
    }
    if (frame_index >= eff->frame_count) {
        rt_kprintf("func: %s, frame_index out of range.\r\n", __func__);
        return RT_NULL;
    }

    uint32_t offset = (uint32_t)frame_index * eff->led_count;

    return &eff->frames[offset];
}

/**
 * @brief 切换到下一个或上一个灯效
 * 
 * @param eff 灯效数组
 * @param count 灯效数量
 * @param cur 当前灯效指针
 * @param forward 是否切换到下一个，true为下一个，false为上一个
 * @return const rgb_effect_t* 切换后的灯效指针，未找到则返回RT_NULL
 */ 
const rgb_effect_t *rgb_effect_switch(const rgb_effect_t *eff, uint16_t count, const rgb_effect_t *cur, bool forward)
{
    if (!eff || count == 0 || !cur) {
        rt_kprintf("func: %s, eff or count or cur is NULL.\r\n", __func__);
        return RT_NULL;
    }
    int16_t index = -1;
    for (uint16_t i = 0; i < count; i++) {
        if (&eff[i] == cur) {
            index = (int16_t)i;
            break;
        }
    }
    if (index < 0 && cur->name) {
        for (uint16_t i = 0; i < count; i++) {
            if (eff[i].name && strcmp(eff[i].name, cur->name) == 0) {
                index = (int16_t)i;
                break;
            }
        }
    }
    if (index < 0) {
        rt_kprintf("func: %s, current effect not found.\r\n", __func__);
        return RT_NULL;
    }

    uint16_t n = forward ? (uint16_t)((index + 1) % count) : (uint16_t)((index + count - 1) % count);
    
    return &eff[n];
}

/**
 * @brief 切换到下一个灯效
 * 
 * @param eff 灯效数组
 * @param count 灯效数量
 * @param cur 当前灯效指针
 * @return const rgb_effect_t* 切换后的灯效指针，未找到则返回RT_NULL
 */
const rgb_effect_t *rgb_effect_next(const rgb_effect_t *eff, uint16_t count, const rgb_effect_t *cur)
{
    return rgb_effect_switch(eff, count, cur, true);
}

/**
 * @brief 切换到上一个灯效
 * 
 * @param eff 灯效数组
 * @param count 灯效数量
 * @param cur 当前灯效指针
 * @return const rgb_effect_t* 切换后的灯效指针，未找到则返回RT_NULL
 */
const rgb_effect_t *rgb_effect_prev(const rgb_effect_t *eff, uint16_t count, const rgb_effect_t *cur)
{
    return rgb_effect_switch(eff, count, cur, false);
}


