#include "FastLED.h"
#include "FastLED_RGBW.h"

// #define NUM_LEDS1 150
// #define NUM_LEDS2 150
// #define NUM_LEDS3 300 // tira virtual que no se pinta
#define DATA_PIN_1 8
#define DATA_PIN_2 3
//#define DATA_PIN_3 4 // tira virtual que no se pinta, en este pin fastled no funciona


#define NUM_STRIPS 2
#define NUM_LEDS_PER_STRIP 150
#define NUM_LEDS NUM_LEDS_PER_STRIP * NUM_STRIPS

#define FRAMES_PER_SECOND   60
#define BRIGHTNESS          100

CRGBW leds[NUM_STRIPS * NUM_LEDS_PER_STRIP];
CRGB *ledsRGB = (CRGB *) &leds[0];


const uint8_t brightness = 255;
int r;
int countFrame = 0;

void setup() { 

  Serial.begin(512000);

  FastLED.addLeds<SK6812, DATA_PIN_1>(ledsRGB, 0, getRGBWsize(NUM_LEDS)/2);
  FastLED.addLeds<SK6812, DATA_PIN_2>(ledsRGB, getRGBWsize(NUM_LEDS)/2, getRGBWsize(NUM_LEDS)/2); // la segunda se mapea a partir de un offset! Brutal!
    
  FastLED.setBrightness(BRIGHTNESS);

  FastLED.setMaxRefreshRate(120);


}
 
void loop(){

  //EVERY_N_MILLISECONDS(1000/FRAMES_PER_SECOND) {
    
    countFrame++;
    r = (countFrame / 625.) * 255 ; //rojo
    //Serial.println(r);
    //3∂Serial.println(countFrame*16);
        //g = neopix_gamma[(int)(255.*countFrame / totalFrames)] * green / 255;
        //b = neopix_gamma[(int)(255.*countFrame / totalFrames)] * blue / 255;
        //w = neopix_gamma[(int)(255.*countFrame / totalFrames)] * white / 255;
    if(countFrame > 625)
      countFrame=0;
    //colorFill(CRGB::Red);
    //colorFill(CRGB::Green);
    //colorFill(CRGB::Blue);
    //fillWhite();
    //rainbowLoop();
    setAll(r, 0, 0, 0);
    FastLED.show();
    //FastLED.delay(1000/FRAMES_PER_SECOND); 


  }

  // EVERY_N_SECONDS(5) {             // Change the target palette to a random one every 5 seconds.
  //   Serial.print(FastLED.getFPS());
  // }

//}




//////////////////////////////////////////////////////////////////
////////////////     PIXEL BASIC FUNCIONS       //////////////////
//////////////////////////////////////////////////////////////////


void showStrip()
{
  FastLED.show(); // parte 1 de 2.5m
}

// Set a LED color (not yet visible)
void setPixel(int Pixel, byte red, byte green, byte blue, byte white) 
{

   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
   leds[Pixel].w = white;
   //    leds[i] = CRGBW(red, green, blue, white);


}

// Set all LEDs to a given color and apply it (visible)
void setAll(byte red, byte green, byte blue, byte white) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue, white); 
  }
  //showStrip();
}


void colorFill(CRGB c){
  for(int i = 0; i < NUM_LEDS; i++){
    leds[i] = c;
    //splitStrip(); // realmente hace falta generar todo en una tira entera y partirla? 
    FastLED.show();
    delay(2);
  }
  delay(500);
}
 
void fillWhite(){
  for(int i = 0; i < NUM_LEDS; i++){
    leds[i] = CRGBW(0, 0, 0, 255);
    //splitStrip();
    FastLED.show();
    delay(2);
  }
  delay(500);
}
 
void rainbow(){
  static uint8_t hue;
 
  for(int i = 0; i < NUM_LEDS; i++){
    leds[i] = CHSV((i * 256 / NUM_LEDS) + hue, 255, 255);
  }
  //splitStrip();
  FastLED.show();
  hue++;
}
 
void rainbowLoop(){
  long millisIn = millis();
  long loopTime = 5000; // 5 seconds
 
  while(millis() < millisIn + loopTime){
    rainbow();
    delay(1);
  }
}



void meteorRain(byte red, byte green, byte blue, byte white, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay) 
{
  
  setAll(0, 0, 0, 0);

  for (int i = 0; i < NUM_LEDS ; i++) {


    // fade brightness all LEDs one step
    for (int j = 0; j < NUM_LEDS; j++) {
      if ( (!meteorRandomDecay) || (random(10) > 5) ) {
        fadeToBlack(j, meteorTrailDecay );
      }
    }

    // draw meteor
    for (int j = 0; j < meteorSize; j++) {
      if ( ( i - j < NUM_LEDS) && (i - j >= 0) ) {
        setPixel(i - j, red, green, blue, white);
      }
    }

    showStrip();
  }
}

void fadeToBlack(int ledNo, byte fadeValue)
{
  // NeoPixel
  //uint32_t oldColor;
  uint8_t r, g, b, w;
  int value;

  r = leds[ledNo].r ;
  g = leds[ledNo].g ;
  b = leds[ledNo].b ;
  w = leds[ledNo].w ;

  r = (r <= 10) ? 0 : (int) r - (r * fadeValue / 256);
  g = (g <= 10) ? 0 : (int) g - (g * fadeValue / 256);
  b = (b <= 10) ? 0 : (int) b - (b * fadeValue / 256);
  w = (w <= 10) ? 0 : (int) w - (w * fadeValue / 256);

  leds[ledNo]=CRGBW(r,g,b,w);

}