/* Morse4_I2C
// interruption en provenance du timer 2,
// Supression du vernier
 * Avec I2C

*/
#include <Adafruit_NeoPixel.h>
#include <Wire.h>

//Common part to put in every core/node 120

#define NODE_SAMPLE_ADDR        9
#define NODE_ABOUT_MEMORY       10
#define NODE_MORSE              11

#define FAILED          1
#define SUCCED          2
#define TURN_ON         3
#define EXPLOSED        4
#define DISARMED        5

//End of common part


#define PIXEL_PIN 11
#define Led 12
#define PotFreq A0

#define Valider 2
volatile byte LeClic = false ;
byte Brillant = false ;

enum EtatLed { END, LEDON, LEDOF } ;
#define MaxElem 100
#define DURELEM 5

byte Action[MaxElem]= {END} ; // Actions elementaires
byte Duree[MaxElem] ; // Durée de l'action
volatile byte Compteur = 0xFF ; // Compteur de durée de l'action
volatile byte Index = 0 ; // Action elementaire en cours

Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

int Frequences[] = {30,110, 220, 330, 440, 550, 660, 770, 880,990, 0} ;
char *Phrase[] = {"AMBRE", "BOULE", "CHAUD", "DIESE", "ENFER", "BARBE", "GARDE", "HAMPE","BISOU","BIERE"} ;

byte Choisi ;
byte Resultat ;
uint32_t LedDiff ;

void setup () {
  pinMode (Led, OUTPUT);

  strip.begin();
  strip.show();
  strip.setBrightness(16);

  randomSeed(analogRead(7));
  Choisi = random(10);

  cli(); // Désactive l'interruption globale
  bitClear (TCCR2A, WGM20); // WGM20 = 0
  bitClear (TCCR2A, WGM21); // WGM21 = 0
  TCCR2B = 0b00000110; // Clock / 256 soit 16 micro-s et WGM22 = 0
  TIMSK2 = 0b00000001; // Interruption locale autorisée par TOIE2
  TCNT2 = 0 ;
  sei(); // Active l'interruption globale

  Serial.begin(57600);
  Wire.begin(NODE_SAMPLE_ADDR);                // join i2c bus with address #2

  Action[0] = END ;
  Serial.println(Phrase[Choisi]);
  Serial.print(ChargeUnePhrase(Phrase[Choisi])) ;
  Serial.println(" Elements");

  pinMode(Valider, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(Valider), Clic, FALLING );

}


// Routine d'interruption
ISR(TIMER2_OVF_vect) {
  static byte varCompteur = 0; // La variable compteur
  TCNT2 = 256 - 250; // 250 x 16 µS = 4 ms
  if (varCompteur++ > 10) { // 10 * 4 ms = 40 ms (demi-période)
    varCompteur = 0;

    do {
      if (Action[Index] == END) break ; // pas d'action en cours
      if (Compteur == 0xFF) { //si Compteur n'est pas initialisé (1ere fois)
        switch (Action[Index]) { //on effectue l'action
          case LEDOF :     digitalWrite (Led, LOW) ; //PORTB |= _BV(Led);
            break ;
          case LEDON :     digitalWrite (Led, HIGH) ; //PORTB &= ~_BV(Led);
            break ;
        }
        Compteur = Duree[Index] ;
      }
      if (Compteur-- != 0) break ; //si Compteur n'est pas à 0
      if (Action[++Index] == END)  Index = 0 ; // si Fin des actions, on repart a 0

      switch (Action[Index]) { //on effectue l'action
        case LEDOF :     digitalWrite (Led, LOW) ;
          break ;
        case LEDON :     digitalWrite (Led, HIGH) ;
          break ;
      }
      Compteur = Duree[Index] ; // et on charge le delai
    } while (false) ;
  }
}

void Clic(void) {
  LeClic = true ;
}

void loop () {
  static char Freq = -1 ;
  Freq = QuelleFrequence() ;
  Resultat = (Freq == Choisi) ;

  if (LeClic) {
    LeClic=false ;
    if (Resultat) {
      Brillant=true ;
      strip.setPixelColor(0, strip.Color(0,255,0));
    } else {
      Brillant=false ;
      strip.setPixelColor(0, strip.Color(255,0,0));
      
    }
    strip.setBrightness(Brillant ? 64 : 8);
  }
  strip.show();
  
  delay (100);
}

byte ChargeUnePhrase(char *s) {
  char c ;
  byte i = 0 ;
  cli() ;
  while (c = *s++) {
    switch (toupper(c)) {
      case 'A' : i = ChargeUnCaractere( i , ".-") ; break ;
      case 'B' : i = ChargeUnCaractere( i , "-...") ; break ;
      case 'C' : i = ChargeUnCaractere( i , "-.-.") ; break ;
      case 'D' : i = ChargeUnCaractere( i , "-..") ; break ;
      case 'E' : i = ChargeUnCaractere( i , ".") ; break ;
      case 'F' : i = ChargeUnCaractere( i , "..-.") ; break ;
      case 'G' : i = ChargeUnCaractere( i , "--.") ; break ;
      case 'H' : i = ChargeUnCaractere( i , "....") ; break ;
      case 'I' : i = ChargeUnCaractere( i , "..") ; break ;
      case 'J' : i = ChargeUnCaractere( i , ".---") ; break ;
      case 'K' : i = ChargeUnCaractere( i , "-.-") ; break ;
      case 'L' : i = ChargeUnCaractere( i , ".-..") ; break ;
      case 'M' : i = ChargeUnCaractere( i , "--") ; break ;
      case 'N' : i = ChargeUnCaractere( i , "-.") ; break ;
      case 'O' : i = ChargeUnCaractere( i , "---") ; break ;
      case 'P' : i = ChargeUnCaractere( i , ".--.") ; break ;
      case 'Q' : i = ChargeUnCaractere( i , "--.-") ; break ;
      case 'R' : i = ChargeUnCaractere( i , ".-.") ; break ;
      case 'S' : i = ChargeUnCaractere( i , "...") ; break ;
      case 'T' : i = ChargeUnCaractere( i , "-") ; break ;
      case 'U' : i = ChargeUnCaractere( i , "..-") ; break ;
      case 'V' : i = ChargeUnCaractere( i , "...-") ; break ;
      case 'W' : i = ChargeUnCaractere( i , ".--") ; break ;
      case 'X' : i = ChargeUnCaractere( i , "-..-") ; break ;
      case 'Y' : i = ChargeUnCaractere( i , "-.--") ; break ;
      case 'Z' : i = ChargeUnCaractere( i , "--..") ; break ;
      case ' ' : i = ChargeUnCaractere( i , "  ") ; break ;
      case '0' : i = ChargeUnCaractere( i , "-----") ; break ;
      case '1' : i = ChargeUnCaractere( i , ".----") ; break ;
      case '2' : i = ChargeUnCaractere( i , "..---") ; break ;
      case '3' : i = ChargeUnCaractere( i , "...--") ; break ;
      case '4' : i = ChargeUnCaractere( i , "....-") ; break ;
      case '5' : i = ChargeUnCaractere( i , ".....") ; break ;
      case '6' : i = ChargeUnCaractere( i , "-....") ; break ;
      case '7' : i = ChargeUnCaractere( i , "--...") ; break ;
      case '8' : i = ChargeUnCaractere( i , "---..") ; break ;
      case '9' : i = ChargeUnCaractere( i , "----.") ; break ;
    }
  }
  i = ChargeUnCaractere( i , "    ") ;
  sei() ;
  return i ;
}

byte ChargeUnCaractere(byte i, char *s) {
  char c ;
  while (c = *s++) {
    if (i >= MaxElem - 5) break ;
    switch (c) {
      case '.' :
        Action[i] = LEDON ; Duree[i] = DURELEM ; i++ ;
        Action[i] = LEDOF ; Duree[i] = DURELEM ; i++ ;
        break ;
      case '-' :
        Action[i] = LEDON ; Duree[i] = DURELEM * 3 ; i++ ;
        Action[i] = LEDOF ; Duree[i] = DURELEM ; i++ ;
        break ;
    }
  }
  Action[i] = LEDOF ; Duree[i] = DURELEM * 3 ; i++ ;
  Action[i] = END ;
  return i ;
}

void CliCli() {
  cli() ;
  byte i=0 ;
  Action[i] = LEDON ; Duree[i] = 1 ; i++ ;
  Action[i] = LEDOF ; Duree[i] = 1 ; i++ ;
  Action[i] = END ;
  Compteur = 0 ;
  sei() ;
}

char QuelleFrequence(void) {
  byte f ;
  int D ;
  int Dif = 1025 ;
  int Lu = analogRead(PotFreq) ;
  int Ajuste ;
  
  Ajuste = Lu ; 

  for ( byte i = 0 ; Frequences[i] > 0 ; i++ ) {
    D = abs(Ajuste - Frequences[i]) ;
    if (D < Dif) {
      f = i ;
      Dif = D ;
    }
  }
  if (Dif > 20) f = -1 ;

  Serial.print(f);
  Serial.print(" Dif:");
  Serial.println(Dif);
  // Led allumée selon la valeur de Dif
  LedDiff = strip.Color(Dif*5,0,0) ;
  if (Dif<=10) LedDiff = strip.Color(100+Dif*15,125-Dif*5,0) ;
  if (Dif>50) LedDiff = strip.Color(255,0,0) ;
  if (Dif<2) LedDiff = strip.Color(0,255,0) ;
  
  return f ;
}


/******
#include <Wire.h>

//Common part to put in every core/node 120

#define NODE_SAMPLE_ADDR        9
#define NODE_ABOUT_MEMORY       10
#define NODE_MORSE              11

#define FAILED          1
#define SUCCED          2
#define TURN_ON         3
#define EXPLOSED        4
#define DISARMED        5

//End of common part


#define SOLVE_BUTTON_PIN    6
#define FAILED_BUTTON_PIN   7
#define STARTED_LED_PIN     8

boolean started=false;
int lastSuccessButtonState=HIGH;
int lastFailureButtonState=HIGH;

int failure=0;
int win=0;
void setup()
{
  Wire.begin(NODE_SAMPLE_ADDR);                // join i2c bus with address #2
  Serial.begin(9600);
  Serial.println("Start NODE_SAMPLE");
  pinMode(SOLVE_BUTTON_PIN, INPUT_PULLUP);
  pinMode(FAILED_BUTTON_PIN, INPUT_PULLUP);
  pinMode(STARTED_LED_PIN, OUTPUT);
  digitalWrite(STARTED_LED_PIN, LOW);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);
}

void receiveEvent(int bytes) {
 int x = Wire.read();    // read one character from the I2C
  Serial.print("Received "); Serial.println(x);
    if (x==TURN_ON){
      startModule();
    }
}

void startModule(){
  started=true;
  digitalWrite(STARTED_LED_PIN, HIGH);
  int failure=0;
  int win=0;
}
void loop()
{
  delay(50);
  if (started){
    if (readSuccessButton()) {
      sendSuccess();
    } else if (readFailureButton()) {
      sendFailure();
    }
  }
}


void requestEvent()
{
  Serial.print("Request data, win");Serial.print(win);Serial.print(" loose "); Serial.println(failure);
  Wire.write(win);
  Wire.write(failure);
}

boolean readSuccessButton(){
  int buttonState = digitalRead(SOLVE_BUTTON_PIN);
  if (buttonState != lastSuccessButtonState) {
    if (buttonState == LOW) {
      lastSuccessButtonState = buttonState;
      return true;
    }
    lastSuccessButtonState = buttonState;
  }
  return false;
}

boolean readFailureButton(){
  int buttonState = digitalRead(FAILED_BUTTON_PIN);
  if (buttonState != lastFailureButtonState) {
    if (buttonState == LOW) {
      lastFailureButtonState = buttonState;
      return true;
    }
    lastFailureButtonState = buttonState;
  }
  return false;
}

void sendFailure() {
  failure++;
  Serial.println("Failure added");
}

void sendSuccess() {
  win++;
  digitalWrite(STARTED_LED_PIN, LOW);
  started=false;
  Serial.println("Success added, turn off");
}
 */
