#include "FastLED.h"

// Staircase ilumination.
// Simulation for scenario with mono-color Hi-Power leds controlled by WS2811.
// Lack of libary with IC WS2811 with 3 external output (3 stairs light can be switch ON by one IC)
//                             ,o      \ . /  |xxxxxxxxxxxxx
//                           ,o        - O -  |xxxxxxxxxxx
//                         ,o          / ' \  |xxxxxxxxx
//                       ,o       .-----------'xxxxxxx
//                     ,o        |xxxxxxxxxxxxxxxxxx
//                   ,o          |xxxxxxxxxxxxxxxx
//                 ,o    \ . /   |xxxxxxxxxxxxxx
//               ,o      - O -   |xxxxxxxxxxxx
//             ,o        / ' \   |xxxxxxxxxx
//           ,o      .-----------'xxxxxxxx
//         ,o       |xxxxxxxxxxxxxxxxxxx
//       ,o         |xxxxxxxxxxxxxxxxx
//     ,o   \ . /   |xxxxxxxxxxxxxxx
//   ,o     - O -   |xxxxxxxxxxxxx
// ,o       / ' \   |xxxxxxxxxxx
//
// Still under construction. project for stairs where each NeoPixel represent each step light (mono) and including side string - along starecase.
// Im Unable to simulate mono lights, to see visual use DEMO = true. DEMO = false represent real IC transmission (so each NEOPIXEL represents 3 diffrent monochrome LED light.)
// My stairs - total 15 Stairs Green BrightLED connected to 5 IC WS2812B.
// Position each step is declared as constant.

//// EPS => PIN 2 -> PowerLDSs (IC WS2811) -> LED STRIP
// Pre set positions for PowerLeds,abs8
int MyBLP[] = {0,16,34,52,70,88,106,124,142,160,178,197,215,240,260,280};
#define HEIGHT 110         // simulator is too slow, I do not make whole lenght only first 100 LED's
#define WIDTH 1
#define NUM_LEDS 325      //310 is a real number     
#define MATRIX_TYPE 1     // Only for simulator
// LEDs pin
#define DATA_PIN 4
// LED brightness
#define BRIGHTNESS 255
// Define the array of leds
const boolean DEMO = false; // SyMULATE REAL IC's not just for display.
#define HighPowerLED 15  // Number of stairs / rockets

CRGB leds[NUM_LEDS];
//CRGB my_point[5];  
//int set_point[5];
int IC_WS2811 = 5;      //Number of IC, HighPowerLED div by 3 when 3 connected to ONE IC.

struct rakiet{
  int start;
  int pozycja;
  int cel;
  int predkosc;
  boolean doleciala;
  boolean zgasla;
  CRGB kolor;
};
struct meteo{
  int jasnoscMax;
  int jasnoscMin;
  int jasnosc;
  boolean rozjasniamy;
  boolean przyciemniamy;

};

rakiet rakieta[HighPowerLED+1]; // selected XX leds represents moving points (Plus ZERO)
meteo meteor[HighPowerLED+1]; // This LED is monochrome single outout from IC ws2812B, fixed position (draw as neo pixel on simulation) 


void zielone (int numer, byte jasnosc) {   // convert GREEN Lights -  3 LED connected to one IC WS2812B directly (FOR DISPLAY simulation USE DEMO=true)

if (DEMO == false) {
    if (numer % 3 == 1) leds[(numer-1)/3].r = jasnosc;  //1ST led at channel R
    if (numer % 3 == 2) leds[(numer-1)/3].g = jasnosc;  //2ND led at channel G
    if (numer % 3 == 0) leds[(numer-1)/3].b = jasnosc;  //3RD LED at channel B
  } else {
    leds[(numer-1)].g = jasnosc;  // FOR DISPLAY SIMULATION USE THIS FAKE FUNCTION - EACH Green LED connected to separate IC to channel G
}

}

void LightUP(){

  double sinusik;

  for (int czas = 1; czas < 330; czas++){
      // time is running .... lest start demo
      //Serial.println(czas);
      for (int a= 1; a<HighPowerLED+1; a++){
        
        if (rakieta[a].doleciala == false) {
          leds[rakieta[a].pozycja+IC_WS2811] =CRGB::Black;   // clear old point before rockets move (don't forget about extar leds)
          //   rocket is on the move.
          if (czas > rakieta[a].start) {
            //   Rocket lunch time achived , lets count position
            sinusik = sin((double)(czas-rakieta[a].start)/rakieta[a].predkosc)*rakieta[a].cel;
            if (sinusik < rakieta[a].pozycja) { 
              rakieta[a].doleciala = true;  // sinus function already start to fallen, means reach target. (not true - always one below target as neve get 100% value)
              leds[rakieta[a].pozycja+IC_WS2811] = rakieta[a].kolor; 
            }
              else { 
                rakieta[a].pozycja = (int)sinusik;
                leds[rakieta[a].pozycja+IC_WS2811] = rakieta[a].kolor; 
                leds[rakieta[a].pozycja+IC_WS2811].fadeToBlackBy(random8(30));  //Sparky rockets
               //; leds[rakieta[a].pozycja+5].r = leds[rakieta[a].pozycja+5].r - random8(30);
              }
          
          }
        } else {
          if ( rakieta[a].zgasla == false) {  // else wiec doleciala = true , ale zgasla ciagle false.
            if (rakieta[a].kolor.g < 100) rakieta[a].kolor.g++;
            if (rakieta[a].kolor.g < 100) rakieta[a].kolor.g++;
            if (rakieta[a].kolor.b > 0) rakieta[a].kolor.b--;
            if (rakieta[a].kolor.b > 0) rakieta[a].kolor.b--;
            if (rakieta[a].kolor.b > 0) rakieta[a].kolor.b--;
            if (rakieta[a].kolor.b > 0) rakieta[a].kolor.b--;
            if (rakieta[a].kolor.r > 0) rakieta[a].kolor.r--;
            if (rakieta[a].kolor.r > 0) rakieta[a].kolor.r--;
            if (rakieta[a].kolor.r > 0) rakieta[a].kolor.r--;
            if (rakieta[a].kolor.r > 0) rakieta[a].kolor.r--;
            
            
            leds[rakieta[a].pozycja+IC_WS2811] = rakieta[a].kolor;
            if (rakieta[a].kolor == CRGB(0,100,0)){
                rakieta[a].zgasla = true; // color has been chande to dastination GREEN (0,50,0) time to stop change color and lets do dark :D
                meteor[a].rozjasniamy = true; // marker to meteor - mono LED to Bright UP and fallen rakieta.
            }
          }
        }
        if (meteor[a].rozjasniamy == true) {   ///this function need to be check - leds.g never above 50 and only CRGB::Green is fading.
              meteor[a].jasnosc = meteor[a].jasnosc+2;  // step = 3 or 2
              // swap color from rocket to meteor - one increase other decrease
              zielone(a,meteor[a].jasnosc);  // call function zielone to find mono LED (simulation is not working correctly as is missing 3-way SW2812B 
              //leds[rakieta[a].pozycja+5].fadeToBlackBy(3);
              leds[rakieta[a].pozycja+IC_WS2811].g--; // all leds should be green (thats why only G has benn decrease)
              //if (leds[rakieta[a].pozycja+IC_WS2811].g >0) leds[rakieta[a].pozycja+IC_WS2811].g--; //step by 3 or 2
              if (leds[rakieta[a].pozycja+IC_WS2811].g >0) leds[rakieta[a].pozycja+IC_WS2811].g--;  // step by 3  , better in the for loop if need to be higher
              //Serial.print(rakieta[a].pozycja); - debugger
              //Serial.print("  ##  ");
              //Serial.println(leds[rakieta[a].pozycja+5].g);
              //delay(20);
              if (leds[rakieta[a].pozycja+IC_WS2811].g == 0) {meteor[a].rozjasniamy = false;
                  Serial.print("doleciala:");
                  Serial.print(a);
                  Serial.print(" na kroku:");
                  Serial.print(czas);
                  Serial.print(" z koncowym kolorem:");
                  Serial.println(meteor[a].jasnosc);
                  
                     
              }
          }
        
      //if (rakieta[a].doleciala == false ) leds[rakieta[a].pozycja] = rakieta[a].kolor; I dont know what that is
    }
  //Serial.println(czas + " FASTLED.SHOW");
  FastLED.show();
  delay(7);

}
Serial.print(" Kiniec kodu czas 2000 ");

}


          //leds[rakieta[a].pozycja] =CRGB::Black;


void setup() {
  Serial.begin(9600);
  //Serial.println(rakieta[1].pozycja);
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  //pinMode(2, INPUT_PULLUP);
  if (DEMO == false) {IC_WS2811 = HighPowerLED / 3; } else {IC_WS2811 = HighPowerLED ;}
}
// This is racket attack from the top 
void PreSet(String kierunek){
if (kierunek == "UP"){
for (int xz=1 ; xz<HighPowerLED+1; xz++) {
    rakieta[xz].cel = MyBLP[xz];
    rakieta[xz].kolor = CRGB(245, 20, 222);
    rakieta[xz].start = (15-xz) * 1;
    rakieta[xz].doleciala = false;
    rakieta[xz].zgasla = false;
    rakieta[xz].predkosc = (48+(2*xz))+random8(5);
    rakieta[xz].pozycja = 0;
    meteor[xz].jasnosc = 1;
    meteor[xz].jasnoscMin = 1;
    meteor[xz].jasnoscMax = 40; // for know I not using , depend from max Green color of rakieta landed ;-)
  }
 }else{      //// leater few more details here
  for (int xz=1 ; xz<HighPowerLED+1; xz++) {
      rakieta[xz].cel = MyBLP[xz];
      rakieta[xz].kolor = CRGB(245, 20, 222);
      rakieta[HighPowerLED+1-xz].start = (15-xz) * 1;
      rakieta[xz].doleciala = false;
      rakieta[xz].zgasla = false;
      rakieta[HighPowerLED+1-xz].predkosc = (48+(2*xz))+random8(5);
      rakieta[xz].pozycja = 0;
      meteor[xz].jasnosc = 1;
      meteor[xz].jasnoscMin = 1;
      meteor[xz].jasnoscMax = 40; // for know I not using , depend from max Green color of rakieta landed ;-)
  }


 }

 Serial.println("KONIEC");
 }



void loop() {
 // bool buttonPressed = digitalRead(2) == LOW;
  PreSet("UP");
  LightUP();
  FastLED.setBrightness(1);
  FastLED.show();
  delay(3000);
  PreSet("DOWN");
  FastLED.setBrightness(255);
  LightUP();
  
} //loop

// Aktualne problemy - HighPower Led is going abobe 50 as max.

FPS: 0
Power: 0.00W