/* Gray modifications: 
 * Added a second ring
 * use millis instead of delay
 * add 3 different simultaneous patterns
 * demonstrate using segments of the pixels
/*
 * Arduino Sketch for controlling an Adafruit NeoPixel Jewel
 * to display a red comet light effect, excluding the center LED.
 * The comet runs anticlockwise.
 *
 * Assumptions:
 * - NeoPixel Jewel is connected to pin D6 of the Arduino Nano.
 * - The circuit is powered appropriately.
 */
#include <Adafruit_NeoPixel.h>
#define PIN_PIXELS     6  // Pin where the NeoPixel is connected
#define DELAY_BLINK_MS 1000
#define DELAY_FADE_MS  13
#define DELAY_COMET_MS 75 // Time (in milliseconds) between pixel updates
#define DELAY_RANDOM_MS 200
#define CENTER_START   0
#define CENTER_LENGTH  1
#define CENTER_LAST    (CENTER_START+CENTER_LENGTH-1)
#define RING1_START    (CENTER_START+CENTER_LENGTH)
#define RING1_LENGTH   6
#define RING1_LAST     (RING1_START+RING1_LENGTH-1)
#define RING2_START    (RING1_START+RING1_LENGTH)
#define RING2_LENGTH   16
#define RING2_LAST     (RING2_START+RING2_LENGTH-1)
#define NUMPIXELS      (CENTER_LENGTH+RING1_LENGTH+RING2_LENGTH)
Adafruit_NeoPixel pixels(NUMPIXELS, PIN_PIXELS, NEO_GRB + NEO_KHZ800);
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pixels.begin(); // Initialize the NeoPixel library.
  pixels.show();  // Initialize all pixels to 'off'.
}
void loop() {
  boardBlink();
  fadeCenter();
  cometEffect();
  randomOuter();
}
void boardBlink() {
  static unsigned long lastChangeMs;
  static bool blinker;
  if(millis() - lastChangeMs < DELAY_BLINK_MS) return;
  lastChangeMs = millis();
  blinker = !blinker;
  digitalWrite(LED_BUILTIN, blinker);
}
void fadeCenter() {
  static unsigned long lastChangeMs;
  static uint8_t counter;
  if(millis() - lastChangeMs < DELAY_FADE_MS) return;
  lastChangeMs = millis();
  counter++;
  uint8_t col = Adafruit_NeoPixel::sine8(counter);
  uint32_t color = pixels.Color(col, col, col);
  pixels.setPixelColor(CENTER_START, color);
  pixels.show();
  
}
void cometEffect() {
  static unsigned long lastChangeMs;
  static int head = 0;
  static int tail = -2;
  if(millis() - lastChangeMs < DELAY_COMET_MS) return;
  lastChangeMs = millis();
  // Turn off the tail pixel
  if (tail >= 0) {
    pixels.setPixelColor(RING1_START+tail, pixels.Color(0, 0, 0));
  }
  // Set the head pixel to red
  pixels.setPixelColor(RING1_START+head, pixels.Color(255, 0, 0));
  // Move the head and tail anticlockwise
  head = (head + 1) % RING1_LENGTH;
  tail = (tail + 1) % RING1_LENGTH;
  pixels.show();
}
void randomOuter() {
  static unsigned long lastChangeMs;
  static int lastOn = RING2_START;
  
  if(millis() - lastChangeMs < DELAY_RANDOM_MS) return;
  lastChangeMs = millis();
  pixels.setPixelColor(RING2_START+lastOn, pixels.Color(0, 0, 0));
  lastOn = random(RING2_LENGTH);
  pixels.setPixelColor(RING2_START+lastOn, pixels.Color(0, 0, 255));
  pixels.show();
}