#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
 
//Definimos GPIO de la entrada del detector crepuscular LDR
#define ldr 12

//Definimos GPIO de las entradas de los detectores de presencia PIR
#define pir1 16
#define pir2 17
#define pir3 5
#define pir4 18 

//Definimos configuracion de la tira WS2812B
#define pasillo_leds 32     //Número de píxeles en la tira del pasillo
#define garaje_leds 16      //Numero pixeles en tira puerta garaje
#define jardin_leds 32      //Numero pixeles en tira jardin
#define puerta_leds 16      //Numero pixeles en tira puerta
#define BRIGHTNESS 255      //Banderas de tipo píxel, agréguelas según sea necesario

//Definimos GPIO de salida para control neopixel
#define PINpasillo 15       //Numero del GPIO del ESP32 para control del pasillo      
#define PINgaraje 2         //Numero del GPIO del ESP32 para control del garaje 
#define PINjardin 0         //Numero del GPIO del ESP32 para control del jardin 
#define PINpuerta 4         //Numero del GPIO del ESP32 para control del puerta 
#define BRIGHTNESS 255      //Banderas de tipo píxel, agréguelas según sea necesario:

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   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 tirapasillo = Adafruit_NeoPixel(pasillo_leds, PINpasillo, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel tiragaraje = Adafruit_NeoPixel(garaje_leds, PINgaraje, NEO_GRB + NEO_KHZ800);
//Adafruit_NeoPixel tirajardin = Adafruit_NeoPixel(jardin_leds, PINjardin, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel tirapuerta = Adafruit_NeoPixel(puerta_leds, PINpuerta, NEO_GRB + NEO_KHZ800);

int P1=0;
int P2=0;
int P3=0;
int P4=0;
int sol=0;
int ldrValor;
int E0=0;

TaskHandle_t Garaje;
TaskHandle_t Puerta;
TaskHandle_t Pasillo;
//TaskHandle_t Jardin;

void setup() {
  Serial.begin(115200);
  xTaskCreatePinnedToCore(loop0,"Garaje",5000,NULL,1,&Garaje,0);
  xTaskCreatePinnedToCore(loop1,"Puerta",5000,NULL,1,&Puerta,1);
  xTaskCreatePinnedToCore(loop2,"Pasillo",5000,NULL,1,&Pasillo,1);
  //xTaskCreatePinnedToCore(loop3,"Jardin",1000,NULL,1,&Jardin,0);
pinMode(ldr,INPUT);
 
  
  pinMode (pir1,INPUT); 
  pinMode (pir2,INPUT);
  pinMode (pir3,INPUT);
  pinMode (pir4,INPUT);
  pinMode (ldr,INPUT);

  tirapasillo.setBrightness(BRIGHTNESS);
  tirapasillo.begin();
  tirapasillo.show();  // Initialize all pixels to 'off'

  tiragaraje.setBrightness(BRIGHTNESS);
  tiragaraje.begin();
  tiragaraje.show();  // Initialize all pixels to 'off'

  tirapuerta.setBrightness(BRIGHTNESS);
  tirapuerta.begin();
  tirapuerta.show();  // Initialize all pixels to 'off'
}

void loop() {

  //SENSOR CREPUSCULAR
  ldrValor = analogRead(ldr);  // Lee valor de entrada A0 y lo almacena en la variable
  if (ldrValor > 400) {        // Ajuste del nivel de oscuridad para activacion
    delay(1000);
    E0 = 1;  
  } else {
    E0=0;  
  }
   //Serial.println(E0);
   //Serial.println(analogRead(ldr));


/*CONTROL TIRA PASILLO
P1=digitalRead(pir1);
if (E0 == 1){
  if (P1 == 1){
  izqder(tirapasillo.Color(255, 255, 255), 50); 
  offizqder(tirapasillo.Color(0, 0, 0), 50); 
}}

P3=digitalRead(pir3);
if (E0 == 1){
  if (P3 == 1){
  derizq(tirapasillo.Color(0, 255, 0), 50); 
  offderizq(tirapasillo.Color(0, 0, 0), 50);
}}*/}

void loop2(void *parameter){
  while(1==1){
    P1=digitalRead(pir1);
if (E0 == 1){
  if (P1 == 1){
  izqder(tirapasillo.Color(255, 255, 255), 50); 
  offizqder(tirapasillo.Color(0, 0, 0), 50); 
}}

P3=digitalRead(pir3);
if (E0 == 1){
  if (P3 == 1){
  derizq(tirapasillo.Color(0, 255, 0), 50); 
  offderizq(tirapasillo.Color(0, 0, 0), 50);
}}}}

 //CONTROL TIRA PUERTA GARAJE
void loop0(void *parameter){
  while(1==1){
    P2=digitalRead(pir2);
if (E0==1){
  if (P2 == 1){
  garaje(tiragaraje.Color(255, 255, 0), 50);
  offgaraje(tiragaraje.Color(0, 0, 0), 50);
}}}}

//CONTROL TIRA PUERTA DE ENTRADA
void loop1(void *parameter){
  while(1==1){
    P4=digitalRead(pir4);
if (E0==1){
  if (P4 == 1){
  puerta(tirapuerta.Color(255, 255, 0), 50); 
  offpuerta(tirapuerta.Color(0, 0, 0), 50);
}}}}

//SECUENCIA ENCENDIDO AL CENTRO PARA TIRA DEL PASILLO
void alcentro(uint32_t c, uint16_t wait) {
  clearpasillo();
  delay(wait);
   for (uint16_t i = 0; i < (tirapasillo.numPixels() / 2); i++) {  // fill strip from sides to middle
    tirapasillo.setPixelColor(i, c);
    tirapasillo.setPixelColor(tirapasillo.numPixels() - i, c);
    tirapasillo.show();
    delay(wait);
  }
  tirapasillo.setPixelColor(tirapasillo.numPixels() / 2, c);
  tirapasillo.show();
  delay(5000);
  P1=0;
  //clearStrip();
}

//SECUENCIA APADADO AL CENTRO PARA TIRA DEL PASILLO
void offalcentro(uint32_t c, uint16_t wait) {
  //clearStrip();
  delay(wait);
  for (uint16_t i = 0; i < (tirapasillo.numPixels() / 2); i++) {  // fill strip from sides to middle
    tirapasillo.setPixelColor(i, c);
    tirapasillo.setPixelColor(tirapasillo.numPixels() - i, c);
    tirapasillo.show();
    delay(wait);
  }
  tirapasillo.setPixelColor(tirapasillo.numPixels() / 2, c);
  tirapasillo.show();
  //clearpasillo();
}

//SECUENCIA ENCENDIDO A LOS LADOS PARA TIRA DEL PASILLO
void aloslados(uint32_t c, uint16_t wait) {
  clearpasillo();
  delay(wait);
  for (uint16_t i = 0; i <= (tirapasillo.numPixels() / 2); i++) {  // reverse
    tirapasillo.setPixelColor(tirapasillo.numPixels() / 2 - i, c);
    tirapasillo.setPixelColor(tirapasillo.numPixels() / 2 + i, c);
    tirapasillo.show();
    delay(wait);
  }
}

//SECUENCIA APAGADO A LOS LADOS PARA TIRA DEL PASILLO
void offaloslados(uint32_t c, uint16_t wait) {
  //clearStrip();
  delay(wait);
  for (uint16_t i = 0; i <= (tirapasillo.numPixels() / 2); i++) {  // reverse
    tirapasillo.setPixelColor(tirapasillo.numPixels() / 2 - i, c);
    tirapasillo.setPixelColor(tirapasillo.numPixels() / 2 + i, c);
    tirapasillo.show();
    delay(wait);
  }
  //clearpasillo();
}

//SECUENCIA DE ENCENDIDO PUERTA GARAJE
void garaje(uint32_t c, uint16_t wait) {
  cleargaraje();
  delay(wait);
  for (uint16_t i = 0; i <= (tiragaraje .numPixels() / 2); i++) {  // reverse
    tiragaraje .setPixelColor(tiragaraje .numPixels() / 2 - i, c);
    tiragaraje .setPixelColor(tiragaraje .numPixels() / 2 + i, c);
    tiragaraje .show();
    delay(wait);
  }
  delay(4000);
    P2 = 0;
}

//SECUENCIA APAGADO PUERTA GARAJE
void offgaraje(uint32_t c, uint16_t wait) {
  //clearStrip();
  delay(wait);
  for (uint16_t i = 0; i <= (tiragaraje.numPixels() / 2); i++) {  // reverse
    tiragaraje.setPixelColor(tiragaraje.numPixels() / 2 - i, c);
    tiragaraje.setPixelColor(tiragaraje.numPixels() / 2 + i, c);
    tiragaraje.show();
    delay(wait);
  }
  //cleargaraje();
}

//SECUENCIA ENCENCIDO PUERTA PRINCIPAL
void puerta(uint32_t c, uint16_t wait) {
  clearpuerta();
  delay(wait);
  for (uint16_t i = 0; i <= (tirapuerta .numPixels() / 2); i++) {  // reverse
    tirapuerta .setPixelColor(tirapuerta .numPixels() / 2 - i, c);
    tirapuerta .setPixelColor(tirapuerta .numPixels() / 2 + i, c);
    tirapuerta .show();
    delay(wait);
  }
  delay(5000);
  P4 = 0;
}

//SECUENCIA APAGADO PUERTA PRINCIPAL
void offpuerta(uint32_t c, uint16_t wait) {
  //clearStrip();
  delay(wait);
  for (uint16_t i = 0; i <= (tirapuerta.numPixels() / 2); i++) {  // reverse
    tirapuerta.setPixelColor(tirapuerta.numPixels() / 2 - i, c);
    tirapuerta.setPixelColor(tirapuerta.numPixels() / 2 + i, c);
    tirapuerta.show();
    delay(wait);
  }
  //clearpuerta();
} 

//SECUENCIA ENCENDIDO DE DERECHA A IZQUIERDA PARA TIRA DEL PASILLO
void derizq(uint32_t c, uint8_t wait) {
  for (uint16_t i = 0; i < tirapasillo.numPixels(); i++) {
    tirapasillo.setPixelColor(i, c);
    tirapasillo.show();
    delay(wait);
  }
  delay(2000);
  //clearStrip();
}

//SECUENCIA APAGADO DE DERECHA A IZQUIERDA PARA TIRA DEL PASILLO
void offderizq(uint32_t c, uint8_t wait) {
  for (uint16_t i = 0; i < tirapasillo.numPixels(); i++) {
    tirapasillo.setPixelColor(i, c);
    tirapasillo.show();
    delay(wait);
  }
  //clearpasillo();
}

//SECUENCIA ENCENCIDO DE IZQUIERDA A DERECHA PARA TIRA DEL PASILLO
void izqder(uint32_t c, uint8_t wait) {
  for (uint16_t i = tirapasillo.numPixels(); i > 0; i--) {
    tirapasillo.setPixelColor(i, c);
    tirapasillo.show();
    delay(wait);
  }
  tirapasillo.setPixelColor(0, c);
  tirapasillo.show();
  delay(5000);
  P1=0;
  //clearStrip();
}

//SECUENCIA DE APAGADO DE IZQUIERDA A DERECHA PARA TIRA DEL PASILLO
void offizqder(uint32_t c, uint8_t wait) {
  for (uint16_t i = tirapasillo.numPixels(); i > 0; i--) {
    tirapasillo.setPixelColor(i, c);
    tirapasillo.show();
    delay(wait);
  }
  tirapasillo.setPixelColor(0, c);
  tirapasillo.show();
  //clearpasillo();
}

//RESETEO DE CADA TIRA
void clearpasillo() {
  for (int i = 0; i < pasillo_leds; i++) {
    tirapasillo.setPixelColor(i, tirapasillo.Color(0, 0, 0));  //change RGB color value here
  }
  tirapasillo.show();
} 

void cleargaraje(){
  for (int i = 0; i < garaje_leds; i++) {
    tiragaraje.setPixelColor(i, tiragaraje.Color(0, 0, 0));  //change RGB color value here
  }
  tiragaraje.show();
}

void clearpuerta(){
  for (int i = 0; i < garaje_leds; i++) {
    tirapuerta.setPixelColor(i, tirapuerta.Color(0, 0, 0));  //change RGB color value here
  }
  tirapuerta.show();
}
  //offizqder(tirapasillo.Color(0, 0, 0), 50); 
  //alcentro(tirapasillo.Color(255, 255, 255), 50);     // ENCENDIDO AL CENTRO                     Azul
  //offalcentro(tirapasillo.Color(0, 0, 0), 50);    // APAGADO AL CENTRO
  //aloslados(tirapasillo.Color(255, 0, 0), 50);  // ENCENDIDO A LOS LADOS                   Rojo 
  //garaje(tiragaraje.Color(255, 255, 0), 50);  // ENCENDIDO A LOS LADOS 
  //puerta(tirapuerta.Color(255, 255, 0), 50);  // ENCENDIDO A LOS LADOS                  Rojo
  //offaloslados(tirapasillo.Color(0, 0, 0), 50); //APAGADO A LOS LADOS
  //derizq(tirapasillo.Color(0, 255, 0), 50);       // ENCENDIDO DE DERECHA A IZQUIERDA      Verde
  //offderizq(tirapasillo.Color(0, 0, 0), 50);      //APAGADO DE DERECHA A IZQUIERDA
  //izqder(tirapasillo.Color(255, 255, 5), 50);       // ENCENCIDO DE IZQUIERDA A DERECHA    Yellow
  //offgaraje(tiragaraje.Color(0, 0, 0), 50);    //APAGADO DE IZQUIERDA A DERECHA
  //offizqder(tirapasillo.Color(0, 0, 0), 50);    //APAGADO DE IZQUIERDA A DERECHA
  //apagado(strip.Color(150, 150, 150), 50);  // APAGADO