/* 
  https://www.reddit.com/r/FastLED/comments/1foiz9i/what_do_you_think_about_the_hsv_rgb_pr_for_fastled/
  https://github.com/FastLED/FastLED/pull/1726

  Original FastLED on the left. PR1726 on the right.
*/

#include <FastLED.h>
#include "fill_rainbow_circular-pr1726.h"

// `false`: typical idiomatic FastLED code
// `true` : a path less well trodden
#define USE_RAW_CONVERSION false

#define REVERSED false

#define NUM_LEDS 402

CRGB leds[NUM_LEDS];
CHSV* leds_hsv = (CHSV*) leds;

void setup() {
  FastLED.addLeds<WS2812B, 3, GRB>(leds, NUM_LEDS);
  Serial.begin(2000000);
}

void loop() {
  const int iterations = 1;
  static uint8_t hue = 0;

  uint32_t orig_us1 = micros();
  for (uint32_t i = 0; i < iterations; i++) {
    fill_rainbow_circular(&leds_hsv[0], 4, hue, REVERSED);
    fill_rainbow_circular(&leds_hsv[4], 12, hue, REVERSED);
    fill_rainbow_circular(&leds_hsv[16], 21, hue, REVERSED);
    fill_rainbow_circular(&leds_hsv[37], 29, hue, REVERSED);
    fill_rainbow_circular(&leds_hsv[66], 37, hue, REVERSED);
    fill_rainbow_circular(&leds_hsv[103], 45, hue, REVERSED);
    fill_rainbow_circular(&leds_hsv[148], 53, hue, REVERSED);
  }
  uint32_t orig_us2 = micros();

  uint32_t fix_us1 = micros();
  for (uint32_t i = 0; i < iterations; i++) {
    fill_rainbow_circular2(&leds_hsv[201], 4, hue, REVERSED);
    fill_rainbow_circular2(&leds_hsv[201 + 4], 12, hue, REVERSED);
    fill_rainbow_circular2(&leds_hsv[201 + 16], 21, hue, REVERSED);
    fill_rainbow_circular2(&leds_hsv[201 + 37], 29, hue, REVERSED);
    fill_rainbow_circular2(&leds_hsv[201 + 66], 37, hue, REVERSED);
    fill_rainbow_circular2(&leds_hsv[201 + 103], 45, hue, REVERSED);
    fill_rainbow_circular2(&leds_hsv[201 + 148], 53, hue, REVERSED);
  }
  uint32_t fix_us2 = micros();

  // convert framebuffer from CHSV to CRGB
  if ( ! USE_RAW_CONVERSION) {
    // using FastLED's usual hsv2rgb_rainbow() method
    for (auto i = 0; i < NUM_LEDS; i++)
      leds[i] = leds_hsv[i];
  } else {
    // using hsv2rgb_raw()
    for (auto i = 0; i < NUM_LEDS; i++)
      hsv2rgb_raw(leds_hsv[i], leds[i]);
  }

  FastLED.show();
  hue++;

  Serial.print(float(orig_us2 - orig_us1) / iterations);
  Serial.print("μs vs ");
  Serial.print(float(fix_us2 - fix_us1) / iterations);
  Serial.print("μs  % change: ");
  Serial.println(float(fix_us2 - fix_us1) / float(orig_us2 - orig_us1) * 100.f - 100.f);
}