 //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
 //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
 //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
-Adafruit_NeoPixel rim = Adafruit_NeoPixel(RIM_N, RIM_PIN, NEO_GRB + NEO_KHZ800);
+Adafruit_NeoPixel rimJob = Adafruit_NeoPixel(RIM_N, RIM_PIN, NEO_GRB + NEO_KHZ800);
 
 // define some colors.
-const uint32_t Red = rim.Color(255, 0, 0);
-const uint32_t Grn = rim.Color(0, 255, 0);
-const uint32_t Blu = rim.Color(0, 0, 255);
-const uint32_t Yel = rim.Color(128, 128, 0);
-const uint32_t Dead = rim.Color(0, 0, 0);
-
-// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
-// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
-// and minimize distance between Arduino and first pixel.  Avoid connecting
-// on a live circuit...if you must, connect GND first.
+#define RED_MAX 255
+#define GRN_MAX 220
+#define BLU_MAX 210
+#define LED_OFF 0 // makes it a litle brighter in the Console.  0 is fine, too.
+const uint32_t SweetLoveMakin = rimJob.Color(RED_MAX / 4, GRN_MAX / 6, BLU_MAX / 9);
+const uint32_t Red = rimJob.Color(RED_MAX, LED_OFF, LED_OFF);
+const uint32_t Yel = rimJob.Color(RED_MAX, GRN_MAX, LED_OFF);
+const uint32_t Grn = rimJob.Color(LED_OFF, GRN_MAX, LED_OFF);
+const uint32_t Blu = rimJob.Color(LED_OFF, LED_OFF, BLU_MAX);
+const uint32_t Dead = rimJob.Color(LED_OFF, LED_OFF, LED_OFF);
 
 void setup() {
   Serial.begin(115200);
 
   randomSeed(analogRead(0));
 
-  rim.begin(); // Initialize all pixels to 'off'
-  simulateButtonPress();
-  rim.show();
-  //  test(rim); // run through some tests
+  // Initialize all pixels to 'sweet love makin'
+  rimJob.begin();
+  for ( uint16_t i = 0; i < rimJob.numPixels(); i++ ) {
+    rimJob.setPixelColor(i, SweetLoveMakin);
+  }
+  rimJob.show();
+  delay(1000);
+
+  //  test(rimJob); // run through some tests
   Serial << "Light: startup complete." << endl;
 }
 
 void loop() {
-  // simulate a button press
-  // simulate button presses.  replace this with Button library to 4x GPIO pins.
-  static Metro buttonUpdate(1000UL);
-  if ( buttonUpdate.check() ) {
-    simulateButtonPress();
-    rim.show();
-    buttonUpdate.reset();
-  }
-
-  // update the rim
-  static Metro rimUpdate(RIM_UPDATE);
-  if ( rimUpdate.check() ) {
-    Serial << ".";
-    updateRule90(rim, RIM_DECAY_RATE);
-    rim.show();
-    rimUpdate.reset();
-  }
-
-}
-
-void simulateButtonPress() {
-  const uint16_t rimSegLength = floor((float)RIM_N / 4);
-
-  uint8_t button = random(0, 4); // pick a button
+
+  // simulate button presses.  replace this with Button library to 4x GPIO pins wired to Mega.
+  static Metro buttonTimer(500UL);
+  static boolean buttonHeld = true;
+  static uint8_t buttonPressed = 0; // pick a button
+
+  // flip-flop between pressed and not pressed.
+  if ( buttonTimer.check() ) {
+    if ( buttonHeld ) { // stop holding it.
+      buttonTimer.interval(random(420UL, 420UL * 2UL));
+      buttonTimer.reset();
+      buttonPressed = 4;
+      Serial << "Release." << endl;
+    } else { // press it
+      buttonTimer.interval(random(420UL / 2UL, 420UL));
+      buttonTimer.reset();
+      buttonPressed = random(0, 4); // pick button
+      Serial << "Press." << endl;
+    }
+    buttonHeld = !buttonHeld;
+  }
+
+  // update the rimJob
+  static Metro rimJobUpdate(RIM_UPDATE);
+  if ( rimJobUpdate.check() ) {
+    // compute the next step
+    updateRule90(rimJob, RIM_LED_TTL);
+
+    // check for buttons
+    if ( buttonHeld ) buttonPressPattern(buttonPressed);
+
+    // go to press
+    rimJob.show();
+    rimJobUpdate.reset();
+  }
+
+}
+
+void buttonPressPattern(uint8_t button) {
+  const uint16_t rimJobSegLength = floor((float)RIM_N / 4);
+
   switch (button) {
-      delay(1000);
-    case 0: buttonPressToRim(Red, 0, rimSegLength); break;
-    case 2: buttonPressToRim(Blu, rimSegLength, rimSegLength); break;
-    case 3: buttonPressToRim(Yel, rimSegLength * 2, rimSegLength); break;
-    case 1: buttonPressToRim(Grn, rimSegLength * 3, rimSegLength); break;
+    case 0: buttonPressToRim(Red, RED_SEG_OFFSET, rimJobSegLength); break;
+    case 2: buttonPressToRim(Blu, RED_SEG_OFFSET + rimJobSegLength, rimJobSegLength); break;
+    case 3: buttonPressToRim(Yel, RED_SEG_OFFSET + rimJobSegLength * 2, rimJobSegLength); break;
+    case 1: buttonPressToRim(Grn, RED_SEG_OFFSET + rimJobSegLength * 3, rimJobSegLength); break;
   }
 
 }
 
 void buttonPressToRim(const uint32_t color, uint16_t segStart, uint16_t segLength) {
-  Serial << F("Button.  Adding pixels from ") << segStart << F(" to ") << segStart + segLength - 1;
+  Serial << F("Button.  Adding pixels from ") << segStart << F(" to ") << segStart + segLength - 1 << ". Color: ";
   printColor(color);
-  Serial << endl;
-
-  // clear the segment
-  for ( uint16_t i = segStart + 1; i < segLength; i++ ) {
-    rim.setPixelColor(segStart + i, Dead);
-  }
-  // put down the color every other pixel
-  for ( uint16_t i = 0; i < segLength; i += 3 ) {
-    rim.setPixelColor(segStart + i, color);
+
+  // clear the segment and lay down this color
+  for ( int i = 1; i < segLength; i++ )  {
+    rimJob.setPixelColor((segStart + i) % RIM_N, color);
   }
 
 }


    // apply Rule 90
    if ( ps == Dead ) {
      color = adjustColor(ns, decay);
    } else if ( ns == Dead ) {
      color = adjustColor(ps, decay);
    } else {
      color = adjustColor(mergeColor(ps, ns), decay);
    }



// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

#include <Adafruit_NeoPixel.h>
#include <Streaming.h>
#include <Metro.h>
