#include <Arduino.h>
#include <U8g2lib.h>
#include <AccelStepper.h>

#include<FastLED.h>
#define NUM_LEDS 42
#define LED_PIN 10
CRGB leds[NUM_LEDS];

#ifdef U8X8_HAVE_HW_I2C
#endif
#include <Wire.h>
int t=101;
int points= 0;
unsigned long startTime_TIMER = 0;
unsigned long interval_TIMER = 1000;
U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(1, 0); // RX, TX
DFRobotDFPlayerMini myDFPlayer;


int sensor1=2;
int sensor2=3;
unsigned long int startpoint_TIMER=0;
unsigned long int startpoint_TIMER1=0;
unsigned long int intervalpoint_TIMER=200;
unsigned long int intervalpoint_TIMER1=200;

volatile int ledstate=1;

#define speed3 7
#define speed2 8
#define speed1 9

int encoder0PinA = 5;
int encoder0PinB = 6;
int encoder0Pos = 0;
int button=4;
int encoder0PinALast = LOW;
int n = LOW;
int counter1=0;
unsigned long buttondelay=0;
unsigned long buttoninterval=250;

void setup() {
   u8g2.begin();
   u8g2.setDisplayRotation(U8G2_R2);
   //stepper.setMaxSpeed(500);
   //stepper.setAcceleration(100.0);
   FastLED.addLeds<WS2812B, LED_PIN,GRB>(leds,NUM_LEDS);
   FastLED.setBrightness(255);
   pinMode (encoder0PinA, INPUT);
   pinMode (encoder0PinB, INPUT);
   pinMode (button, INPUT);
   pinMode (speed1, OUTPUT);
   pinMode (speed2, OUTPUT);
   pinMode (speed3, OUTPUT);
   pinMode(sensor1,INPUT_PULLUP);
   pinMode(sensor2,INPUT_PULLUP);
   attachInterrupt(digitalPinToInterrupt(sensor1),subtract,FALLING);
   attachInterrupt(digitalPinToInterrupt(sensor2),addition,FALLING);
   mySoftwareSerial.begin(9600);
   if (!myDFPlayer.begin(mySoftwareSerial, true, false)) {  
    while(true){
      delay(0); 
    }
   }
  myDFPlayer.volume(28); 
  
}

void(* resetFunc) (void) = 0;

void loop() 
{ 
   n = digitalRead(encoder0PinA);
   if ((encoder0PinALast == LOW) && (n == HIGH)) 
   {
    encoder0Pos=encoder0Pos+1;
   }
  encoder0PinALast = n;
  unsigned currentTime= millis();
  if (digitalRead(button) == LOW) 
    {
      if(currentTime-buttondelay >= buttoninterval)
    {
    buttondelay = currentTime;
    counter1++;
    }}
  
  if (counter1==0)
  startscreen();
  
  if (counter1==1)
  difficulty(); 
  
  if (counter1==2)
  pointsandtime(); 

  if(counter1==3)
   gameover();
 }
  
void startscreen()
{ for(int v=0;v<1;v++){
  fill_rainbow(leds,NUM_LEDS,0,255/NUM_LEDS); 
  FastLED.show();
  }
  myDFPlayer.next();
  digitalWrite(speed1, HIGH);
  digitalWrite(speed2, HIGH);
  digitalWrite(speed3, HIGH);
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_profont22_tf);
    u8g2.setCursor(35,20);
    u8g2.print(F("Press"));
    u8g2.setCursor(35,50);
    u8g2.print(F("Start"));
    } while ( u8g2.nextPage() );
}

void difficulty()
{ for(int w=0;w<1;w++){
    for(int i=0;i<17;i++){
    leds[i]=CRGB::Red;}
    for(int i=16;i<43;i++){
    leds[i]=CRGB::Gold;
    FastLED.show();}
    } 
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_profont22_tf);
    u8g2.setCursor(35,20);
    u8g2.print(F("Level"));
    u8g2.setCursor(50,50);
    u8g2.print(encoder0Pos);
    } while ( u8g2.nextPage());
}

void pointsandtime()
{ if(ledstate==1)
  ledfunction();
    myDFPlayer.enableLoop();
    unsigned currentTime= millis();
    if(encoder0Pos == 1)
    digitalWrite(speed1, LOW);
    if(t==0) 
    digitalWrite(speed1,HIGH);
    
    if(encoder0Pos == 2)
    digitalWrite(speed2, LOW);
    if(t==0) 
    digitalWrite(speed2, HIGH);
    
    if(encoder0Pos == 3)
    digitalWrite(speed3, LOW);
    if(t==0) 
    digitalWrite(speed3, HIGH);
    
    if(t==0)
    counter1++;
    
    if(currentTime-startTime_TIMER >= interval_TIMER)
    {    
    startTime_TIMER = currentTime;
    if (t!=0) t--;
    u8g2.firstPage();
    do {
    u8g2.setFont(u8g2_font_profont22_tf);
    u8g2.setCursor(0,54);
    u8g2.print(F("Points"));
    u8g2.setCursor(80,54);
    u8g2.print(F("Time"));
    u8g2.setCursor(10,25);
    u8g2.print(points);
    u8g2.setCursor(86,25);
    u8g2.print(t); 
    } while ( u8g2.nextPage() );
    }
  }


 void gameover()
 {  u8g2.firstPage();
    do {
    u8g2.setFont(u8g2_font_profont22_tf);
    u8g2.setCursor(10,20);
    u8g2.print(F("Game Over"));
    u8g2.setCursor(50,50);
    u8g2.print(points);
    } while ( u8g2.nextPage() );
    delay(2000);
    myDFPlayer.disableLoopAll();
    resetFunc(); 
    }

 void subtract()
{ unsigned currentTime= millis();
  if(currentTime-startpoint_TIMER >= intervalpoint_TIMER)
  {startpoint_TIMER = currentTime;
  points=points-200;
}
}

void addition()
{ unsigned currentTime= millis();
  if(currentTime-startpoint_TIMER1 >= intervalpoint_TIMER1)
  {startpoint_TIMER1 = currentTime;
  points=points+1200;
}
}

void ledfunction(){
  for(int i=0;i<14;i++){
    leds[i]=CRGB::White;}
  for(int i=14;i<28;i++){
    leds[i]=CRGB::Blue;}
  for(int i=28;i<43;i++){
    leds[i]=CRGB::DarkRed;
    FastLED.show();}
    ledstate=0;
}






    
