#include <LiquidCrystal.h>

#define IR_PIN 2
#define LCD_RS_PIN 10
#define LCD_E_PIN 11
#define LCD_D4_PIN 3
#define LCD_D5_PIN 4
#define LCD_D6_PIN 5
#define LCD_D7_PIN 6
#define BTN_PIN 7

LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN);

unsigned long currentTime;
unsigned long previousTime;
bool isScored;
int score;
int temps;
bool btnPressed = false;
bool isGo = false;
 
void setup(void){
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(IR_PIN), panier, FALLING);
  pinMode(IR_PIN, INPUT);
  pinMode(BTN_PIN, INPUT);
  lcd.begin(16, 2);
  lcd.setCursor(2,0);
  notifyNotStarted();
}

void notifyNotStarted(void) {
  lcd.clear();
  lcd.print("Click on start");
  lcd.setCursor(3,1);
  lcd.print("to play...");
  Serial.print(millis());
  Serial.print(":message:");
  Serial.println("Click on start to play...");
}
 
void loop(void){
  if(Serial.available() > 0) {
    char response = (char) Serial.read();
    convertToState(response);
  }

  if(digitalRead(BTN_PIN) == HIGH and !btnPressed){
    btnPressed = true;
    go();
  } else if(digitalRead(BTN_PIN) == LOW and btnPressed) {
    btnPressed = false;
  }

  if(isGo and temps != 0) {
    if(isScored) {
      score += 1;
      notifyGameStatus();
      isScored = false;
    }
    currentTime = millis();
    if(previousTime == 0) {
      previousTime = millis();
    }
    if((currentTime-previousTime)>1000) {
      temps -= (int)(currentTime-previousTime)/(int)1000;
      previousTime=currentTime;
      notifyGameStatus();
    }
  } else if(isGo){
    Serial.print(millis());
    Serial.print(":score:");
    Serial.println(score);
    notifyNotStarted();
    isGo = false;
  }
  delay(1);
}

void convertToState(char action) {
  if(action == 'g' and !isGo){
    go();
  }else if(action == 'r'){
    reset();
  }
}

void notifyGameStatus(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Time  : ");
  lcd.setCursor(8,0);
  lcd.print(temps);
  lcd.setCursor(0,1);
  lcd.print("Score : ");
  lcd.setCursor(8,1);
  lcd.print(score);
  Serial.print(millis());
  Serial.print(":values:");
  Serial.print(temps);
  Serial.print(":");
  Serial.println(score);
}

void panier(){
  isScored = true;
}

void go(){
  reset();
  for(int i = 5; i > 0; i--){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Start in...");
    lcd.setCursor(15,1);
    lcd.print(i);
    Serial.print(millis());
    Serial.print(":message:");
    Serial.print("Start in ");
    Serial.println(i);
    delay(1000);
  }
  Serial.print(millis());
    Serial.print(":message:");
    Serial.println(" ");
  btnPressed = false;
  isGo = true;
  notifyGameStatus();
}

void reset(){
  currentTime=0;
  previousTime=0;
  isScored = false;
  isGo = false;
  score = 0;
  temps = 60;
  notifyGameStatus();
  notifyNotStarted();
}
