#include <Adafruit_NeoPixel.h>

#define PIN 2  // input pin Neopixel is attached to

#define NUMPIXELS 36  // number of neopixels in strip
#define STEPTIME 100 // in ms
#define TAILLENGTH 16
#define HOMES 16


Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel home = Adafruit_NeoPixel(HOMES, 3, NEO_GRB + NEO_KHZ800);



int redColor = 255;
int greenColor = 10;
int blueColor = 10;

int headPixel = 0;
double pixelsDim[NUMPIXELS];
double lastDeliver = TAILLENGTH * STEPTIME * -2;

void setup() {
  pinMode(4,INPUT_PULLUP);
  pinMode(A1,INPUT);

  randomSeed(analogRead(0));
  // Initialize the NeoPixel library.
  pixels.begin();
  Serial.begin(9600);
  for (int i = 0; i < NUMPIXELS; ++i) {
    pixelsDim[i] = 0;
  }
  home.begin();
  
}

uint32_t getColor(double dim) {
  return pixels.Color(double(redColor * dim), double(greenColor * dim), double(blueColor * dim));
}




void setColor(int pixel, double percent) {
  percent = percent;
  pixels.setPixelColor(pixel, getColor(percent));
}
bool stable = (digitalRead(4) == HIGH);
void loop() {
  double efficiency = (double)analogRead(A1)/1023.0;
  Serial.println(efficiency);
  double speed = (STEPTIME * 1/(efficiency*10+1));
  double minDim = stable ? 0.35 : 0.0;
  double animationStart = millis();
  double animationEnd = animationStart + speed;
  double step = 0;
  int tail = stable ? TAILLENGTH : float(TAILLENGTH * 0.5);
  while (step < 1){
    step = (double)(millis() - animationStart)/(double)speed;
    for (int i = headPixel - tail; i < headPixel; i++) {

      int pixel = i;
      if (pixel < 0) pixel = NUMPIXELS + pixel;
      double targetDim = max(minDim,(i - headPixel + tail) * (1.0/tail));
      double dim;
      if(step >= 1){
        dim = targetDim;
        pixelsDim[pixel] = dim;
      } else {
        dim = pixelsDim[pixel] - ((double)(step) * (pixelsDim[pixel] - targetDim));
      }
      setColor(pixel, dim);
    }
    
    
    
    pixels.show();
  }


  int homesToShow = float(efficiency*HOMES);

  // bool show = (stable || millis() < lastDeliver + (speed*0.5 *TAILLENGTH)) ? true : false;
  bool show = true;

  for (int i = 0; i < HOMES; i++) {
    if(i > homesToShow || !show){
      home.setPixelColor(i, getColor(0));
    } else {
      if(stable){
        home.setPixelColor(i, getColor(1));
      } else {
        
        int rand = random(float(1+2*homesToShow));
        if(rand == 0){
          home.setPixelColor(i, getColor((double)random(3,9)/10));
        } else {
          home.setPixelColor(i, getColor(0.9));
        }
      }
    }
    home.show();
  }

  
  headPixel++;
  if (headPixel >= NUMPIXELS) {
    stable = (digitalRead(4) == HIGH);
    lastDeliver = millis();
    headPixel = 0;
  }
}