#define FASTLED_INTERRUPT_RETRY_COUNT 0
#include <FastLED.h> //https://github.com/FastLED/FastLED
#include <Bounce2.h> //https://github.com/thomasfredericks/Bounce2
#define DATA_PIN    0
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS    36
CRGB leds[NUM_LEDS];
#define BRIGHTNESS	128
#define FRAMES_PER_SECOND  120

#define BUTTON_GPIO2 2
Bounce debouncer = Bounce();

void setup() {
	delay(1000); // 1 second delay for recovery
	// tell FastLED about the LED strip configuration
	FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
	// set master brightness control
	FastLED.setBrightness(BRIGHTNESS);
	debouncer.attach(BUTTON_GPIO2,INPUT_PULLUP); // Attach the debouncer to a pin with INPUT_PULLUP mode
	debouncer.interval(25); // Use a debounce interval of 25 milliseconds
}

uint8_t gPattern = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns

void loop()
{
	switch(gPattern){
	case 0:
		rainbow();
		break;
	case 1:
		confetti();
		break;
	case 2:
		juggle();
		break;
	case 3:
		backlight();
		break;
	}

	debouncer.update();
	if ( debouncer.fell() ) {
		if (gPattern < 3) {
			gPattern ++;   // change patterns
		}
		else {gPattern = 0;}
	}

	// send the 'leds' array out to the actual LED strip
	FastLED.show();
	// insert a delay to keep the framerate modest
	FastLED.delay(1000/FRAMES_PER_SECOND);

	// do some periodic updates
	EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow
}

void rainbow()
{
	// FastLED's built-in rainbow generator
	fill_rainbow( leds, NUM_LEDS, gHue, 7);
}

void confetti()
{
	// random colored speckles that blink in and fade smoothly
	fadeToBlackBy( leds, NUM_LEDS, 10);
	int pos = random16(NUM_LEDS);
	leds[pos] += CHSV( gHue + random8(64), 200, 255);
}

void juggle() {
	// eight colored dots, weaving in and out of sync with each other
	fadeToBlackBy( leds, NUM_LEDS, 20);
	byte dothue = 0;
	for( int i = 0; i < 8; i++) {
		leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
		dothue += 32;
	}
}

void backlight()
{
	fill_solid((CRGB*)leds, NUM_LEDS, CRGB::White);
}
