#include <Adafruit_NeoPixel.h>
#include <SPI.h>
#include "button.h"
button btn1(9);    // указываем пин кнопки включения/выключения света 
button btn2(12);    // указываем пин кнопки включения/выключения эффектов
boolean button_state; // текущее состояние ленты по кнопке свет вкл/выкл
boolean button_effect; // текущее состояние ленты по кнопке эффектов
#define PIN_PHOTO_SENSOR A0
int pirPin1 = 3;
int pirPin2 = 5;
#define LED_COUNT 16
#define LED_PIN 7

Adafruit_NeoPixel LED_Ring = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void showStrip() {
   LED_Ring.show();
}
void setPixel(int Pixel, byte red, byte green, byte blue) {
   LED_Ring.setPixelColor(Pixel, LED_Ring.Color(red, green, blue));
}
void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < LED_COUNT; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

void RunningLights(byte red, byte green, byte blue, int WaveDelay) {
  int Position=0; 
  for(int j=0; j<LED_COUNT*2; j++)
  {
      Position++; // = 0; //Position + Rate;
      for(int i=0; i<LED_COUNT; i++) {
        setPixel(i,((sin(i+Position) * 127 + 128)/255)*red,
                   ((sin(i+Position) * 127 + 128)/255)*green,
                   ((sin(i+Position) * 127 + 128)/255)*blue);
      }
     
      showStrip();
      delay(WaveDelay);
  }
}
void Fire(int Cooling, int Sparking, int SpeedDelay) {
  static byte heat[LED_COUNT];
  int cooldown;
 
  // Step 1.  Cool down every cell a little
  for( int i = 0; i < LED_COUNT; i++) {
    cooldown = random(0, ((Cooling * 10) / LED_COUNT) + 2);
   
    if(cooldown>heat[i]) {
      heat[i]=0;
    } else {
      heat[i]=heat[i]-cooldown;
    }
  }
 
  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for( int k= LED_COUNT - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
  }
   
  // Step 3.  Randomly ignite new 'sparks' near the bottom
  if( random(255) < Sparking ) {
    int y = random(7);
    heat[y] = heat[y] + random(160,255);
    //heat[y] = random(160,255);
  }

  // Step 4.  Convert heat to LED colors
  for( int j = 0; j < LED_COUNT; j++) {
    setPixelHeatColor(j, heat[j] );
  }

  showStrip();
  delay(SpeedDelay);
}

void setPixelHeatColor (int Pixel, byte temperature) {
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round((temperature/255.0)*191);
 
  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
  heatramp <<= 2; // scale up to 0..252
 
  // figure out which third of the spectrum we're in:
  if( t192 > 0x80) {                     // hottest
    setPixel(Pixel, 255, 255, heatramp);
  } else if( t192 > 0x40 ) {             // middle
    setPixel(Pixel, 255, heatramp, 0);
  } else {                               // coolest
    setPixel(Pixel, heatramp, 0, 0);
  }
}


void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);   
  pinMode(pirPin1, INPUT);
  pinMode(pirPin2, INPUT);
  button_state=false;
  LED_Ring.begin(); 
}

void button_press(){
      button_state=!button_state;
      if (button_state==true){
        digitalWrite(13, HIGH);
        for (int i = 0; i < LED_COUNT; i++){
          LED_Ring.setPixelColor(i, LED_Ring.Color(255,255, 0));
          LED_Ring.show();
        };
      } else {
        digitalWrite(13, LOW);
        for (int i = 0; i < LED_COUNT; i++){
          LED_Ring.setPixelColor(i, LED_Ring.Color(0,0, 0));
          LED_Ring.show();
        };        
      };
      delay(1000);
}
// показываем всякие эффекты, пока снова не нажманута любая кнопка
void button_effect_press(){
  int randLed;
  int randR;
  int randG;
  int randB;
  int effectR=random(0, 3);
  Serial.print("effect:");
  Serial.println(effectR);
  while(true){
    if (btn1.click()) {break;};
    if (btn2.click()) {break;};
    if (effectR==0){
      RunningLights(0xff,0,0, 50);        // red
      RunningLights(0xff,0xff,0xff, 50);  // white
      RunningLights(0,0,0xff, 50);        // blue    
    };
    if (effectR==1){
      randLed = random(0, LED_COUNT);
      randR = random(0, 255);
      randG = random(0, 255);
      randB = random(0, 255);
      LED_Ring.setPixelColor(randLed, LED_Ring.Color(randR,randG, randB));
      LED_Ring.show();
      delay(100);
    };
    if (effectR==2){
      Fire(55,120,15);
    };
  }
}  
void sleep(int ms){
  unsigned long time_old; 
  time_old = millis();
  while(true){
    if (btn1.click()) {button_press();};
    if ((millis()- time_old) >= ms){
      break;
    }
  };
}
void loop() {
  while(true){
    if (btn1.click()) {button_press();}; //нажата кнопка включения-выключения света
    if (btn2.click()) {delay(1000);button_effect_press();}; //нажата кнопка включения спецэффектов

    int light_level = analogRead(PIN_PHOTO_SENSOR); // если >300, то считаем что и так светло
    light_level=100; // для отладки - потом убрать!

    int move1 = digitalRead(pirPin1);
    int move2 = digitalRead(pirPin2);
    if ((move1 == HIGH) or (move2 == HIGH)){
      if (move1==HIGH){Serial.println("move1");};
      if (move2==HIGH){Serial.println("move2");};
      if (button_state==false){  // если свет не включен кнопкой
        if (light_level<250){    // если на леснице темно
          for (int i = 0; i < LED_COUNT; i++){
            if (move1 == HIGH){LED_Ring.setPixelColor(i, LED_Ring.Color(255, 0, 0));};
            if (move2 == HIGH){LED_Ring.setPixelColor(LED_COUNT-i-1, LED_Ring.Color(255, 0, 0));};
            LED_Ring.show();
            sleep(3);
            if (button_state==true){break;};
          };
          if (button_state==false){
            for (int i = 0; i < LED_COUNT; i++){
              LED_Ring.setPixelColor(i, LED_Ring.Color(255, 0, 0));
            };
            LED_Ring.show();
            sleep(10000);
            if (button_state==false){
              for (int i = 0; i < LED_COUNT; i++){
                if (move1 == HIGH){LED_Ring.setPixelColor(i, LED_Ring.Color(0, 0, 0)); };
                if (move2 == HIGH){LED_Ring.setPixelColor(LED_COUNT-i-1, LED_Ring.Color(0, 0, 0));};              
                LED_Ring.show();
                sleep(3);
                if (button_state==true){break;};
              };              
            };
          };
        }
      };
    };
  };

}