//////////////////////////////////////////////////////////////////
//                                                              //
//                 LUMICUBE - IUT LYON  - GEII                  //
//                                                              //
//          TEAM : DIE ODD      BY RUBEN SARGSYAN (RUBYAN)      //
//                                                              // 
//                       Ver :  4.1                             // 
//                                                              //
//////////////////////////////////////////////////////////////////

#include      "FastLED.h"
#include      "BluetoothSerial.h"
#include      "Arduino.h"
#include      "DFRobotDFPlayerMini.h"
#include      "MegunoLink.h"
#include      "Filter.h"



HardwareSerial mySoftwareSerial(1);
DFRobotDFPlayerMini myDFPlayer;

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error        Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;
int           Reception;                                              // La valeur de Reception
char          ValeurReceptionBT=0;                                    // La valeur de Reception en "char"



const   char  PIN_RX        =900;
char          NB_Capteur_PIC=0;
        char  changement;  
const   char  turnON ='a';
const   char  turnOFF ='b';
        int   Cellule = 9 ;                                           // Choix de la cellule
#define       LED_PIN     13                                          // Pin de commande LED
#define       NUM_LEDS    30                                          // Nombre de Led sur le ruban
#define       NUM_LEDS  30                                            // Nombre de Leds
#define       AUDIO_IN_PIN   A0                                       // try pin sp , GPIO 36


// the following parameters can be tweaked according to your audio levels
#define       NOISE 350           // 550 par defaut , cela rend le système moin sensible
#define       TOP   (NUM_LEDS+2) // allow the max level to be slightly off scale
#define       LED_TYPE  WS2812
#define       BRIGHTNESS  250     // a little dim for recording purposes max 255
#define       COLOR_ORDER GRB
CRGB          leds[NUM_LEDS];


// define the variables needed for the audio levels
int lvl = 0, minLvl = 0, maxLvl = 350; // tweak the min and max as needed //300 default
ExponentialFilter<long> ADCFilter(5,0);   // instantiate the filter class for smoothing the raw audio signal

#include      "LumiZic.h"
#include      "LumiGame.h"
#include      "ValeurBT.h"
#include      "LumiColor.h"
#include      "LumiHelp.h"

//--------------------------------------------------------------------------------------------------------------------------//
//Init INT
//--------------------------------------------------------------------------------------------------------------------------//

portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR INT_NB_Capteur_PIC(void)
{
portENTER_CRITICAL_ISR(&mux);
NB_Capteur_PIC++;                               // ajouter finction rebon si problème
portEXIT_CRITICAL_ISR(&mux);
}

//--------------------------------------------------------------------------------------------------------------------------//
//SETUP
//--------------------------------------------------------------------------------------------------------------------------//
  void setup() 
{  

  FastLED.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);

  pinMode(PIN_RX, INPUT_PULLUP);                                                  // sets pin high
  attachInterrupt(digitalPinToInterrupt(PIN_RX), INT_NB_Capteur_PIC, FALLING);    // attaches pin to interrupt on Falling Edge
 
  pinMode(23, OUTPUT);  
  digitalWrite(23, HIGH);
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  Serial.begin(115200);
  Serial.println("Boot ok\n");
  SerialBT.begin("ESP32_LumiCube\n");                                   // Bluetooth device name
  Serial.println("BT ok\n");
  mySoftwareSerial.begin(9600, SERIAL_8N1, 17, 16);                   // Bauds, type, RX, TX
  Serial.println("Tx/RX ok");
  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini"));
  Serial.println(F("Initialisation DFPlayer ... (Attendre 3~5 seconds)"));

  SetAllLed(30,0,210);
  delay(100);
  SetAllLed(0,0,0);
  
  while(!myDFPlayer.begin(mySoftwareSerial)) 
  {
    Serial.println(F("Liaison impossible ou erreur"));
  }
  Serial.println(F("DFPlayer Mini online."));
 
  SetAllLed(110,0,210);
  delay(100);
  SetAllLed(0,0,0);
}

void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param){
  if(event == ESP_SPP_SRV_OPEN_EVT){
    Serial.println("Client Connecté");
    delay(3000);
    LumiHelp();
  }
}

  void loop (void)
{

  ValeurReceptionBT =(char)SerialBT.read();

  SerialBT.register_callback(callback);
  
  /////////////////////////////////////////////
  //          Pour Deboguer 
  /////////////////////////////////////////////
  //if(!SerialBT.begin("ESP32"))
  //    {
  //      Serial.println("Une erreur s'est produite lors de l'initialisation du Bluetooth");
  //    }
  //else
  //    {
  //      Serial.println("Communication Bluetooth initialisé");
  //    }
  
  if (  Serial.available()  )    { SerialBT.write(Serial.read()); }             
  myDFPlayer.pause();
  if (SerialBT.available()) 
  {
       /* if(event == ESP_SPP_SRV_OPEN_EVT)
            {
              Serial.println("Client Connected");
            }*/
        
        SerialBT.print("Reception :");                                // write on BT app
        SerialBT.println(ValeurReceptionBT);                          // write on BT app      
        Serial.print ("Reception :");                                 // print on serial monitor
        Serial.println(ValeurReceptionBT);                            // print on serial monitor    
        //SerialBT.println(ValeurReceptionBT);                        // print on the app    
        //SerialBT.write(ValeurReceptionBT);                          // print on serial monitor
        
        
        if(ValeurReceptionBT == turnON)                               // pour gestion BT
        
        {
              
              while (ValeurReceptionBT == turnON)                     // Si BT -> activation LumiCube
              {
                    changement='a';
                                                                      // PROVOQUE UN FLASH BLANC DES LEDS //!!!\\ ne pas le prendre en compte lors des tets ! (le flash)
                    {                                                 // Start
                    
                        digitalWrite(23, LOW);                        // Etat Bas  = 5v (passage transistor)
                        delayMicroseconds(9);
                        digitalWrite(23, HIGH);                       // Etat Haut = 0v
                    
                    }
                    
                    {                                                 // Selection cellule    
                         SelectionCellule(Cellule);   
                    }
                    
                    {                                                 // Stop
                    
                        digitalWrite(23, LOW);                        // Etat Bas  = 5v (passage transistor)
                        delayMicroseconds(3);
                        digitalWrite(23, HIGH);                       // Etat Haut = 0v
                        delayMicroseconds(3);
                        digitalWrite(23, LOW);                        // Etat Bas  = 5v (passage transistor)
                        delayMicroseconds(3);
                        digitalWrite(23, HIGH);                       // Etat Haut = 0v
                    
                    }
                    
                    for (int i = 0; i <= 29; i++) 
                    {               
                        leds[i] = CRGB ( 0, 0, 255);                  // Selection Bleu 
                        FastLED.show();                               // Utilisation de l'algo FastLed
                        if(SerialBT.read()=='b'){ changement='b';  }  // Detection éventuel d'une action BT 
                         
                        delayMicroseconds(5);                         // delay de 5  us
                        delay(40);                                    // delay de 40 ms
                    }
                    
                    
                    for (int i = 29; i >= 0; i--) 
                    {
                        leds[i] = CRGB ( 255, 0, 0);                  // Selection Rouge
                        FastLED.show();                               // Utilisation de l'algo FastLed
                        if(SerialBT.read()=='b'){ changement='b';  }  // Detection éventuel d'une action BT 
                        
                        delayMicroseconds(5);                         // delay de 5  us
                        delay(40);                                    // delay de 40 ms
                    }
                    
                    Serial.write(SerialBT.read());                    // pour debugage
                    ValeurReceptionBT = changement;                   // pour gestion BT
                    
              }
        }
        
        if(ValeurReceptionBT == turnOFF)                              // Si BT -> aLumiCube OFF
        
            {
              for (int i = 0; i <= 29; i++) 
                {
                 leds[i] = CRGB ( 0, 0, 0);                           // Selection "noir"
                 FastLED.show();                                      // Utilisation de l'algo FastLed
                 delay(40);                                           // delay de 40 ms
                }
            
            }
            
        if(ValeurReceptionBT == 'g')                              
        
            {
                LumiGame();
                ValeurReceptionBT='h';
            }
            
        if(ValeurReceptionBT == 'm')                              // Si BT -> aLumiCube OFF
        
            {
               LumiZic();
               ValeurReceptionBT='h';     
            }
            
        if(ValeurReceptionBT == 's')                              // Si BT -> aLumiCube OFF
        
            {
                byte R=0; byte G=0; byte B=0;           // permet une lecteur de la valeurs en ascii, meme si celui-ci peut etre remplacer en char pour une utilisation "pure et dure" 

                SerialBT.print("\n \\________ROUGE________//");
                R=ValeurBT255();
                SerialBT.print("\n \\________VERT________//");
                G=ValeurBT255();
                SerialBT.print("\n \\________BLEU________//");
                B=ValeurBT255();


                              SerialBT.print("\nValeurs Reçu  ");
                              SerialBT.print("R: ");                        
                              SerialBT.print(R);                          
                              SerialBT.print("  ");
                              SerialBT.print("G: ");                                
                              SerialBT.print(G);                                                       
                              SerialBT.print("  ");
                              SerialBT.print("B: ");                               
                              SerialBT.print(B);   
                              SerialBT.print("\n");                     

                              
                SetAllLed(R,G,B);

                ValeurReceptionBT='h';
            }


     

        if(ValeurReceptionBT == 'c')                              // Color
        
            {
              LumiColor();
              ValeurReceptionBT='h';    
            }
        
        if(ValeurReceptionBT == 'h')                                            //help
            {

              LumiHelp();
                        /*SerialBT.print("\n\\__Menu Principal____//");
                        SerialBT.print("\n\\__c -> Color_Control//");
                        SerialBT.print("\n\\__m -> Musique______//");
                        SerialBT.print("\n\\__a -> LEDS_ON______//");         // a modifié
                        SerialBT.print("\n\\__b -> LEDS_OFF_____//");
                        SerialBT.print("\n\\__g -> GAMES________//");
                        SerialBT.print("\n\\__s -> SET_LEDS_____//");
                        SerialBT.print("\n\\__XXXXXXXXXXXX__//");
                        SerialBT.print("\n\\__h -> Aide_________//");
                        //SerialBT.print("\n\\__z -> BACK_________//");*/      
            
            }    
        delay(100);                                                   // delay de 100 ms

  }                                                                   // fin de if SerialBT.available
 
}                                                                     // fin de loop



void SelectionCellule(int Cellule)
{ 
    delayMicroseconds(2);                                             // Attente suplémentaire pour eviter un 
                                                                      // problème lors du dechargement (5->0) 
                                                                      // du transistor
    for (int i = 0; i <= (Cellule-1); i++) 
    {
        digitalWrite(13, HIGH);                                       // Etat Haut = 3v
        delayMicroseconds(1);
        digitalWrite(13, LOW);                                        // Etat Bas = 3v
        delayMicroseconds(1);
        
    }
}


/*void SetAllLed(char R,char G,char B)
{ 
    for (int i = 0; i <= (NUM_LEDS-1); i++)              
    {
          leds[i] = CRGB ( R, G, B);
          FastLED.show();
          delay(2);
    }
}*/
