/// @file five_bit_hd_gamma.h
/// Declares functions for five-bit gamma correction

#pragma once

#include <stdint.h>

#include "crgb.h"
#include "fl/force_inline.h"
#include "fl/namespace.h"

namespace fl {

enum FiveBitGammaCorrectionMode {
    kFiveBitGammaCorrectionMode_Null = 0,
    kFiveBitGammaCorrectionMode_BitShift = 1
};

// Applies gamma correction for the RGBV(8, 8, 8, 5) color space, where
// the last byte is the brightness byte at 5 bits.
// To override this five_bit_hd_gamma_bitshift you'll need to define
// FASTLED_FIVE_BIT_HD_BITSHIFT_FUNCTION_OVERRIDE in your build settings
// then define the function anywhere in your project.
// Example:
//  FASTLED_NAMESPACE_BEGIN
//  void five_bit_hd_gamma_bitshift(
//      uint8_t r8, uint8_t g8, uint8_t b8,
//      uint8_t r8_scale, uint8_t g8_scale, uint8_t b8_scale,
//      uint8_t* out_r8,
//      uint8_t* out_g8,
//      uint8_t* out_b8,
//      uint8_t* out_power_5bit) {
//        cout << "hello world\n";
//  }
//  FASTLED_NAMESPACE_END

void __builtin_five_bit_hd_gamma_bitshift(CRGB colors, CRGB colors_scale,
                                          uint8_t global_brightness,
                                          CRGB *out_colors,
                                          uint8_t *out_power_5bit);

// Exposed for testing.
uint8_t five_bit_bitshift(uint16_t r16, uint16_t g16, uint16_t b16,
                          uint8_t brightness, CRGB *out,
                          uint8_t *out_power_5bit);

#ifdef FASTLED_FIVE_BIT_HD_BITSHIFT_FUNCTION_OVERRIDE
// This function is located somewhere else in your project, so it's declared
// extern here.
extern void five_bit_hd_gamma_bitshift(CRGB colors, CRGB colors_scale,
                                       uint8_t global_brightness,
                                       CRGB *out_colors,
                                       uint8_t *out_power_5bit);
#else
FASTLED_FORCE_INLINE void five_bit_hd_gamma_bitshift(CRGB colors,
                                                     CRGB colors_scale,
                                                     uint8_t global_brightness,
                                                     CRGB *out_colors,
                                                     uint8_t *out_power_5bit) {
    __builtin_five_bit_hd_gamma_bitshift(
        colors, colors_scale, global_brightness, out_colors, out_power_5bit);
}
#endif // FASTLED_FIVE_BIT_HD_BITSHIFT_FUNCTION_OVERRIDE

// Simple gamma correction function that converts from
// 8-bit color component and converts it to gamma corrected 16-bit
// color component. Fast and no memory overhead!
// To override this function you'll need to define
// FASTLED_FIVE_BIT_HD_GAMMA_BITSHIFT_FUNCTION_OVERRIDE in your build settings
// and then define your own version anywhere in your project. Example:
//  FASTLED_NAMESPACE_BEGIN
//  void five_bit_hd_gamma_function(
//    uint8_t r8, uint8_t g8, uint8_t b8,
//    uint16_t* r16, uint16_t* g16, uint16_t* b16) {
//      cout << "hello world\n";
//  }
//  FASTLED_NAMESPACE_END
#ifdef FASTLED_FIVE_BIT_HD_GAMMA_FUNCTION_OVERRIDE
// This function is located somewhere else in your project, so it's declared
// extern here.
extern void five_bit_hd_gamma_function(CRGB color, uint16_t *r16, uint16_t *g16,
                                       uint16_t *b16);
#else
void five_bit_hd_gamma_function(CRGB color, uint16_t *r16, uint16_t *g16,
                                uint16_t *b16);
#endif // FASTLED_FIVE_BIT_HD_GAMMA_FUNCTION_OVERRIDE

} // namespace fl
